-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Punishment for visiting Kika clouds too frequently
- Loading branch information
1 parent
846cbc0
commit d53cb31
Showing
2 changed files
with
184 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
src/games/stendhal/server/maps/kikareukin/islands/HeavenGateKeeper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/*************************************************************************** | ||
* Copyright © 2024 - Faiumoni e. V. * | ||
*************************************************************************** | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
package games.stendhal.server.maps.kikareukin.islands; | ||
|
||
import games.stendhal.common.Level; | ||
import games.stendhal.common.MathHelper; | ||
import games.stendhal.common.NotificationType; | ||
import games.stendhal.server.core.engine.SingletonRepository; | ||
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; | ||
|
||
|
||
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). */ | ||
private static final long TIME_BUFFER = MathHelper.MILLISECONDS_IN_ONE_DAY * 4; | ||
/** XP modifier for trying to requesting too often (15% of excess). */ | ||
private static final float XP_MODIFIER = 0.15f; | ||
|
||
|
||
/** | ||
* 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); | ||
} | ||
} | ||
|
||
/** | ||
* 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); | ||
} | ||
|
||
/** | ||
* 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) { | ||
// 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); | ||
final int xpBuffer = Math.max(xpStart - Level.getXP(player.getLevel()), 0); | ||
// a percentage of player's gained XP relative to the current level (levels cannot be lost) | ||
final int xpDiff = (int) Math.floor(xpBuffer * HeavenGateKeeper.XP_MODIFIER); | ||
final int hpStart = player.getHP(); | ||
player.addXP(-xpDiff); | ||
player.setHP(1); | ||
final int xpLoss = xpStart - player.getXP(); | ||
final int hpLoss = hpStart - player.getHP(); | ||
|
||
NotificationType ntype = NotificationType.INFORMATION; | ||
String msg = "It appears you you are not welcome in the clouds at this time."; | ||
if (xpLoss > 0 || hpLoss > 0) { | ||
ntype = NotificationType.NEGATIVE; | ||
msg += " You lost "; | ||
if (hpLoss > 0) { | ||
msg += hpLoss + " health"; | ||
if (xpLoss > 0) { | ||
msg += " and "; | ||
} | ||
} | ||
if (xpLoss > 0) { | ||
msg += xpLoss + " experience"; | ||
} | ||
msg += "."; | ||
} | ||
player.sendPrivateText(ntype, msg); | ||
} | ||
|
||
/** | ||
* Checks if player violates visit limit. | ||
* | ||
* @param player | ||
* Player requesting entrance. | ||
* @return | ||
* `true` if player has made more than 3 requests within 4 days. | ||
*/ | ||
private static boolean inViolation(final Player player) { | ||
return HeavenGateKeeper.getRequestCount(player) > HeavenGateKeeper.REQUEST_LIMIT; | ||
} | ||
|
||
/** | ||
* Requests entrance into heaven and punishes if necessary. | ||
* | ||
* @param player | ||
* Player requesting entrance. | ||
* @return | ||
* Whether player can enter. | ||
*/ | ||
public static boolean requestEntrance(final Player player) { | ||
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() { | ||
private boolean notified = false; | ||
@Override | ||
public void onTurnReached(int currentTurn) { | ||
if (!notified) { | ||
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); | ||
} else { | ||
HeavenGateKeeper.punish(player); | ||
} | ||
} | ||
}; | ||
notifier.notifyInTurns(10, listener); | ||
return false; | ||
} | ||
return true; | ||
} | ||
} |