diff --git a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java index a227e693..3be486a3 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -129,6 +129,7 @@ private void registerTags() { this.tagRegistry.registerTag(new TriggerBlockTag()); this.tagRegistry.registerTag(new PermissionTag()); this.tagRegistry.registerTag(new CommandTag()); + this.tagRegistry.registerTag(new PortalEventTag()); } /** diff --git a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java index 9e2e57b5..25f0d306 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java @@ -217,7 +217,7 @@ public boolean playerPortalEvent(PlayerContainer player, PlayerLocation toLoc) { return false; } - var portalResult = this.portalServices.checkPortalActivation(player, toLoc, TriggerType.MOVEMENT); + var portalResult = this.portalServices.checkPortalActivation(player, toLoc, TriggerType.PORTAL); if(portalResult != PortalServices.PortalActivationResult.NOT_IN_PORTAL) { return false; 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 eab3dc79..abf8b51e 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 @@ -30,6 +30,10 @@ public class AdvancedPortal implements TagTarget { private final HashMap args = new HashMap<>(); + private transient List portalTags = new ArrayList<>(); + + private transient boolean isSorted = false; + @Inject private transient PlayerDataServices playerDataServices; @@ -64,6 +68,7 @@ public String[] getArgValues(String argName) { @Override public void setArgValues(String argName, String[] argValues) { + this.isSorted = false; this.args.put(argName, argValues); } @@ -72,8 +77,26 @@ public void addArg(String argName, String argValues) { // TODO need to add the ability to add args after creation } + private void updatePortalTagList() { + portalTags.clear(); + int i = 0; + for (Map.Entry entry : args.entrySet()) { + this.portalTags.add(new DataTag(entry.getKey(), entry.getValue())); + } + // sort the tags by priority + this.portalTags.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(); + } + })); + } + @Override public void removeArg(String arg) { + this.isSorted = false; this.args.remove(arg); } @@ -113,6 +136,11 @@ public void updateBounds(BlockLocation loc1, BlockLocation loc2) { * @return Whether the portal was successfully activated */ public ActivationResult activate(PlayerContainer player, TriggerType triggerType) { + if(!isSorted) { + updatePortalTagList(); + isSorted = true; + } + var playerData = playerDataServices.getPlayerData(player); if (playerData.hasJoinCooldown()) { @@ -131,22 +159,23 @@ public ActivationResult activate(PlayerContainer player, TriggerType triggerType } ActivationData data = new ActivationData(triggerType); - DataTag[] portalTags = new DataTag[args.size()]; - int i = 0; - for (Map.Entry entry : args.entrySet()) { - portalTags[i++] = new DataTag(entry.getKey(), entry.getValue()); - } - for (DataTag portalTag : portalTags) { + for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = tagRegistry.getActivationHandler(portalTag.NAME); - if (activationHandler != null - && !activationHandler.preActivated( - this, player, data, this.getArgValues(portalTag.NAME))) { - return ActivationResult.FAILED_DO_KNOCKBACK; + if (activationHandler != null) { + var preActivated = activationHandler.preActivated( + this, player, data, this.getArgValues(portalTag.NAME)); + + if(!preActivated) { + if(activationHandler instanceof Tag.DenyBehavior denyBehavior && denyBehavior.getDenyBehavior() == Tag.DenyBehavior.Behaviour.SILENT) { + return ActivationResult.FAILED_DO_NOTHING; + } + return ActivationResult.FAILED_DO_KNOCKBACK; + } } } - for (DataTag portalTag : portalTags) { + for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = tagRegistry.getActivationHandler(portalTag.NAME); if (activationHandler != null @@ -155,7 +184,7 @@ public ActivationResult activate(PlayerContainer player, TriggerType triggerType return ActivationResult.FAILED_DO_KNOCKBACK; } } - for (DataTag portalTag : portalTags) { + for (DataTag portalTag : this.portalTags) { Tag.Activation activationHandler = tagRegistry.getActivationHandler(portalTag.NAME); if (activationHandler != null) { 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 5704ee8e..9bcdf976 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 @@ -103,9 +103,16 @@ public boolean registerTag(Tag tag) { return true; } - public List getTags() { - // TODO Make a copy of the list to prevent issues with modification + public Tag getTag(String tagName) { + for (Tag tag : this.tags) { + if (tag.getName().equals(tagName)) { + return tag; + } + } + return null; + } - return this.tags; + public List getTags() { + return new ArrayList<>(this.tags); } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/PortalEventTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/PortalEventTag.java index 27460bb7..9e92abc2 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/tags/PortalEventTag.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/PortalEventTag.java @@ -8,10 +8,14 @@ import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.core.warphandler.ActivationData; import com.sekwah.advancedportals.core.warphandler.Tag; +import com.sekwah.advancedportals.core.warphandler.TriggerType; + import javax.annotation.Nullable; import javax.inject.Inject; +import java.util.List; +import java.util.Objects; -public class PortalEventTag implements Tag.Activation { +public class PortalEventTag implements Tag.Activation, Tag.AutoComplete, Tag.DenyBehavior, Tag.OrderPriority { @Inject PlayerDataServices playerDataServices; @@ -40,7 +44,7 @@ public String getName() { @Nullable @Override public String[] getAliases() { - return new String[0]; + return aliases; } @Override @@ -51,16 +55,13 @@ public String description() { @Override public boolean preActivated(TagTarget target, PlayerContainer player, ActivationData activeData, String[] argData) { - if (!player.hasPermission(argData[1])) { - player.sendMessage(Lang.translate("portal.error.nopermission")); - return false; - } - return true; + return !Objects.equals(argData[0], "true") || activeData.getTriggerType() == TriggerType.PORTAL; } @Override public void postActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + // Do nothing } @Override @@ -68,4 +69,26 @@ public boolean activated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { return true; } + + @Nullable + @Override + public List autoComplete(String argData) { + return List.of("true", "false"); + } + + @Nullable + @Override + public String splitString() { + return ""; + } + + @Override + public Behaviour getDenyBehavior() { + return Behaviour.SILENT; + } + + @Override + public Priority getPriority() { + return Priority.HIGHEST; + } } 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 f39344a5..1b0883b0 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 @@ -29,6 +29,8 @@ public interface Tag { */ enum TagType { PORTAL, DESTINATION } + enum Priority { LOWEST, LOW, NORMAL, HIGH, HIGHEST } + /** * Used to flag where the auto complete should show more or less info. * @@ -43,6 +45,16 @@ enum TagType { PORTAL, DESTINATION } String description(); + interface OrderPriority { + Priority getPriority(); + } + + interface DenyBehavior { + enum Behaviour { SILENT, KNOCKBACK } + + Behaviour getDenyBehavior(); + } + interface AutoComplete extends Tag { /** * This is used to get the auto complete for the tag. This is called