From 2064c3f8ab3d133830c5535234f4a78f7af6ecb1 Mon Sep 17 00:00:00 2001 From: Sekwah Date: Mon, 5 Feb 2024 02:17:44 +0000 Subject: [PATCH] feat: add cooldown tag that is stored --- .../core/AdvancedPortalsCore.java | 2 + .../advancedportals/core/CoreListeners.java | 6 +- .../core/destination/Destination.java | 2 +- .../core/portal/AdvancedPortal.java | 23 ++-- .../repository/impl/ConfigRepositoryImpl.java | 2 +- .../core/serializeddata/PlayerData.java | 28 +++-- .../core/serializeddata/config/Config.java | 4 +- .../core/services/PlayerDataServices.java | 4 +- .../core/services/PortalServices.java | 11 ++ .../core/tags/activation/CooldownTag.java | 111 ++++++++++++++++++ .../core/util/PlayerUtils.java | 11 ++ .../core/warphandler/ActivationData.java | 6 + lang/src/main/resources/lang/en_GB.lang | 6 + 13 files changed, 189 insertions(+), 27 deletions(-) create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java create mode 100644 core/src/main/java/com/sekwah/advancedportals/core/util/PlayerUtils.java 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 f940c3c..c320d48 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -15,6 +15,7 @@ import com.sekwah.advancedportals.core.repository.ConfigRepository; import com.sekwah.advancedportals.core.services.DestinationServices; import com.sekwah.advancedportals.core.services.PortalServices; import com.sekwah.advancedportals.core.services.PlayerDataServices; +import com.sekwah.advancedportals.core.tags.activation.CooldownTag; import com.sekwah.advancedportals.core.tags.activation.DestiTag; import com.sekwah.advancedportals.core.tags.activation.NameTag; import com.sekwah.advancedportals.core.tags.activation.TriggerBlockTag; @@ -118,6 +119,7 @@ public class AdvancedPortalsCore { private void registerTags() { this.tagRegistry.registerTag(new NameTag()); this.tagRegistry.registerTag(new DestiTag()); + this.tagRegistry.registerTag(new CooldownTag()); this.tagRegistry.registerTag(new TriggerBlockTag()); } 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 5cb83c5..e625a29 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java @@ -32,11 +32,11 @@ public class CoreListeners { private GameScheduler gameScheduler; public void playerJoin(PlayerContainer player) { - this.playerDataServices.activateCooldown(player); + this.playerDataServices.setJoinCooldown(player); } public void teleportEvent(PlayerContainer player) { - this.playerDataServices.activateCooldown(player); + this.playerDataServices.setJoinCooldown(player); } public void playerLeave(PlayerContainer player) { @@ -157,7 +157,7 @@ public class CoreListeners { } public void worldChange(PlayerContainer player) { - this.playerDataServices.activateCooldown(player); + this.playerDataServices.setJoinCooldown(player); } public boolean preventEntityCombust(EntityContainer entity) { 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 cb1a338..9110273 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 @@ -65,7 +65,7 @@ public class Destination implements TagTarget { } public boolean activate(PlayerContainer player) { - ActivationData data = new ActivationData(); + ActivationData data = new ActivationData(false); this.portalActivate(player, data); this.postActivate(player, data); return true; 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 40b8d36..8bb7602 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 @@ -11,6 +11,8 @@ import com.sekwah.advancedportals.core.registry.TagRegistry; import com.sekwah.advancedportals.core.serializeddata.PlayerLocation; import com.sekwah.advancedportals.core.services.PlayerDataServices; import com.sekwah.advancedportals.core.tags.activation.TriggerBlockTag; +import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.core.util.PlayerUtils; import com.sekwah.advancedportals.core.warphandler.ActivationData; import com.sekwah.advancedportals.core.warphandler.Tag; @@ -107,15 +109,19 @@ public class AdvancedPortal implements TagTarget { */ public boolean activate(PlayerContainer player, boolean moveActivated) { var playerData = playerDataServices.getPlayerData(player); - if(playerData.isGlobalCooldown()) { + if(playerData.isInPortal()) return false; + playerData.setInPortal(true); + if(playerData.hasJoinCooldown()) { + var cooldown = (int) Math.ceil(playerData.getJoinCooldownLeft() / 1000D); + player.sendMessage(Lang.translateInsertVariables("portal.cooldown.join", cooldown, + Lang.translate(cooldown == 1 ? "time.second" : "time.seconds"))); if(configRepository.playFailSound()) { player.playSound("block.portal.travel", 0.05f, new Random().nextFloat() * 0.4F + 0.8F); } - if(moveActivated) throwPlayerBack(player); return false; } - ActivationData data = new ActivationData(); + ActivationData data = new ActivationData(moveActivated); DataTag[] portalTags = new DataTag[args.size()]; int i = 0; for(Map.Entry entry : args.entrySet()) { @@ -146,18 +152,11 @@ public class AdvancedPortal implements TagTarget { } if(data.hasActivated()) { playerData.setNetherPortalCooldown(1000); - playerData.setGlobalCooldown(configRepository.getPortalCooldown() * 1000); return true; } return false; } - private void throwPlayerBack(PlayerContainer player) { - var strength = configRepository.getThrowbackStrength(); - var playerLoc = player.getLoc().getDirection(); - player.setVelocity(playerLoc.setY(0).normalize().multiply(-1).setY(0.5).multiply(strength)); - } - public boolean isLocationInPortal(BlockLocation loc) { return this.isLocationInPortal(loc, 0); @@ -209,4 +208,8 @@ public class AdvancedPortal implements TagTarget { } return false; } + + public String getName() { + return getArgValues("name")[0]; + } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java index fba7a85..a55afde 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/repository/impl/ConfigRepositoryImpl.java @@ -79,7 +79,7 @@ public class ConfigRepositoryImpl implements ConfigRepository { @Override public long getPortalCooldown() { - return this.config.portalCooldown; + return this.config.joinCooldown; } @Override diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerData.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerData.java index 32f0a73..8631427 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerData.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/PlayerData.java @@ -39,11 +39,11 @@ public class PlayerData { /** * The next time System.currentTimeMillis() a player can use a portal. */ - private transient long globalCooldown; + private transient long joinCooldown; private transient long netherPortalCooldown; - private HashMap perPortalCooldowns = new HashMap<>(); + private HashMap perPortalCooldowns = new HashMap<>(); private String selectedPortal; @@ -63,12 +63,12 @@ public class PlayerData { this.pos2 = pos2; } - public long getGlobalCooldown() { - return globalCooldown; + public long getJoinCooldownLeft() { + return joinCooldown - System.currentTimeMillis(); } - public void setGlobalCooldown(long globalCooldown) { - this.globalCooldown = System.currentTimeMillis() + globalCooldown; + public void setJoinCooldown(long joinCooldown) { + this.joinCooldown = System.currentTimeMillis() + joinCooldown; } public String getSelectedPortal() { @@ -107,11 +107,23 @@ public class PlayerData { this.netherPortalCooldown = System.currentTimeMillis() + netherPortalCooldown; } - public boolean isGlobalCooldown() { - return System.currentTimeMillis() < globalCooldown; + public boolean hasJoinCooldown() { + return System.currentTimeMillis() < joinCooldown; } public boolean isNetherPortalCooldown() { return System.currentTimeMillis() < netherPortalCooldown; } + + public void setPortalCooldown(String portalName, long cooldown) { + perPortalCooldowns.put(portalName, System.currentTimeMillis() + cooldown); + } + + public boolean hasPortalCooldown(String portalName) { + return perPortalCooldowns.containsKey(portalName) && System.currentTimeMillis() < perPortalCooldowns.get(portalName); + } + + public double getPortalCooldownLeft(String portalName) { + return perPortalCooldowns.get(portalName) - System.currentTimeMillis(); + } } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java index 91990e9..33b75e6 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/serializeddata/config/Config.java @@ -17,7 +17,7 @@ public class Config { public boolean stopWaterFlow = true; - public int portalCooldown = 5; + public int joinCooldown = 5; public String warpParticles = "ENDER"; @@ -31,7 +31,7 @@ public class Config { public int maxTriggerVisualisationSize = 1000; - public double throwbackStrength = 1; + public double throwbackStrength = 0.7; public boolean playFailSound = true; } diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PlayerDataServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PlayerDataServices.java index ce2939f..d209504 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PlayerDataServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PlayerDataServices.java @@ -39,9 +39,9 @@ public final class PlayerDataServices { }); } - public void activateCooldown(PlayerContainer player) { + public void setJoinCooldown(PlayerContainer player) { var tempData = getPlayerData(player); - tempData.setGlobalCooldown(configRepository.getPortalCooldown() * 1000); + tempData.setJoinCooldown(configRepository.getPortalCooldown() * 1000); } public void playerLeave(PlayerContainer player) { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java index 99de679..649e045 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java @@ -12,6 +12,7 @@ import com.sekwah.advancedportals.core.portal.AdvancedPortal; import com.sekwah.advancedportals.core.serializeddata.PlayerData; import com.sekwah.advancedportals.core.tags.activation.NameTag; import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.core.util.PlayerUtils; import com.sekwah.advancedportals.core.warphandler.Tag; import javax.inject.Singleton; @@ -80,16 +81,26 @@ public class PortalServices { var blockMaterial = world.getBlock(blockLoc); var blockEntityTopMaterial = world.getBlock(blockEntityTopLoc); + var notInPortal = true; for (AdvancedPortal portal : portalCache.values()) { if ((portal.isLocationInPortal(toLoc) && portal.isTriggerBlock(blockMaterial)) || (portal.isLocationInPortal(blockEntityTopLoc) && portal.isTriggerBlock(blockEntityTopMaterial))) { + notInPortal = false; if(portal.activate(player, true)) { return; } } } + var playerData = playerDataServices.getPlayerData(player); + if(!notInPortal) { + var strength = configRepository.getThrowbackStrength(); + PlayerUtils.throwPlayerBack(player, strength); + } + if(playerData.isInPortal() && notInPortal) { + playerData.setInPortal(false); + } } public List getPortalNames() { diff --git a/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java new file mode 100644 index 0000000..3683d63 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/tags/activation/CooldownTag.java @@ -0,0 +1,111 @@ +package com.sekwah.advancedportals.core.tags.activation; + +import com.google.inject.Inject; +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.portal.AdvancedPortal; +import com.sekwah.advancedportals.core.registry.TagTarget; +import com.sekwah.advancedportals.core.repository.ConfigRepository; +import com.sekwah.advancedportals.core.services.PlayerDataServices; +import com.sekwah.advancedportals.core.util.InfoLogger; +import com.sekwah.advancedportals.core.util.Lang; +import com.sekwah.advancedportals.core.util.PlayerUtils; +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; + +public class CooldownTag implements Tag.Activation, Tag.Creation { + + @Inject + transient PlayerDataServices playerDataServices; + + @Inject + transient ConfigRepository configRepository; + + + @Inject + private InfoLogger infoLogger; + + public static String TAG_NAME = "cooldown"; + + private final TagType[] tagTypes = new TagType[]{ TagType.PORTAL }; + + @Override + public TagType[] getTagTypes() { + return tagTypes; + } + + @Override + public String getName() { + return TAG_NAME; + } + + @Nullable + @Override + public String[] getAliases() { + return null; + } + + @Override + public String description() { + return Lang.translate("tag.cooldown.description"); + } + + @Override + public boolean preActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + var playerData = playerDataServices.getPlayerData(player); + if(target instanceof AdvancedPortal portal) { + var portalName = portal.getName(); + if(playerData.hasPortalCooldown(portalName)) { + var cooldown = (int) Math.ceil(playerData.getPortalCooldownLeft(portalName) / 1000D); + player.sendMessage(Lang.translateInsertVariables("portal.cooldown.individual", cooldown, + Lang.translate(cooldown == 1 ? "time.second" : "time.seconds"))); + if(configRepository.playFailSound()) { + player.playSound("block.portal.travel", 0.05f, new Random().nextFloat() * 0.4F + 0.8F); + } + return false; + } + return true; + } + return false; + } + + @Override + public void postActivated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + if(activationData.hasActivated()) { + if(target instanceof AdvancedPortal portal) { + var playerData = playerDataServices.getPlayerData(player); + try { + playerData.setPortalCooldown(portal.getName(), Integer.parseInt(argData[0]) * 1000); + } catch (NumberFormatException e) { + infoLogger.warning("Cooldown tag failed to set cooldown for portal: " + portal.getName() + " with value: " + argData[0]); + } + } + } + } + + @Override + public boolean activated(TagTarget target, PlayerContainer player, ActivationData activationData, String[] argData) { + return true; + } + + @Override + public boolean created(TagTarget target, PlayerContainer player, String[] argData) { + try { + Integer.parseInt(argData[0]); + } catch (NumberFormatException e) { + player.sendMessage(Lang.translate("messageprefix.negative") + Lang.translate("tag.cooldown.fail")); + return false; + } + return true; + } + + @Override + public void destroyed(TagTarget target, PlayerContainer player, String[] argData) { + + } +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/util/PlayerUtils.java b/core/src/main/java/com/sekwah/advancedportals/core/util/PlayerUtils.java new file mode 100644 index 0000000..a430447 --- /dev/null +++ b/core/src/main/java/com/sekwah/advancedportals/core/util/PlayerUtils.java @@ -0,0 +1,11 @@ +package com.sekwah.advancedportals.core.util; + +import com.sekwah.advancedportals.core.connector.containers.PlayerContainer; + +public class PlayerUtils { + + public static void throwPlayerBack(PlayerContainer player, double strength) { + var playerLoc = player.getLoc().getDirection(); + player.setVelocity(playerLoc.setY(0).normalize().multiply(-1).setY(0.5).multiply(strength)); + } +} diff --git a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java index f371f2a..60e7662 100644 --- a/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java +++ b/core/src/main/java/com/sekwah/advancedportals/core/warphandler/ActivationData.java @@ -12,6 +12,8 @@ public class ActivationData { private boolean warpAllowed = true; + public final boolean moveActivated; + private WarpedStatus warpStatus = WarpedStatus.NOTACTIVATED; private PlayerLocation wantedLocation; @@ -20,6 +22,10 @@ public class ActivationData { return this.warpStatus; } + public ActivationData(boolean moveActivated) { + this.moveActivated = moveActivated; + } + public void setWarpStatus(WarpedStatus warped) { if (this.warpStatus == WarpedStatus.WARPED) { return; diff --git a/lang/src/main/resources/lang/en_GB.lang b/lang/src/main/resources/lang/en_GB.lang index e7c2280..4cac766 100644 --- a/lang/src/main/resources/lang/en_GB.lang +++ b/lang/src/main/resources/lang/en_GB.lang @@ -141,6 +141,11 @@ error.notplayer=Only players can do that. portal.selector.poschange=&aYou have selected &epos%1$s &aX&7:&e%2$s &aY&7:&e%3$s &aZ&7:&e%4$s +time.second=second +time.seconds=seconds +portal.cooldown.join=&cThere is &e%1$s &c%2$s join cooldown protection left. +portal.cooldown.individual=&cPlease wait &e%1$s &c%2$s until attempting to enter this portal again. + command.lang.help=Update the translation file command.version.help=Returns the current version of the plugin @@ -156,4 +161,5 @@ tag.desti.description=Sets the destination of the portal tag.name.error.nospaces= The name cannot contain spaces. tag.triggerblock.description=Sets the trigger block/s of the portal. Comma seperated or multi tag. +tag.cooldown.fail= The cooldown must be a number.