forked from Upstream/mmocore
global skill cooldown
This commit is contained in:
parent
2d4a3cd3bd
commit
dc5ec436b9
@ -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()))
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user