diff --git a/src/games/stendhal/server/maps/kikareukin/islands/HeavenGateKeeper.java b/src/games/stendhal/server/maps/kikareukin/islands/HeavenGateKeeper.java index 34777bc237..bf4672bdde 100644 --- a/src/games/stendhal/server/maps/kikareukin/islands/HeavenGateKeeper.java +++ b/src/games/stendhal/server/maps/kikareukin/islands/HeavenGateKeeper.java @@ -11,9 +11,6 @@ ***************************************************************************/ package games.stendhal.server.maps.kikareukin.islands; -import java.util.HashMap; -import java.util.Map; - import games.stendhal.common.Level; import games.stendhal.common.MathHelper; import games.stendhal.common.NotificationType; @@ -21,12 +18,16 @@ import games.stendhal.server.core.engine.StendhalRPZone; import games.stendhal.server.core.events.TurnListener; import games.stendhal.server.core.events.TurnNotifier; +import games.stendhal.server.entity.npc.action.IncrementQuestAction; import games.stendhal.server.entity.player.Player; -import marauroa.common.Pair; public class HeavenGateKeeper { + /** Slot name used for tracking requests. */ + private static final String SLOT = "heaven_gatekeeper"; + /** Name of entity that messages player. */ + private static final String ENTITY_NAME = "Kikareukin's Gatekeeper"; /** Number of requests allowed before being punished. */ private static final short REQUEST_LIMIT = 3; /** Time period in which player requests are tracked (4 days). */ @@ -34,53 +35,68 @@ public class HeavenGateKeeper { /** XP modifier for trying to requesting too often (15% of excess). */ private static final float XP_MODIFIER = 0.15f; - // FIXME: would it be better to store in database than using memory? - private static Map> visitors = new HashMap<>(); - - private static Pair getVisitorInfo(final String name) { - if (HeavenGateKeeper.visitors.containsKey(name)) { - return HeavenGateKeeper.visitors.get(name); + /** + * Increments number of requests player has made. + * + * @param player + * Player requesting entrance. + */ + private static void addRequest(final Player player) { + final long timeFromRequestStart = System.currentTimeMillis() - HeavenGateKeeper.getRequestTime(player); + if (timeFromRequestStart > HeavenGateKeeper.TIME_BUFFER) { + // first request or time limit expired so reset so player isn't unnecessarily punished + player.setQuest(HeavenGateKeeper.SLOT, System.currentTimeMillis() + ";1"); + } else { + new IncrementQuestAction(HeavenGateKeeper.SLOT, 1, 1).fire(player, null, null); } - return HeavenGateKeeper.createVisitorInfo(name); } - private static Pair createVisitorInfo(final String name) { - final Pair request = new Pair<>(System.currentTimeMillis(), 0); - HeavenGateKeeper.visitors.put(name, request); - return request; - } - - private static void addRequest(final String name) { - final Pair visitorInfo = HeavenGateKeeper.getVisitorInfo(name); - visitorInfo.setSecond(visitorInfo.second() + 1); - visitors.put(name, visitorInfo); - } - - private static long getRequestTime(final String name) { - return HeavenGateKeeper.getVisitorInfo(name).first(); + /** + * Retrieves the time period beginning when player made initial request. + * + * @param player + * Player requesting entrance. + * @return + * Time of initial request. + */ + private static long getRequestTime(final Player player) { + return MathHelper.parseLongDefault(player.getQuest(HeavenGateKeeper.SLOT, 0), 0); } - private static int getRequestCount(final String name) { - return HeavenGateKeeper.getVisitorInfo(name).second(); + /** + * Retrieves number of request player has made in the current time period. + * + * @param player + * Player requesting entrance. + * @return + * Request count. + */ + private static int getRequestCount(final Player player) { + return MathHelper.parseIntDefault(player.getQuest(HeavenGateKeeper.SLOT, 1), 0); } /** * Punishment from heaven. * + * - sent to afterlife + * - loses all but 1 HP + * - loses 15% of excess XP + * + * TODO: + * - add lightning (spell effect) + * - play thunder sound + * * @param player * Player being punished. */ private static void punish(final Player player) { - // TODO: - // - add lightning (spell effect) - // - play thunder sound - - // set player's HP to 1 & send to afterlife + // send to afterlife final StendhalRPZone afterlife = SingletonRepository.getRPWorld().getZone("int_afterlife"); if (afterlife != null) { player.teleport(afterlife, 31, 23, player.getDirection(), null); } + // set HP to 1 & subtract XP final int xpStart = player.getXP(); // a percentage of XP based on difference requirement to next level (levels can be lost) //final int xpDiff = (int) Math.floor(Level.getXPDiff(player.getLevel()-1) * HeavenGateKeeper.XP_MODIFIER); @@ -116,18 +132,12 @@ private static void punish(final Player player) { * Checks if player violates visit limit. * * @param player - * Name of player requesting entrance. + * Player requesting entrance. * @return - * `true` if player has made more than 3 requests within 3 days. + * `true` if player has made more than 3 requests within 4 days. */ - private static boolean inViolation(final String name) { - final long timeFromRequestStart = System.currentTimeMillis() - HeavenGateKeeper.getRequestTime(name); - if (timeFromRequestStart > HeavenGateKeeper.TIME_BUFFER) { - // reset request state so player doesn't get unnecessarily punished - HeavenGateKeeper.createVisitorInfo(name); - return false; - } - return HeavenGateKeeper.getRequestCount(name) > HeavenGateKeeper.REQUEST_LIMIT; + private static boolean inViolation(final Player player) { + return HeavenGateKeeper.getRequestCount(player) > HeavenGateKeeper.REQUEST_LIMIT; } /** @@ -139,9 +149,8 @@ private static boolean inViolation(final String name) { * Whether player can enter. */ public static boolean requestEntrance(final Player player) { - final String name = player.getName(); - HeavenGateKeeper.addRequest(name); - if (HeavenGateKeeper.inViolation(name)) { + HeavenGateKeeper.addRequest(player); + if (HeavenGateKeeper.inViolation(player)) { // first delay is to notify player, second is to apply punishment final TurnNotifier notifier = SingletonRepository.getTurnNotifier(); final TurnListener listener = new TurnListener() { @@ -149,7 +158,7 @@ public static boolean requestEntrance(final Player player) { @Override public void onTurnReached(int currentTurn) { if (!notified) { - player.sendPrivateText(NotificationType.PRIVMSG, "Kikareukin's Gatekeeper", + player.sendPrivateText(NotificationType.PRIVMSG, HeavenGateKeeper.ENTITY_NAME, "You have worn out your welcome and shall be punished for your greed!"); notified = true; notifier.notifyInTurns(10, this);