global skill cooldown

This commit is contained in:
Jules 2022-01-14 14:06:39 +01:00
parent 2d4a3cd3bd
commit dc5ec436b9
12 changed files with 89 additions and 64 deletions

View File

@ -2,6 +2,7 @@ package net.Indyuce.mmocore.api;
import java.text.DecimalFormat;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import org.bukkit.attribute.Attribute;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scheduler.BukkitRunnable;
@ -36,7 +37,7 @@ public class PlayerActionBar extends BukkitRunnable {
@Override
public void run() {
for (PlayerData data : PlayerData.getAll())
if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.canSeeActionBar()) {
if (data.isOnline() && !data.getPlayer().isDead() && !data.isCasting() && data.getActivityTimeOut(PlayerActivity.ACTION_BAR_MESSAGE) == 0) {
data.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(MMOCore.plugin.placeholderParser.parse(data.getPlayer(),
MythicLib.plugin.parseColors((data.getProfess().hasActionBar() ? data.getProfess().getActionBar() : config.format)
.replace("{health}", digit.format(data.getPlayer().getHealth()))

View File

@ -0,0 +1,35 @@
package net.Indyuce.mmocore.api.player;
import net.Indyuce.mmocore.MMOCore;
import javax.inject.Provider;
import java.util.Objects;
/**
* Used by MMOCore when it has to store the last time
* a player did some action.
* <p>
* This also features a time out function which can
* be used for cooldowns
*/
public enum PlayerActivity {
USE_WAYPOINT(() -> 5 * 1000L),
FRIEND_REQUEST(() -> 1000 * 60 * 2L),
ACTION_BAR_MESSAGE(() -> MMOCore.plugin.actionBarManager.getTimeOut() * 50),
LOOT_CHEST_SPAWN(() -> MMOCore.plugin.configManager.lootChestPlayerCooldown),
CAST_SKILL(() -> MMOCore.plugin.configManager.globalSkillCooldown);
private final Provider<Long> timeout;
PlayerActivity(Provider<Long> timeout) {
this.timeout = timeout;
}
public long getTimeOut() {
return Objects.requireNonNull(timeout, "Time out not supported").get();
}
}

View File

@ -74,8 +74,7 @@ public class PlayerData extends OfflinePlayerData implements Closable {
private final PlayerProfessions collectSkills = new PlayerProfessions(this);
private final PlayerAttributes attributes = new PlayerAttributes(this);
private final Map<String, SavedClassInformation> classSlots = new HashMap<>();
private long lastWaypoint, lastFriendRequest, actionBarTimeOut, lastLootChest;
private final Map<PlayerActivity, Long> lastActivity = new HashMap<>();
// NON-FINAL player data stuff made public to facilitate field change
public int skillGuiDisplayOffset;
@ -177,13 +176,25 @@ public class PlayerData extends OfflinePlayerData implements Closable {
return mmoData.getPlayer();
}
@Override
public long getLastLogin() {
return mmoData.getLastLogin();
public long getLastActivity(PlayerActivity activity) {
return this.lastActivity.getOrDefault(activity, 0l);
}
public long getLastFriendRequest() {
return lastFriendRequest;
public long getActivityTimeOut(PlayerActivity activity) {
return Math.max(0, getLastActivity(activity) + activity.getTimeOut() - System.currentTimeMillis());
}
public void setLastActivity(PlayerActivity activity) {
setLastActivity(activity, System.currentTimeMillis());
}
public void setLastActivity(PlayerActivity activity, long timestamp) {
this.lastActivity.put(activity, timestamp);
}
@Override
public long getLastLogin() {
return mmoData.getLastLogActivity();
}
@Override
@ -333,25 +344,6 @@ public class PlayerData extends OfflinePlayerData implements Closable {
waypoints.add(waypoint.getId());
}
public long getWaypointCooldown() {
return Math.max(0, lastWaypoint + 5000 - System.currentTimeMillis());
}
/**
* Handles the per-player loot chest cooldown system. That is to
* reduce the rik of spawning multiple loot chests around the same
* player in a row, which could be game breaking.
*
* @return If a random chest can spawn around that player
*/
public boolean canSpawnLootChest() {
return lastLootChest + MMOCore.plugin.configManager.lootChestPlayerCooldown < System.currentTimeMillis();
}
public void applyLootChestCooldown() {
lastLootChest = System.currentTimeMillis();
}
/**
* @deprecated Provide a heal reason with {@link #heal(double, PlayerResourceUpdateEvent.UpdateReason)}
*/
@ -405,15 +397,11 @@ public class PlayerData extends OfflinePlayerData implements Closable {
MMOCore.plugin.getLogger().log(level, "[Userdata:" + (isOnline() ? getPlayer().getName() : "Offline Player") + "] " + message);
}
public void setLastFriendRequest(long ms) {
lastFriendRequest = Math.max(0, ms);
}
public void sendFriendRequest(PlayerData target) {
if (!isOnline() || !target.isOnline())
return;
setLastFriendRequest(System.currentTimeMillis());
setLastActivity(PlayerActivity.FRIEND_REQUEST);
FriendRequest request = new FriendRequest(this, target);
new ConfigMessage("friend-request").addPlaceholders("player", getPlayer().getName(), "uuid", request.getUniqueId().toString())
.sendAsJSon(target.getPlayer());
@ -435,7 +423,7 @@ public class PlayerData extends OfflinePlayerData implements Closable {
* spamming waypoints. There is no need to reset it when resetting the
* player waypoints data
*/
lastWaypoint = System.currentTimeMillis();
setLastActivity(PlayerActivity.USE_WAYPOINT);
giveStellium(-waypoint.getStelliumCost(), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
@ -687,27 +675,11 @@ public class PlayerData extends OfflinePlayerData implements Closable {
return skillCasting != null;
}
/**
* @return If the action bar is not being used to display anything else
* i.e if the "general info" action bar can be displayed
*/
public boolean canSeeActionBar() {
return actionBarTimeOut < System.currentTimeMillis();
}
/**
* @param timeOut Delay during which the general info action bar
* will not be displayed to the player
*/
public void setActionBarTimeOut(long timeOut) {
actionBarTimeOut = System.currentTimeMillis() + (timeOut * 50);
}
public void displayActionBar(String message) {
if (!isOnline())
return;
setActionBarTimeOut(MMOCore.plugin.actionBarManager.getTimeOut());
setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE);
getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message));
}

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmocore.api.player.social;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Sound;
@ -24,7 +25,7 @@ public class FriendRequest extends Request {
}
public void accept() {
getCreator().setLastFriendRequest(0);
getCreator().setLastActivity(PlayerActivity.FRIEND_REQUEST, 0);
getCreator().addFriend(target.getUniqueId());
target.addFriend(getCreator().getUniqueId());
if(target.isOnline() && getCreator().isOnline()) {

View File

@ -1,15 +1,14 @@
package net.Indyuce.mmocore.command.rpg.admin;
import io.lumine.mythic.lib.commands.mmolib.api.CommandTreeNode;
import io.lumine.mythic.lib.commands.mmolib.api.Parameter;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import net.Indyuce.mmocore.api.player.PlayerData;
import io.lumine.mythic.lib.commands.mmolib.api.CommandTreeNode;
import io.lumine.mythic.lib.commands.mmolib.api.Parameter;
public class HideActionBarCommandTreeNode extends CommandTreeNode {
public HideActionBarCommandTreeNode(CommandTreeNode parent) {
super(parent, "hideab");
@ -37,7 +36,8 @@ public class HideActionBarCommandTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
PlayerData.get(player).setActionBarTimeOut(amount);
long lastUsed = System.currentTimeMillis() - PlayerActivity.ACTION_BAR_MESSAGE.getTimeOut() + amount * 50;
PlayerData.get(player).setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, lastUsed);
return CommandResult.SUCCESS;
}
}

View File

@ -18,8 +18,7 @@ public class MainExperienceDispenser implements ExperienceDispenser {
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation) {
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
: hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation;
playerData.giveExperience(experience, EXPSource.SOURCE, hologramLocation);
playerData.giveExperience(experience, EXPSource.SOURCE, hologramLocation, true);
}
@Override

View File

@ -4,6 +4,7 @@ import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.Waypoint;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.gui.api.EditableInventory;
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
@ -183,7 +184,7 @@ public class WaypointViewer extends EditableInventory {
return;
}
if (playerData.getWaypointCooldown() > 0)
if (playerData.getActivityTimeOut(PlayerActivity.USE_WAYPOINT) > 0)
return;
player.closeInventory();

View File

@ -3,6 +3,7 @@ package net.Indyuce.mmocore.gui.social.friend;
import io.lumine.mythic.lib.api.item.ItemTag;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType;
import net.Indyuce.mmocore.api.util.math.format.DelayFormat;
@ -199,7 +200,7 @@ public class EditableFriendList extends EditableInventory {
if (item.getFunction().equals("request")) {
long remaining = playerData.getLastFriendRequest() + 60 * 2 * 1000 - System.currentTimeMillis();
long remaining = playerData.getActivityTimeOut(PlayerActivity.FRIEND_REQUEST);
if (remaining > 0) {
MMOCore.plugin.configManager.getSimpleMessage("friend-request-cooldown", "cooldown", new DelayFormat().format(remaining))
.send(player);

View File

@ -2,6 +2,7 @@ package net.Indyuce.mmocore.loot.chest;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.LootChestSpawnEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.loot.LootBuilder;
import org.apache.commons.lang.Validate;
@ -27,7 +28,8 @@ public class LootChestRegion {
@Override
public void run() {
getBounds().getPlayers().filter(PlayerData::canSpawnLootChest).findAny().ifPresent(player -> spawnChest(player));
getBounds().getPlayers().filter(player -> player.getActivityTimeOut(PlayerActivity.LOOT_CHEST_SPAWN) == 0)
.findAny().ifPresent(player -> spawnChest(player));
}
};
@ -80,7 +82,7 @@ public class LootChestRegion {
public void spawnChest(PlayerData player) {
// Apply chest cooldown
player.applyLootChestCooldown();
player.setLastActivity(PlayerActivity.LOOT_CHEST_SPAWN);
// First randomly determine the chest tier
ChestTier tier = rollTier();

View File

@ -27,7 +27,7 @@ public class ConfigManager {
public boolean overrideVanillaExp, canCreativeCast, cobbleGeneratorXP, saveDefaultClassInfo;
public String partyChatPrefix, noSkillBoundPlaceholder;
public ChatColor staminaFull, staminaHalf, staminaEmpty;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
public SwapAction normalSwapAction, sneakingSwapAction;
private final FileConfiguration messages;
@ -97,6 +97,7 @@ public class ConfigManager {
combatLogTimer = MMOCore.plugin.getConfig().getInt("combat-log.timer") * 1000L;
lootChestExpireTime = Math.max(MMOCore.plugin.getConfig().getInt("loot-chests.chest-expire-time"), 1) * 1000L;
lootChestPlayerCooldown = (long) MMOCore.plugin.getConfig().getDouble("player-cooldown") * 1000L;
globalSkillCooldown = MMOCore.plugin.getConfig().getLong("global-skill-cooldown") * 50;
noSkillBoundPlaceholder = getSimpleMessage("no-skill-placeholder").message();
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);

View File

@ -8,6 +8,7 @@ import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData;
public class CastableSkill extends Skill {
@ -33,6 +34,10 @@ public class CastableSkill extends Skill {
return false;
}
// Global cooldown check
if (!skill.getSkill().isPassive() && playerData.getActivityTimeOut(PlayerActivity.CAST_SKILL) > 0)
return false;
// Cooldown check
if (skillMeta.getCaster().getData().getCooldownMap().isOnCooldown(this)) {
MMOCore.plugin.configManager.getSimpleMessage("casting.on-cooldown").send(playerData.getPlayer());
@ -73,6 +78,8 @@ public class CastableSkill extends Skill {
casterData.giveMana(-getModifier("mana"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
casterData.giveStamina(-getModifier("stamina"), PlayerResourceUpdateEvent.UpdateReason.SKILL_COST);
}
casterData.setLastActivity(PlayerActivity.CAST_SKILL);
}
@Override

View File

@ -72,6 +72,11 @@ loot-chests:
# spawns two loot chests in ANY region.
player-cooldown: 600
# A global cooldown (in ticks) that applies for every skill
# Set to 0 to disable this option. It is set to half
# a second by default. This does not apply to passive skills
global-skill-cooldown: 10
# Settings for the default action bar
action-bar: