mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-26 00:35:17 +01:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
This commit is contained in:
commit
482eeb9e8b
@ -213,7 +213,14 @@
|
||||
<dependency>
|
||||
<groupId>de.erethon</groupId>
|
||||
<artifactId>DungeonsXL</artifactId>
|
||||
<version>0.18-PRE-02</version>
|
||||
<version>0.18-SNAPSHOT-1149</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.erethon</groupId>
|
||||
<artifactId>Bedrock</artifactId>
|
||||
<version>1.2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -262,7 +269,7 @@
|
||||
<dependency>
|
||||
<groupId>me.ulrich</groupId>
|
||||
<artifactId>UltimateClans</artifactId>
|
||||
<version>4.2.0</version>
|
||||
<version>6.0.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@ -276,7 +283,7 @@
|
||||
<dependency>
|
||||
<groupId>org.kingdoms.main</groupId>
|
||||
<artifactId>Kingdoms</artifactId>
|
||||
<version>1.11.15.0.0.0.1.1</version>
|
||||
<version>1.15.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -172,8 +172,8 @@ public class MMOCore extends JavaPlugin {
|
||||
}
|
||||
|
||||
/*
|
||||
* Resource regeneration. Must check if entity is dead otherwise regen will make
|
||||
* the 'respawn' button glitched plus HURT entity effect bug
|
||||
* Resource regeneration. Must check if entity is dead otherwise regen
|
||||
* will make the 'respawn' button glitched plus HURT entity effect bug
|
||||
*/
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
@ -208,6 +208,7 @@ public class MMOCore extends JavaPlugin {
|
||||
PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName);
|
||||
Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
|
||||
partyModule = moduleType.provideModule();
|
||||
getLogger().log(Level.WARNING, "Hooked parties onto " + moduleType.getPluginName());
|
||||
} catch (RuntimeException exception) {
|
||||
getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage());
|
||||
partyModule = new MMOCorePartyModule();
|
||||
@ -219,6 +220,7 @@ public class MMOCore extends JavaPlugin {
|
||||
GuildModuleType moduleType = GuildModuleType.valueOf(pluginName);
|
||||
Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
|
||||
guildModule = moduleType.provideModule();
|
||||
getLogger().log(Level.WARNING, "Hooked guilds onto " + moduleType.getPluginName());
|
||||
} catch (RuntimeException exception) {
|
||||
getLogger().log(Level.WARNING, "Could not initialize guild module: " + exception.getMessage());
|
||||
guildModule = new MMOCoreGuildModule();
|
||||
|
@ -21,6 +21,7 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import net.Indyuce.mmocore.api.player.social.FriendRequest;
|
||||
import net.Indyuce.mmocore.api.player.stats.PlayerStats;
|
||||
import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||
import net.Indyuce.mmocore.api.quest.trigger.StatTrigger;
|
||||
import net.Indyuce.mmocore.api.util.Closable;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
@ -32,8 +33,6 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
|
||||
import net.Indyuce.mmocore.party.provided.Party;
|
||||
import net.Indyuce.mmocore.player.ClassDataContainer;
|
||||
import net.Indyuce.mmocore.player.CombatHandler;
|
||||
import net.Indyuce.mmocore.player.Unlockable;
|
||||
@ -127,7 +126,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
private final Map<String, Integer> tableItemClaims = new HashMap<>();
|
||||
|
||||
// NON-FINAL player data stuff made public to facilitate field change
|
||||
public boolean noCooldown, statsLoaded;
|
||||
public boolean noCooldown;
|
||||
|
||||
/**
|
||||
* Player data is stored in the data map before it's actually fully loaded
|
||||
@ -141,14 +140,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
this.mmoData = mmoData;
|
||||
questData = new PlayerQuests(this);
|
||||
playerStats = new PlayerStats(this);
|
||||
|
||||
// Used to see if the triggers need to be applied
|
||||
for (StatInstance instance : mmoData.getStatMap().getInstances())
|
||||
for (StatModifier modifier : instance.getModifiers())
|
||||
if (modifier.getKey().startsWith("trigger")) {
|
||||
statsLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,7 +183,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
skillTree.setupNodeStates(this);
|
||||
|
||||
// Stat triggers setup
|
||||
if (!statsLoaded) {
|
||||
if (!areStatsLoaded()) {
|
||||
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
|
||||
for (SkillTreeNode node : skillTree.getNodes())
|
||||
node.getExperienceTable().claimStatTriggers(this, node);
|
||||
@ -227,6 +218,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
skillTreePoints.clear();
|
||||
}
|
||||
|
||||
public void clearNodeTimesClaimed() {
|
||||
final Iterator<String> ite = tableItemClaims.keySet().iterator();
|
||||
while (ite.hasNext())
|
||||
if (ite.next().startsWith(SkillTreeNode.KEY_PREFIX))
|
||||
ite.remove();
|
||||
}
|
||||
|
||||
public Set<Map.Entry<String, Integer>> getNodeLevelsEntrySet() {
|
||||
HashMap<String, Integer> nodeLevelsString = new HashMap<>();
|
||||
for (SkillTreeNode node : nodeLevels.keySet())
|
||||
@ -235,7 +233,12 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public boolean areStatsLoaded() {
|
||||
return statsLoaded;
|
||||
// Used to see if the triggers need to be applied
|
||||
for (StatInstance instance : mmoData.getStatMap().getInstances())
|
||||
for (StatModifier modifier : instance.getModifiers())
|
||||
if (modifier.getKey().startsWith(StatTrigger.TRIGGER_PREFIX))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<SkillTreeNode, Integer> getNodeLevels() {
|
||||
@ -364,13 +367,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
// Remove from party if it is MMO Party Module
|
||||
if (MMOCore.plugin.partyModule instanceof MMOCorePartyModule) {
|
||||
AbstractParty party = getParty();
|
||||
if (party != null && party instanceof Party)
|
||||
((Party) party).removeMember(this);
|
||||
}
|
||||
|
||||
// Close combat handler
|
||||
combat.close();
|
||||
|
||||
@ -1031,6 +1027,16 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
public void setSkillLevel(String skill, int level) {
|
||||
skills.put(skill, level);
|
||||
//If it is a passive skill we rebind it to make sure to update the damages done by it.
|
||||
for (int i = 0; i < boundPassiveSkills.size(); i++) {
|
||||
|
||||
PassiveSkill passiveSkill = boundPassiveSkills.get(i);
|
||||
if (passiveSkill.getTriggeredSkill().getHandler().getId().equals(skill)) {
|
||||
passiveSkill.unregister(mmoData);
|
||||
passiveSkill.register(mmoData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void resetSkillLevel(String skill) {
|
||||
|
@ -213,6 +213,8 @@ public class SavedClassInformation {
|
||||
|
||||
while (player.hasSkillBound(0))
|
||||
player.unbindSkill(0);
|
||||
player.clearNodeTimesClaimed();
|
||||
|
||||
|
||||
/*
|
||||
* Reads this class info, applies it to the player. set class after
|
||||
|
@ -9,10 +9,11 @@ import org.apache.commons.lang.Validate;
|
||||
import java.util.UUID;
|
||||
|
||||
public class StatTrigger extends Trigger {
|
||||
public static String TRIGGER_PREFIX = "mmocore_trigger";
|
||||
private final StatModifier statModifier;
|
||||
private final String stat;
|
||||
private final String modifierKey = TRIGGER_PREFIX + "." + UUID.randomUUID();
|
||||
private final double amount;
|
||||
private final ModifierType type;
|
||||
private final String modifierKey = "mmocore_trigger." + UUID.randomUUID();
|
||||
|
||||
public StatTrigger(MMOLineConfig config) {
|
||||
super(config);
|
||||
@ -24,12 +25,16 @@ public class StatTrigger extends Trigger {
|
||||
Validate.isTrue(type.equals("FLAT") || type.equals("RELATIVE"));
|
||||
stat = config.getString("stat");
|
||||
amount = config.getDouble("amount");
|
||||
this.type = ModifierType.valueOf(type);
|
||||
statModifier = new StatModifier(modifierKey, stat, amount, ModifierType.valueOf(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PlayerData player) {
|
||||
new StatModifier(modifierKey, stat, amount, type).register(player.getMMOPlayerData());
|
||||
StatModifier prevModifier = player.getMMOPlayerData().getStatMap().getInstance(stat).getModifier(modifierKey);
|
||||
if (prevModifier == null)
|
||||
statModifier.register(player.getMMOPlayerData());
|
||||
else
|
||||
prevModifier.add(amount).register(player.getMMOPlayerData());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,6 +53,10 @@ public class MMOCoreUtils {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String ymlName(String str) {
|
||||
return str.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value an integer you want to convert
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmocore.command;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.command.api.RegisteredCommand;
|
||||
@ -39,7 +40,17 @@ public class PvpModeCommand extends RegisteredCommand {
|
||||
|
||||
playerData.getCombat().setPvpMode(!playerData.getCombat().isInPvpMode());
|
||||
playerData.getCooldownMap().applyCooldown(COOLDOWN_KEY, playerData.getCombat().isInPvpMode() ? MMOCore.plugin.configManager.pvpModeToggleOnCooldown : MMOCore.plugin.configManager.pvpModeToggleOffCooldown);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.toggle-" + (playerData.getCombat().isInPvpMode() ? "on" : "off")).send((Player) sender);
|
||||
|
||||
// Toggling on when in PVP region
|
||||
if (playerData.getCombat().isInPvpMode() &&
|
||||
MythicLib.plugin.getFlags().isFlagAllowed(playerData.getPlayer(), CustomFlag.PVP_MODE)) {
|
||||
playerData.getCombat().setInvulnerable(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeCommand);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.toggle.on-invulnerable", "time",
|
||||
MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeCommand)).send(playerData.getPlayer());
|
||||
|
||||
// Just send message otherwise
|
||||
} else
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.toggle." + (playerData.getCombat().isInPvpMode() ? "on" : "off") + "-safe").send((Player) sender);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +95,9 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
||||
else if (identifier.equals("in_combat"))
|
||||
return String.valueOf(playerData.isInCombat());
|
||||
|
||||
else if (identifier.equals("pvp_mode"))
|
||||
return String.valueOf(playerData.getCombat().isInPvpMode());
|
||||
|
||||
else if (identifier.startsWith("since_enter_combat"))
|
||||
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getFirstHit()) / 1000) : "-1";
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
package net.Indyuce.mmocore.comp.region.pvpmode;
|
||||
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.session.MoveType;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import com.sk89q.worldguard.session.handler.FlagValueChangeHandler;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class MMOCoreFlagHandler extends FlagValueChangeHandler<StateFlag.State> {
|
||||
|
||||
@NotNull
|
||||
protected PlayerData playerData;
|
||||
|
||||
protected long lastMessage;
|
||||
|
||||
protected static final long MESSAGE_TIMEOUT = 3 * 1000;
|
||||
|
||||
public MMOCoreFlagHandler(Session session, Flag<StateFlag.State> flag) {
|
||||
super(session, flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when WorldGuard initializes the value for the first time,
|
||||
* on player login or world change for instance.
|
||||
*/
|
||||
@Override
|
||||
protected void onInitialValue(LocalPlayer player, ApplicableRegionSet set, StateFlag.State value) {
|
||||
try {
|
||||
playerData = PlayerData.get(player.getUniqueId());
|
||||
|
||||
// Things get done here
|
||||
onSetValue(player, player.getLocation(), player.getLocation(), set, value, StateFlag.State.DENY, MoveType.TELEPORT);
|
||||
} catch (Exception exception) {
|
||||
// Citizens.
|
||||
}
|
||||
}
|
||||
|
||||
public abstract StateFlag.State getDefaultState();
|
||||
|
||||
/**
|
||||
* Triggered when WorldGuard does not find a region setting the value of the flag.
|
||||
* In that case, put PvP mode to its default setting that is OFF.
|
||||
*/
|
||||
@Override
|
||||
protected boolean onAbsentValue(LocalPlayer player, Location from, Location to, ApplicableRegionSet toSet, StateFlag.State lastValue, MoveType moveType) {
|
||||
return onSetValue(player, from, to, toSet, getDefaultState(), lastValue, moveType);
|
||||
}
|
||||
|
||||
protected boolean isInvalid() {
|
||||
return playerData == null;
|
||||
}
|
||||
|
||||
protected boolean toBoolean(@Nullable StateFlag.State state) {
|
||||
return state == StateFlag.State.ALLOW;
|
||||
}
|
||||
|
||||
protected boolean canSendMessage() {
|
||||
return System.currentTimeMillis() > lastMessage + MESSAGE_TIMEOUT;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package net.Indyuce.mmocore.comp.region.pvpmode;
|
||||
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.session.MoveType;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
public class PvPFlagHandler extends MMOCoreFlagHandler {
|
||||
|
||||
public static final Factory FACTORY = new Factory() {
|
||||
|
||||
@Override
|
||||
public PvPFlagHandler create(Session session) {
|
||||
return new PvPFlagHandler(session, Flags.PVP);
|
||||
}
|
||||
};
|
||||
|
||||
public PvPFlagHandler(Session session, StateFlag flag) {
|
||||
super(session, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getDefaultState() {
|
||||
return State.ALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when a player changes region and finds a new value for that flag.
|
||||
* In that case, apply the new setting and display messages if needed.
|
||||
*/
|
||||
@Override
|
||||
protected boolean onSetValue(LocalPlayer player, Location from, Location to, ApplicableRegionSet toSet, State currentValue, State lastValue, MoveType moveType) {
|
||||
if (isInvalid())
|
||||
return true;
|
||||
|
||||
boolean newPvp = toBoolean(currentValue);
|
||||
boolean lastPvp = toBoolean(lastValue);
|
||||
|
||||
if (newPvp && !lastPvp) {
|
||||
|
||||
// Apply invulnerability
|
||||
playerData.getCombat().setInvulnerable(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeRegionChange);
|
||||
|
||||
// Send message
|
||||
if (canSendMessage()) {
|
||||
lastMessage = System.currentTimeMillis();
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.enter.pvp-mode-on", "time",
|
||||
MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeRegionChange)).send(playerData.getPlayer());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -3,32 +3,23 @@ package net.Indyuce.mmocore.comp.region.pvpmode;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.session.MoveType;
|
||||
import com.sk89q.worldguard.session.Session;
|
||||
import com.sk89q.worldguard.session.handler.FlagValueChangeHandler;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import io.lumine.mythic.lib.comp.flags.WorldGuardFlags;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.Indyuce.mmocore.command.PvpModeCommand;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PvPModeHandler extends FlagValueChangeHandler<State> {
|
||||
|
||||
@NotNull
|
||||
private PlayerData playerData;
|
||||
|
||||
private long lastMessage;
|
||||
|
||||
private static final long MESSAGE_TIMEOUT = 3 * 1000;
|
||||
public class PvPModeHandler extends MMOCoreFlagHandler {
|
||||
|
||||
public static final Factory FACTORY = new Factory() {
|
||||
public final WorldGuardFlags wgFlags = Objects.requireNonNull(MythicLib.plugin.getFlags().getHandler(WorldGuardFlags.class), "Could not reach ML compatibility class for WG");
|
||||
final WorldGuardFlags wgFlags = Objects.requireNonNull(MythicLib.plugin.getFlags().getHandler(WorldGuardFlags.class), "Could not reach ML compatibility class for WG");
|
||||
|
||||
@Override
|
||||
public PvPModeHandler create(Session session) {
|
||||
@ -40,77 +31,59 @@ public class PvPModeHandler extends FlagValueChangeHandler<State> {
|
||||
super(session, flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when WorldGuard initializes the value for the first time,
|
||||
* on player login or world change for instance.
|
||||
*/
|
||||
@Override
|
||||
protected void onInitialValue(LocalPlayer player, ApplicableRegionSet set, State value) {
|
||||
try {
|
||||
playerData = PlayerData.get(player.getUniqueId());
|
||||
} catch (Exception exception) {
|
||||
// Citizens.
|
||||
}
|
||||
public State getDefaultState() {
|
||||
return State.ALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when WorldGuard does not find a region setting the value of the flag.
|
||||
* In that case, put PvP mode to its default setting that is OFF.
|
||||
*/
|
||||
@Override
|
||||
protected boolean onAbsentValue(LocalPlayer player, Location from, Location to, ApplicableRegionSet toSet, StateFlag.State lastValue, MoveType moveType) {
|
||||
return onSetValue(player, from, to, toSet, DEFAULT_STATE, lastValue, moveType);
|
||||
}
|
||||
|
||||
public static final StateFlag.State DEFAULT_STATE = StateFlag.State.DENY;
|
||||
|
||||
/**
|
||||
* Triggered when a player changes region and finds a new value for that flag.
|
||||
* In that case, apply the new setting and display messages if needed.
|
||||
*/
|
||||
@Override
|
||||
protected boolean onSetValue(LocalPlayer player, Location from, Location to, ApplicableRegionSet toSet, StateFlag.State currentValue, StateFlag.State lastValue, MoveType moveType) {
|
||||
boolean newPvpMode = toBoolean(currentValue);
|
||||
boolean lastPvpMode = toBoolean(lastValue);
|
||||
if (isInvalid())
|
||||
return true;
|
||||
|
||||
boolean newPvpMode = toBoolean(currentValue);
|
||||
boolean lastPvpMode = toBoolean(lastValue);
|
||||
|
||||
if (!newPvpMode && lastPvpMode) {
|
||||
|
||||
// Apply cooldown
|
||||
playerData.getMMOPlayerData().getCooldownMap().applyCooldown(PvpModeCommand.COOLDOWN_KEY, MMOCore.plugin.configManager.pvpModeRegionLeaveCooldown);
|
||||
|
||||
// Send message
|
||||
if (canSendMessage()) {
|
||||
final String msgPath = (playerData.getCombat().isInPvpMode() && !playerData.getCombat().canQuitPvpMode()) ? "allowed" : "denied";
|
||||
|
||||
// Leave combat when joining safe zone
|
||||
final boolean pvpFlag = toSet.queryState(null, Flags.PVP) != StateFlag.State.DENY;
|
||||
if (playerData.getCombat().isInPvpMode() && !pvpFlag)
|
||||
playerData.getCombat().close();
|
||||
|
||||
final boolean pvpEnabled = playerData.getCombat().isInPvpMode() && !playerData.getCombat().canQuitPvpMode() && pvpFlag;
|
||||
lastMessage = System.currentTimeMillis();
|
||||
final double remaining = (playerData.getCombat().getLastHit() + MMOCore.plugin.configManager.pvpModeCombatTimeout * 1000.0D - System.currentTimeMillis()) / 1000.0D;
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.leave.pvp-" + msgPath, new String[]{"remaining",
|
||||
(MythicLib.plugin.getMMOConfig()).decimal.format(remaining)}).send(playerData.getPlayer());
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.leave.pvp-" + (pvpEnabled ? "allowed" : "denied"), "remaining",
|
||||
(MythicLib.plugin.getMMOConfig()).decimal.format(remaining)).send(playerData.getPlayer());
|
||||
}
|
||||
} else if (newPvpMode && !lastPvpMode) {
|
||||
|
||||
// Apply cooldown
|
||||
playerData.getMMOPlayerData().getCooldownMap().applyCooldown(PvpModeCommand.COOLDOWN_KEY, MMOCore.plugin.configManager.pvpModeRegionEnterCooldown);
|
||||
|
||||
// Apply invulnerability
|
||||
final boolean applyInvulnerability = playerData.getCombat().isInPvpMode() && playerData.getCombat().canQuitPvpMode();
|
||||
if (applyInvulnerability)
|
||||
playerData.getCombat().applyInvulnerability();
|
||||
playerData.getCombat().setInvulnerable(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeRegionChange);
|
||||
|
||||
// Send message
|
||||
if (canSendMessage()) {
|
||||
lastMessage = System.currentTimeMillis();
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.enter.pvp-mode-" + (applyInvulnerability ? "on" : "off"), new String[]{"time",
|
||||
(MythicLib.plugin.getMMOConfig()).decimal.format(MMOCore.plugin.configManager.pvpModeInvulnerability)}).send(playerData.getPlayer());
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.enter.pvp-mode-" + (applyInvulnerability ? "on" : "off"), "time",
|
||||
MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.configManager.pvpModeInvulnerabilityTimeRegionChange)).send(playerData.getPlayer());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isInvalid() {
|
||||
return playerData == null;
|
||||
}
|
||||
|
||||
private boolean toBoolean(@Nullable State state) {
|
||||
return state == State.ALLOW;
|
||||
}
|
||||
|
||||
private boolean canSendMessage() {
|
||||
return System.currentTimeMillis() > lastMessage + MESSAGE_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,89 @@
|
||||
package net.Indyuce.mmocore.comp.region.pvpmode;
|
||||
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.bukkit.protection.events.DisallowedPVPEvent;
|
||||
import com.sk89q.worldguard.session.handler.Handler;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.comp.flags.CustomFlag;
|
||||
import io.lumine.mythic.lib.comp.interaction.InteractionType;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PvPModeListener implements Listener {
|
||||
public PvPModeListener() {
|
||||
Validate.isTrue(WorldGuard.getInstance().getPlatform().getSessionManager().registerHandler(PvPModeHandler.FACTORY, null), "Could not register WG handler for PvP mode");
|
||||
Validate.isTrue(registerHandler(PvPModeHandler.FACTORY), "Could not register WG handler for PvP mode");
|
||||
if (MMOCore.plugin.getConfig().getBoolean("pvp_mode.invulnerability.apply_to_pvp_flag"))
|
||||
Validate.isTrue(registerHandler(PvPFlagHandler.FACTORY), "Could not register WG handler for PvP");
|
||||
}
|
||||
|
||||
private boolean registerHandler(Handler.Factory factory) {
|
||||
return WorldGuard.getInstance().getPlatform().getSessionManager().registerHandler(factory, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs after MythicLib interaction checks. This listener
|
||||
* takes care of PVP inside of PvP-mode regions.
|
||||
* <p>
|
||||
* Only send messages when damage is greater than 0 to support
|
||||
* Bukkit events-based checks just like in recent ML builds.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void unblockPvp(DisallowedPVPEvent event) {
|
||||
PlayerData defender;
|
||||
if (PlayerData.get(event.getAttacker()).getCombat().isInPvpMode() || !(defender = PlayerData.get(event.getDefender())).getCombat().isInPvpMode())
|
||||
public void a(EntityDamageByEntityEvent event) {
|
||||
if (!UtilityMethods.isRealPlayer(event.getEntity()))
|
||||
return;
|
||||
|
||||
if (!defender.getCombat().canQuitPvpMode() ||
|
||||
(!defender.getCombat().isInvulnerable() && MythicLib.plugin.getFlags().isFlagAllowed(event.getDefender().getLocation(), CustomFlag.PVP_MODE)))
|
||||
if (MythicLib.plugin.getEntities().checkPvpInteractionRules(event.getAttacker(), event.getDefender(), InteractionType.OFFENSE_ACTION, true))
|
||||
event.setCancelled(true);
|
||||
final @Nullable Player source = UtilityMethods.getPlayerDamager(event);
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
// Check for target's invulnerability BEFORE pvp-mode flag because it can also
|
||||
// happen when the option pvp_mode.invulnerability.apply_to_pvp_flag is on
|
||||
final Player target = (Player) event.getEntity();
|
||||
final PlayerData targetData = PlayerData.get(target);
|
||||
if (targetData.getCombat().isInvulnerable()) {
|
||||
if (event.getDamage() > 0) {
|
||||
final long left = targetData.getCombat().getInvulnerableTill() - System.currentTimeMillis();
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.cannot-hit.invulnerable-target",
|
||||
"left", MythicLib.plugin.getMMOConfig().decimal.format(left / 1000d)).send(source);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If attacker is still invulnerable and cannot deal damage
|
||||
final PlayerData sourceData = PlayerData.get(source);
|
||||
if (!MMOCore.plugin.configManager.pvpModeInvulnerabilityCanDamage && sourceData.getCombat().isInvulnerable()) {
|
||||
if (event.getDamage() > 0) {
|
||||
final long left = sourceData.getCombat().getInvulnerableTill() - System.currentTimeMillis();
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.cannot-hit.invulnerable-self",
|
||||
"left", MythicLib.plugin.getMMOConfig().decimal.format(left / 1000d)).send(source);
|
||||
}
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Checks for PvP mode on target location
|
||||
if (!MythicLib.plugin.getFlags().isFlagAllowed(target.getLocation(), CustomFlag.PVP_MODE))
|
||||
return;
|
||||
|
||||
// Defender has not enabled PvP mode
|
||||
if (!targetData.getCombat().isInPvpMode()) {
|
||||
event.setCancelled(true);
|
||||
if (event.getDamage() > 0)
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.cannot-hit.pvp-mode-disabled-target").send(source);
|
||||
}
|
||||
|
||||
// Attacker has not enabled PvP mode
|
||||
else if (!sourceData.getCombat().isInPvpMode()) {
|
||||
event.setCancelled(true);
|
||||
if (event.getDamage() > 0)
|
||||
MMOCore.plugin.configManager.getSimpleMessage("pvp-mode.cannot-hit.pvp-mode-disabled-self").send(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import io.lumine.mythic.lib.api.util.PostLoadObject;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -125,8 +125,7 @@ public class Profession extends PostLoadObject implements ExperienceObject {
|
||||
|
||||
@Override
|
||||
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
|
||||
hologramLocation = !getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null
|
||||
: hologramLocation;
|
||||
hologramLocation = !getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null : hologramLocation;
|
||||
playerData.getCollectionSkills().giveExperience(this, experience, EXPSource.SOURCE, hologramLocation, true);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,7 @@ public class SimpleExperienceObject implements ExperienceDispenser {
|
||||
|
||||
@Override
|
||||
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
|
||||
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null
|
||||
: hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation;
|
||||
hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null : hologramLocation;
|
||||
playerData.giveExperience(experience, source, hologramLocation, true);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,6 @@ public class MineBlockExperienceSource extends SpecificExperienceSource<Material
|
||||
}
|
||||
|
||||
private boolean hasSilkTouch(ItemStack item) {
|
||||
|
||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
package net.Indyuce.mmocore.gui;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
|
||||
@ -9,21 +14,29 @@ import net.Indyuce.mmocore.gui.api.PluginInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClassConfirmation extends EditableInventory {
|
||||
public ClassConfirmation() {
|
||||
super("class-confirm");
|
||||
}
|
||||
|
||||
/**
|
||||
* This enables to configure the name of the
|
||||
* class confirmation GUI (for custom GUI textures).
|
||||
*/
|
||||
private final Map<String, String> specificNames = new HashMap<>();
|
||||
|
||||
public ClassConfirmation() {
|
||||
super("class-confirm");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventoryItem load(String function, ConfigurationSection config) {
|
||||
@ -34,8 +47,20 @@ public class ClassConfirmation extends EditableInventory {
|
||||
return new ClassConfirmationInventory(data, this, profess, last);
|
||||
}
|
||||
|
||||
public class UnlockedItem extends InventoryItem<ClassConfirmationInventory> {
|
||||
@Override
|
||||
public void reload(FileConfiguration config) {
|
||||
super.reload(config);
|
||||
|
||||
specificNames.clear();
|
||||
|
||||
if (config.contains("class-specific-name")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("class-specific-name");
|
||||
for (String key : section.getKeys(false))
|
||||
specificNames.put(key, section.getString(key));
|
||||
}
|
||||
}
|
||||
|
||||
public class UnlockedItem extends InventoryItem<ClassConfirmationInventory> {
|
||||
public UnlockedItem(ConfigurationSection config) {
|
||||
super(config);
|
||||
}
|
||||
@ -46,18 +71,18 @@ public class ClassConfirmation extends EditableInventory {
|
||||
SavedClassInformation info = inv.getPlayerData().getClassInfo(profess);
|
||||
Placeholders holders = new Placeholders();
|
||||
|
||||
int nextLevelExp = inv.getPlayerData().getLevelUpExperience();
|
||||
double ratio = (double) info.getExperience() / (double) nextLevelExp;
|
||||
final double nextLevelExp = inv.getPlayerData().getLevelUpExperience();
|
||||
final double ratio = info.getExperience() / nextLevelExp;
|
||||
|
||||
StringBuilder bar = new StringBuilder("" + ChatColor.BOLD);
|
||||
int chars = (int) (ratio * 20);
|
||||
for (int j = 0; j < 20; j++)
|
||||
bar.append(j == chars ? "" + ChatColor.WHITE + ChatColor.BOLD : "").append("|");
|
||||
|
||||
holders.register("percent", decimal.format(ratio * 100));
|
||||
holders.register("progress", bar.toString());
|
||||
holders.register("class", profess.getName());
|
||||
holders.register("unlocked_skills", info.getSkillKeys().size());
|
||||
holders.register("percent", decimal.format(ratio * 100));
|
||||
holders.register("progress", bar.toString());
|
||||
holders.register("class", profess.getName());
|
||||
holders.register("unlocked_skills", info.getSkillKeys().size());
|
||||
holders.register("class_skills", profess.getSkills().size());
|
||||
holders.register("next_level", "" + nextLevelExp);
|
||||
holders.register("level", info.getLevel());
|
||||
@ -93,43 +118,45 @@ public class ClassConfirmation extends EditableInventory {
|
||||
public ItemStack display(ClassConfirmationInventory inv, int n) {
|
||||
return inv.getPlayerData().hasSavedClass(inv.profess) ? unlocked.display(inv, n) : locked.display(inv, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassConfirmationInventory extends GeneratedInventory {
|
||||
private final PlayerClass profess;
|
||||
private final PluginInventory last;
|
||||
public class ClassConfirmationInventory extends GeneratedInventory {
|
||||
private final PlayerClass profess;
|
||||
private final PluginInventory last;
|
||||
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last) {
|
||||
super(playerData, editable);
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last) {
|
||||
super(playerData, editable);
|
||||
|
||||
this.profess = profess;
|
||||
this.last = last;
|
||||
}
|
||||
this.profess = profess;
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClicked(InventoryClickContext context, InventoryItem item) {
|
||||
if (item.getFunction().equals("back"))
|
||||
last.open();
|
||||
@Override
|
||||
public void whenClicked(InventoryClickContext context, InventoryItem item) {
|
||||
if (item.getFunction().equals("back"))
|
||||
last.open();
|
||||
|
||||
else if (item.getFunction().equals("yes")) {
|
||||
else if (item.getFunction().equals("yes")) {
|
||||
|
||||
PlayerChangeClassEvent called = new PlayerChangeClassEvent(playerData, profess);
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (called.isCancelled())
|
||||
return;
|
||||
PlayerChangeClassEvent called = new PlayerChangeClassEvent(playerData, profess);
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (called.isCancelled())
|
||||
return;
|
||||
|
||||
playerData.giveClassPoints(-1);
|
||||
(playerData.hasSavedClass(profess) ? playerData.getClassInfo(profess)
|
||||
: new SavedClassInformation(MMOCore.plugin.dataProvider.getDataManager().getDefaultData())).load(profess, playerData);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("class-select", "class", profess.getName()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SELECT_CLASS).playTo(player);
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
playerData.giveClassPoints(-1);
|
||||
(playerData.hasSavedClass(profess) ? playerData.getClassInfo(profess)
|
||||
: new SavedClassInformation(MMOCore.plugin.dataProvider.getDataManager().getDefaultData())).load(profess, playerData);
|
||||
MMOCore.plugin.configManager.getSimpleMessage("class-select", "class", profess.getName()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SELECT_CLASS).playTo(player);
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String calculateName() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String calculateName() {
|
||||
final String professKey = MMOCoreUtils.ymlName(profess.getId());
|
||||
final @Nullable String found = specificNames.get(professKey);
|
||||
return found == null ? getName().replace("{class}", profess.getName()) : found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,17 @@ package net.Indyuce.mmocore.gui;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.ClassOption;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
|
||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
import net.Indyuce.mmocore.api.SoundEvent;
|
||||
import net.Indyuce.mmocore.api.player.profess.ClassOption;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -115,7 +115,7 @@ public class ClassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerClass profess = MMOCore.plugin.classManager.get(classId);
|
||||
final PlayerClass profess = MMOCore.plugin.classManager.get(classId);
|
||||
if (profess.hasOption(ClassOption.NEEDS_PERMISSION) && !player.hasPermission("mmocore.class." + profess.getId().toLowerCase())) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
|
||||
new ConfigMessage("no-permission-for-class").send(player);
|
||||
@ -128,7 +128,8 @@ public class ClassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryManager.CLASS_CONFIRM.newInventory(playerData, findDeepestSubclass(playerData, profess), this).open();
|
||||
final PlayerClass playerClass = findDeepestSubclass(playerData, profess);
|
||||
InventoryManager.CLASS_CONFIRM.newInventory(playerData, playerClass, this).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ public abstract class EditableInventory {
|
||||
private String name;
|
||||
private int slots;
|
||||
|
||||
|
||||
/*
|
||||
* This set is linked so it keeps the order/priority in
|
||||
* which the items are loaded from the config.
|
||||
@ -83,7 +82,6 @@ public abstract class EditableInventory {
|
||||
return adaptorType;
|
||||
}
|
||||
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
@ -368,10 +368,8 @@ public class ThreeDimAdaptor extends Adaptor {
|
||||
.getEntityFromID(event.getPlayer().getWorld(), packet.getIntegers().read(0));
|
||||
if (entity instanceof ArmorStand armorStand) {
|
||||
if (true) {
|
||||
Bukkit.broadcastMessage("IN");
|
||||
|
||||
if (armorStands.values().contains(armorStand)) {
|
||||
Bukkit.broadcastMessage("CANCEL" + armorStand.getName());
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,6 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
|
||||
Placeholders placeholders = getPlaceholders(inv, n);
|
||||
ItemStack item = new ItemStack(specificMaterial == null ? material : specificMaterial);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setCustomModelData(modelData);
|
||||
if (texture != null && meta instanceof SkullMeta)
|
||||
applyTexture(texture, (SkullMeta) meta);
|
||||
|
||||
@ -163,7 +162,7 @@ public abstract class InventoryItem<T extends GeneratedInventory> {
|
||||
}
|
||||
|
||||
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13))
|
||||
meta.setCustomModelData(getModelData());
|
||||
meta.setCustomModelData(modelData);
|
||||
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
|
@ -3,6 +3,7 @@ package net.Indyuce.mmocore.guild;
|
||||
import io.lumine.mythic.lib.comp.interaction.relation.Relationship;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface GuildModule {
|
||||
@ -10,5 +11,6 @@ public interface GuildModule {
|
||||
@Nullable
|
||||
public AbstractGuild getGuild(PlayerData playerData);
|
||||
|
||||
@NotNull
|
||||
public Relationship getRelationship(Player player, Player target);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ public enum GuildModuleType {
|
||||
// Useless since MythicLib already supports FactionBridge
|
||||
// FACTIONS("Factions", FactionsGuildModule::new),
|
||||
GUILDS("Guilds", GuildsGuildModule::new),
|
||||
KINGDOMSX("KingdomsX", KingdomsXGuildModule::new),
|
||||
KINGDOMSX("Kingdoms", KingdomsXGuildModule::new),
|
||||
MMOCORE("MMOCore", MMOCoreGuildModule::new),
|
||||
ULTIMATE_CLANS("UltimateClans", UltimateClansGuildModule::new),
|
||||
;
|
||||
@ -25,6 +25,10 @@ public enum GuildModuleType {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return Bukkit.getPluginManager().getPlugin(pluginName) != null;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import net.Indyuce.mmocore.guild.AbstractGuild;
|
||||
import net.Indyuce.mmocore.guild.GuildModule;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.kingdoms.constants.kingdom.Kingdom;
|
||||
import org.kingdoms.constants.kingdom.model.KingdomRelation;
|
||||
import org.kingdoms.constants.group.Kingdom;
|
||||
import org.kingdoms.constants.group.model.relationships.KingdomRelation;
|
||||
import org.kingdoms.constants.player.KingdomPlayer;
|
||||
import org.kingdoms.main.Kingdoms;
|
||||
|
||||
@ -30,7 +30,7 @@ public class KingdomsXGuildModule implements GuildModule {
|
||||
|
||||
final KingdomPlayer player1 = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(player.getUniqueId());
|
||||
if (player1 == null)
|
||||
return null;
|
||||
return Relationship.GUILD_NEUTRAL;
|
||||
|
||||
final Kingdom kingdom1 = player1.getKingdom();
|
||||
if (kingdom1 == null)
|
||||
@ -38,7 +38,7 @@ public class KingdomsXGuildModule implements GuildModule {
|
||||
|
||||
final KingdomPlayer player2 = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(target.getUniqueId());
|
||||
if (player2 == null)
|
||||
return null;
|
||||
return Relationship.GUILD_NEUTRAL;
|
||||
|
||||
final Kingdom kingdom2 = player2.getKingdom();
|
||||
if (kingdom2 == null)
|
||||
|
@ -3,7 +3,7 @@ package net.Indyuce.mmocore.guild.compat;
|
||||
import io.lumine.mythic.lib.comp.interaction.relation.Relationship;
|
||||
import me.ulrich.clans.data.ClanData;
|
||||
import me.ulrich.clans.data.ClanRivalAlly;
|
||||
import me.ulrich.clans.packets.interfaces.UClans;
|
||||
import me.ulrich.clans.interfaces.UClans;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.guild.AbstractGuild;
|
||||
import net.Indyuce.mmocore.guild.GuildModule;
|
||||
|
@ -27,11 +27,13 @@ import java.util.logging.Level;
|
||||
public class ConfigManager {
|
||||
public final CommandVerbose commandVerbose = new CommandVerbose();
|
||||
|
||||
public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp, splitMainExp, disableQuestBossBar, pvpModeEnabled;
|
||||
public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp, disableQuestBossBar,
|
||||
pvpModeEnabled, pvpModeInvulnerabilityCanDamage;
|
||||
public String partyChatPrefix, noSkillBoundPlaceholder;
|
||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||
public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown, pvpModeCombatTimeout, pvpModeInvulnerability;
|
||||
public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown,
|
||||
pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown;
|
||||
public int maxPartyLevelDifference, maxBoundActiveSkills, maxBoundPassiveSkills;
|
||||
public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>();
|
||||
|
||||
@ -129,7 +131,6 @@ public class ConfigManager {
|
||||
maxPartyLevelDifference = MMOCore.plugin.getConfig().getInt("party.max-level-difference");
|
||||
partyMaxExpSplitRange = MMOCore.plugin.getConfig().getDouble("party.max-exp-split-range");
|
||||
splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
|
||||
splitMainExp = MMOCore.plugin.getConfig().getBoolean("party.main-exp-split");
|
||||
disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar");
|
||||
|
||||
// Combat
|
||||
@ -137,8 +138,12 @@ public class ConfigManager {
|
||||
pvpModeToggleOnCooldown = config.getDouble("pvp_mode.cooldown.toggle_on");
|
||||
pvpModeToggleOffCooldown = config.getDouble("pvp_mode.cooldown.toggle_off");
|
||||
pvpModeCombatCooldown = config.getDouble("pvp_mode.cooldown.combat");
|
||||
pvpModeRegionEnterCooldown = config.getDouble("pvp_mode.cooldown.region_enter");
|
||||
pvpModeRegionLeaveCooldown = config.getDouble("pvp_mode.cooldown.region_leave");
|
||||
pvpModeCombatTimeout = config.getDouble("pvp_mode.combat_timeout");
|
||||
pvpModeInvulnerability = config.getDouble("pvp_mode.invulnerability");
|
||||
pvpModeInvulnerabilityTimeCommand = config.getDouble("pvp_mode.invulnerability.time.command");
|
||||
pvpModeInvulnerabilityTimeRegionChange = config.getDouble("pvp_mode.invulnerability.time.region_change");
|
||||
pvpModeInvulnerabilityCanDamage = config.getBoolean("pvp_mode.invulnerability.can_damage");
|
||||
|
||||
// Resources
|
||||
staminaFull = getColorOrDefault("stamina-whole", ChatColor.GREEN);
|
||||
|
@ -40,7 +40,7 @@ public class InventoryManager {
|
||||
try {
|
||||
inv.reload(new ConfigFile("/gui", inv.getId()).getConfig());
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load inventory " + inv.getId() + ": " + exception.getMessage());
|
||||
MMOCore.log(Level.WARNING, "Could not load inventory '" + inv.getId() + "': " + exception.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -79,24 +80,23 @@ public abstract class PlayerDataManager {
|
||||
public PlayerData setup(UUID uniqueId) {
|
||||
|
||||
// Load player data if it does not exist
|
||||
if (!data.containsKey(uniqueId)) {
|
||||
PlayerData newData = new PlayerData(MMOPlayerData.get(uniqueId));
|
||||
final @Nullable PlayerData current = data.get(uniqueId);
|
||||
if (current != null)
|
||||
return current;
|
||||
|
||||
// Schedule async data loading
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
|
||||
loadData(newData);
|
||||
newData.getStats().updateStats();
|
||||
Bukkit.getPluginManager().callEvent(new AsyncPlayerDataLoadEvent(newData));
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> Bukkit.getPluginManager().callEvent(new PlayerDataLoadEvent(newData)));
|
||||
});
|
||||
final PlayerData newData = new PlayerData(MMOPlayerData.get(uniqueId));
|
||||
|
||||
// Update data map
|
||||
data.put(uniqueId, newData);
|
||||
// Schedule async data loading
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
|
||||
loadData(newData);
|
||||
newData.getStats().updateStats();
|
||||
Bukkit.getPluginManager().callEvent(new AsyncPlayerDataLoadEvent(newData));
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> Bukkit.getPluginManager().callEvent(new PlayerDataLoadEvent(newData)));
|
||||
});
|
||||
|
||||
return newData;
|
||||
}
|
||||
|
||||
return data.get(uniqueId);
|
||||
// Update data map and return
|
||||
data.put(uniqueId, newData);
|
||||
return newData;
|
||||
}
|
||||
|
||||
public DefaultPlayerData getDefaultData() {
|
||||
|
@ -44,10 +44,6 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
if (config.contains("class"))
|
||||
data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
|
||||
|
||||
data.setMana(config.contains("mana") ? config.getDouble("mana") : data.getStats().getStat("MAX_MANA"));
|
||||
data.setStamina(config.contains("stamina") ? config.getDouble("stamina") : data.getStats().getStat("MAX_STAMINA"));
|
||||
data.setStellium(config.contains("stellium") ? config.getDouble("stellium") : data.getStats().getStat("MAX_STELLIUM"));
|
||||
|
||||
if (config.contains("guild")) {
|
||||
Guild guild = provider.getGuildManager().getGuild(config.getString("guild"));
|
||||
data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
|
||||
@ -117,6 +113,11 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
}
|
||||
|
||||
|
||||
//These should be loaded after to make sure that the MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
|
||||
data.setMana(config.contains("mana") ? config.getDouble("mana") : data.getStats().getStat("MAX_MANA"));
|
||||
data.setStamina(config.contains("stamina") ? config.getDouble("stamina") : data.getStats().getStat("MAX_STAMINA"));
|
||||
data.setStellium(config.contains("stellium") ? config.getDouble("stellium") : data.getStats().getStat("MAX_STELLIUM"));
|
||||
|
||||
data.setFullyLoaded();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,10 @@ public enum PartyModuleType {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return Bukkit.getPluginManager().getPlugin(pluginName) != null;
|
||||
}
|
||||
|
@ -1,42 +1,52 @@
|
||||
package net.Indyuce.mmocore.party.provided;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.event.social.PartyChatEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.ConfigManager;
|
||||
import net.Indyuce.mmocore.api.event.social.PartyChatEvent;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class PartyListener implements Listener {
|
||||
private final MMOCorePartyModule module;
|
||||
private final MMOCorePartyModule module;
|
||||
|
||||
public PartyListener(MMOCorePartyModule module) {
|
||||
this.module = module;
|
||||
}
|
||||
public PartyListener(MMOCorePartyModule module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void a(AsyncPlayerChatEvent event) {
|
||||
if (!event.getMessage().startsWith(MMOCore.plugin.configManager.partyChatPrefix))
|
||||
return;
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void partyChat(AsyncPlayerChatEvent event) {
|
||||
if (!event.getMessage().startsWith(MMOCore.plugin.configManager.partyChatPrefix))
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
Party party = module.getParty(data);
|
||||
if (party == null)
|
||||
return;
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
Party party = module.getParty(data);
|
||||
if (party == null)
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
event.setCancelled(true);
|
||||
|
||||
// Running it in a delayed task is recommended
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||
ConfigManager.SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("party-chat", "player", data.getPlayer().getName(), "message",
|
||||
event.getMessage().substring(MMOCore.plugin.configManager.partyChatPrefix.length()));
|
||||
PartyChatEvent called = new PartyChatEvent(party, data, format.message());
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (!called.isCancelled())
|
||||
party.getOnlineMembers().forEach(member -> format.send(member.getPlayer()));
|
||||
});
|
||||
}
|
||||
// Running it in a delayed task is recommended
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||
ConfigManager.SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("party-chat", "player", data.getPlayer().getName(), "message",
|
||||
event.getMessage().substring(MMOCore.plugin.configManager.partyChatPrefix.length()));
|
||||
PartyChatEvent called = new PartyChatEvent(party, data, format.message());
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (!called.isCancelled())
|
||||
party.getOnlineMembers().forEach(member -> format.send(member.getPlayer()));
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void leavePartyOnQuit(PlayerQuitEvent event) {
|
||||
final PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
final AbstractParty party = playerData.getParty();
|
||||
if (party != null)
|
||||
((Party) party).removeMember(playerData);
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,7 @@ public class CombatHandler implements Closable {
|
||||
private final PlayerData player;
|
||||
private final long firstHit = System.currentTimeMillis();
|
||||
|
||||
private long lastHit = System.currentTimeMillis();
|
||||
private long lastInvulnerabilityApplication;
|
||||
private long lastHit = System.currentTimeMillis(), invulnerableTill;
|
||||
|
||||
private boolean pvpMode;
|
||||
|
||||
@ -28,6 +27,7 @@ public class CombatHandler implements Closable {
|
||||
|
||||
public void update() {
|
||||
lastHit = System.currentTimeMillis();
|
||||
invulnerableTill = 0;
|
||||
player.getMMOPlayerData().getCooldownMap().applyCooldown(PvpModeCommand.COOLDOWN_KEY, MMOCore.plugin.configManager.pvpModeCombatCooldown);
|
||||
|
||||
// Simply refreshing
|
||||
@ -58,6 +58,10 @@ public class CombatHandler implements Closable {
|
||||
return firstHit;
|
||||
}
|
||||
|
||||
public long getInvulnerableTill() {
|
||||
return invulnerableTill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply checks if there is a scheduled task.
|
||||
*
|
||||
@ -68,17 +72,18 @@ public class CombatHandler implements Closable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used for PvP mode invulnerability when a player
|
||||
* joins a region while he still has PvP mode toggled on.
|
||||
* This is used for PvP mode inactivity when a player
|
||||
* joins a region with PvP mode toggled on, OR toggles on
|
||||
* PvP mode using the command when standing in a PvP region.
|
||||
*
|
||||
* @return If the player is invulnerable
|
||||
* @return If the player is inert i.e if he CAN hit/take damage
|
||||
*/
|
||||
public boolean isInvulnerable() {
|
||||
return System.currentTimeMillis() < lastInvulnerabilityApplication + MMOCore.plugin.configManager.pvpModeInvulnerability * 1000;
|
||||
return System.currentTimeMillis() < invulnerableTill;
|
||||
}
|
||||
|
||||
public void applyInvulnerability() {
|
||||
lastInvulnerabilityApplication = System.currentTimeMillis();
|
||||
public void setInvulnerable(double time) {
|
||||
invulnerableTill = System.currentTimeMillis() + (long) (time * 1000);
|
||||
}
|
||||
|
||||
public boolean canQuitPvpMode() {
|
||||
@ -107,5 +112,10 @@ public class CombatHandler implements Closable {
|
||||
public void close() {
|
||||
if (isInCombat())
|
||||
quit(true);
|
||||
|
||||
// Necessary steps when entering a town.
|
||||
lastHit = 0;
|
||||
invulnerableTill = 0;
|
||||
player.getMMOPlayerData().getCooldownMap().resetCooldown(PvpModeCommand.COOLDOWN_KEY);
|
||||
}
|
||||
}
|
||||
|
@ -296,19 +296,45 @@ command-verbose:
|
||||
pvp_mode:
|
||||
|
||||
# Requires /reload when changed
|
||||
enabled: true
|
||||
enabled: false
|
||||
|
||||
# Delay after any attack during which the player will stay in PvP Mode (seconds)
|
||||
# Has to be lower than 'cooldown.combat'
|
||||
combat_timeout: 30
|
||||
|
||||
# Invulnerability when entering a pvp-mode region when your PvP mode is toggled on.
|
||||
invulnerability: 60
|
||||
# Invulnerability triggered when:
|
||||
# - entering a PvP region with PvP mode turned on.
|
||||
# - using the /pvpmode command inside of a PvP region.
|
||||
invulnerability:
|
||||
time:
|
||||
region_change: 60
|
||||
command: 30
|
||||
|
||||
# When enabled, players can damage other players
|
||||
# to end this invulnerable time period.
|
||||
can_damage: false
|
||||
|
||||
# When enabled, leaving a no-PVP zone and entering a PVP zone
|
||||
# will apply the SAME invulnerability time.
|
||||
# Requires /reload when changed
|
||||
apply_to_pvp_flag: false
|
||||
|
||||
cooldown:
|
||||
# Delay before being able to use /pvpmode after being in combat (seconds)
|
||||
# Has to be greater than the combat timeout for it to make sense
|
||||
|
||||
# Cooldown before being able to use the /pvpmode
|
||||
# command when entering a PvP mode region.
|
||||
region_enter: 20
|
||||
|
||||
# Cooldown before being able to use the /pvpmode
|
||||
# command when entering a PvP mode region.
|
||||
region_leave: 20
|
||||
|
||||
# Delay before being able to use /pvpmode after being in combat (seconds).
|
||||
# Has to be greater than the 'combat_timeout'
|
||||
combat: 45
|
||||
|
||||
# Cooldown when toggling on PvP mode, before being able to toggle it off (seconds)
|
||||
toggle_on: 5
|
||||
|
||||
# Cooldown when toggling off PvP mode (seconds)
|
||||
toggle_off: 3
|
@ -1,6 +1,15 @@
|
||||
|
||||
# GUI display name
|
||||
name: Class Confirmation
|
||||
# GUI display name, used by default
|
||||
name: 'Confirmation: {class}'
|
||||
|
||||
# GUI display name which overrides the default one.
|
||||
# This can be used to apply custom textures to the GUI
|
||||
class-specific-name:
|
||||
mage: "Select Mage"
|
||||
rogue: "Select Rogue"
|
||||
marksman: "Select Marksman"
|
||||
warrior: "Select Warrior"
|
||||
paladin: "Select Paladin"
|
||||
|
||||
# Number of slots in your inventory. Must be
|
||||
# between 9 and 54 and must be a multiple of 9.
|
||||
@ -10,7 +19,7 @@ items:
|
||||
yes:
|
||||
slots: [12]
|
||||
function: 'yes'
|
||||
|
||||
|
||||
# Displayed when the player had already selected this class
|
||||
# before (only if class slots are enabled in the config).
|
||||
unlocked:
|
||||
@ -24,13 +33,13 @@ items:
|
||||
- ''
|
||||
- '&7Skill Points: &6{skill_points}'
|
||||
- '&7Skills You Unlocked: &6{unlocked_skills}&7/&6{class_skills}'
|
||||
|
||||
|
||||
# Displayed when the class is being chosen for the first time.
|
||||
locked:
|
||||
item: GREEN_TERRACOTTA
|
||||
name: '&aSelect {class}'
|
||||
lore: {}
|
||||
|
||||
|
||||
back:
|
||||
slots: [14]
|
||||
item: RED_TERRACOTTA
|
||||
|
@ -1,45 +1,58 @@
|
||||
# Level & Experience
|
||||
level-up:
|
||||
- ''
|
||||
- '&eCongratulations, you reached level &6{level}&e!'
|
||||
- '&eUse &6/p &eto see your new statistics!'
|
||||
- ''
|
||||
- ''
|
||||
- '&eCongratulations, you reached level &6{level}&e!'
|
||||
- '&eUse &6/p &eto see your new statistics!'
|
||||
- ''
|
||||
profession-level-up:
|
||||
- '&eYou are now level &6{level}&e in &6{profession}&e!'
|
||||
- '&eYou are now level &6{level}&e in &6{profession}&e!'
|
||||
exp-notification: '%&f{profession} &e{progress} &e{ratio}%'
|
||||
exp-hologram: '&e+{exp} EXP!'
|
||||
class-select: '&eYou are now a &6{class}&e!'
|
||||
already-on-class: '&cYou are already a {class}.'
|
||||
death-exp-loss:
|
||||
- ''
|
||||
- '&4You died and lost {loss} experience.'
|
||||
- ''
|
||||
- ''
|
||||
- '&4You died and lost {loss} experience.'
|
||||
- ''
|
||||
|
||||
# General
|
||||
not-enough-perms: '&cYou do not have enough permissions.'
|
||||
|
||||
# Experience boosters
|
||||
booster-main:
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e EXP multiplier is now active!'
|
||||
- '&e'
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e EXP multiplier is now active!'
|
||||
- '&e'
|
||||
booster-skill:
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e &6{profession} &eEXP multiplier is now active!'
|
||||
- '&e'
|
||||
- '&e'
|
||||
- '&eA &6{multiplier}x&e &6{profession} &eEXP multiplier is now active!'
|
||||
- '&e'
|
||||
booster-expired: '&cExpired!'
|
||||
|
||||
# PvP Mode
|
||||
pvp-mode:
|
||||
cooldown: '&cPlease wait {remaining} seconds to use this command again.'
|
||||
toggle-on: '&aPvP Mode on.'
|
||||
toggle-off: '&cPvP Mode off.'
|
||||
leave:
|
||||
pvp-allowed: '&cYou left a PVP zone but are still vulnerable for {remaining} seconds!'
|
||||
pvp-denied: '&cYou left the PVP zone.'
|
||||
enter:
|
||||
pvp-mode-on: '&aYou entered a PVP zone and gained invulnerability for {time} seconds!'
|
||||
pvp-mode-off: '&aYou entered a PVP zone. You may use /pvpmode to fight other players.'
|
||||
cooldown: '&cPlease wait {remaining} seconds to use this command again.'
|
||||
|
||||
# When you cannot hit another player
|
||||
cannot-hit:
|
||||
pvp-mode-disabled-target: '&cThis player has not toggled on PvP.'
|
||||
pvp-mode-disabled-self: '&cYou have not toggled on PvP.'
|
||||
invulnerable-self: '&cYou are still out of combat for {left} seconds.'
|
||||
invulnerable-target: '&cThis player is out of combat for {left} seconds.'
|
||||
|
||||
# When using /pvpmode
|
||||
toggle:
|
||||
on-safe: '&aYou will now be able to fight other players in dedicated areas.'
|
||||
on-invulnerable: '&aYou will be able to fight other players in {time} seconds.'
|
||||
off-safe: '&cYou can no longer fight other players.'
|
||||
|
||||
# Entering/leaving regions
|
||||
leave:
|
||||
pvp-allowed: '&cYou left a PVP zone but are still vulnerable for {remaining} seconds!'
|
||||
pvp-denied: '&cYou left the PVP zone.'
|
||||
enter:
|
||||
pvp-mode-on: '&aYou entered a PVP zone and gained invulnerability for {time} seconds!'
|
||||
pvp-mode-off: '&aYou entered a PVP zone. You may use /pvpmode to fight other players.'
|
||||
|
||||
# Fishing Profession
|
||||
caught-fish: '&cYou caught a fish!'
|
||||
@ -48,32 +61,32 @@ fish-out-water-crit: '&aCritical Fish!'
|
||||
|
||||
# Player Input
|
||||
player-input:
|
||||
anvil:
|
||||
friend-request: 'Friend name..'
|
||||
party-invite: 'Player name..'
|
||||
guild-invite: 'Player name..'
|
||||
guild-creation-tag: 'Guild tag..'
|
||||
guild-creation-name: 'Guild name..'
|
||||
chat:
|
||||
friend-request: '&eWrite in the chat the player name.'
|
||||
party-invite: '&eWrite in the chat the player you want to invite.'
|
||||
guild-invite: '&eWrite in the chat the player you want to invite.'
|
||||
guild-creation-tag: '&eWrite in the chat the TAG of the Guild you want to create.'
|
||||
guild-creation-name: '&eWrite in the chat the name of the Guild you want to create.'
|
||||
cancel: '&eWrite &c''cancel'' &eto cancel.'
|
||||
anvil:
|
||||
friend-request: 'Friend name..'
|
||||
party-invite: 'Player name..'
|
||||
guild-invite: 'Player name..'
|
||||
guild-creation-tag: 'Guild tag..'
|
||||
guild-creation-name: 'Guild name..'
|
||||
chat:
|
||||
friend-request: '&eWrite in the chat the player name.'
|
||||
party-invite: '&eWrite in the chat the player you want to invite.'
|
||||
guild-invite: '&eWrite in the chat the player you want to invite.'
|
||||
guild-creation-tag: '&eWrite in the chat the TAG of the Guild you want to create.'
|
||||
guild-creation-name: '&eWrite in the chat the name of the Guild you want to create.'
|
||||
cancel: '&eWrite &c''cancel'' &eto cancel.'
|
||||
|
||||
# Spell Casting
|
||||
casting:
|
||||
action-bar:
|
||||
ready: '&6[{index}] &a&l{skill}'
|
||||
on-cooldown: '&6[{index}] &c&l{skill} &6(&c{cooldown}&6)'
|
||||
no-mana: '&6[{index}] &9&l{skill}'
|
||||
no-stamina: '&6[{index}] &9&l{skill}'
|
||||
split: '&7 &7 - &7 '
|
||||
no-longer: '%&cYou cancelled skill casting.'
|
||||
no-mana: '&cYou do not have enough {mana}, {mana-required} more required!'
|
||||
no-stamina: '&cYou do not have enough stamina!'
|
||||
on-cooldown: '&cThis skill is on a {cooldown}s cooldown.'
|
||||
action-bar:
|
||||
ready: '&6[{index}] &a&l{skill}'
|
||||
on-cooldown: '&6[{index}] &c&l{skill} &6(&c{cooldown}&6)'
|
||||
no-mana: '&6[{index}] &9&l{skill}'
|
||||
no-stamina: '&6[{index}] &9&l{skill}'
|
||||
split: '&7 &7 - &7 '
|
||||
no-longer: '%&cYou cancelled skill casting.'
|
||||
no-mana: '&cYou do not have enough {mana}, {mana-required} more required!'
|
||||
no-stamina: '&cYou do not have enough stamina!'
|
||||
on-cooldown: '&cThis skill is on a {cooldown}s cooldown.'
|
||||
|
||||
# Combat Log
|
||||
now-in-combat: '%&cYou are now in combat!'
|
||||
@ -112,20 +125,20 @@ friend-request-cooldown: '&cPlease wait {cooldown}.'
|
||||
cant-request-to-yourself: '&cYou can''t send a request to yourself.'
|
||||
already-friends: '&cYou are already friends with {player}.'
|
||||
friend-request:
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ejust sent you a friend request!"}'
|
||||
- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/friends accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/friends deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ejust sent you a friend request!"}'
|
||||
- '[{"text":" ","hoverEvent":{}},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/friends accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r ","hoverEvent":{}},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/friends deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
|
||||
# Parties
|
||||
party-chat: '&5[Party] {player}: {message}'
|
||||
sent-party-invite: '&eYou sent a party invite to &6{player}&e.'
|
||||
already-in-party: '&c{player} is already in your party.'
|
||||
party-invite:
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ehas invited you to their party!"}'
|
||||
- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/party accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/party deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ehas invited you to their party!"}'
|
||||
- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/party accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/party deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
party-is-full: '&cSorry, your party is full.'
|
||||
party-joined: '&eYou successfully joined &6{owner}&e''s party.'
|
||||
party-joined-other: '&6{player}&e joined your party!'
|
||||
@ -139,10 +152,10 @@ guild-chat: '&a[{tag}] {player}: {message}'
|
||||
sent-guild-invite: '&eYou sent a guild invite to &6{player}&e.'
|
||||
already-in-guild: '&c{player} is already in your guild.'
|
||||
guild-invite:
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ehas invited you to their guild!"}'
|
||||
- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/guild accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/guild deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
- '{"text":""}'
|
||||
- '{"text":"&6{player} &ehas invited you to their guild!"}'
|
||||
- '[{"text":" "},{"text":"&8[&a&lACCEPT&8]","clickEvent":{"action":"run_command","value":"/guild accept {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to accept!"}},{"text":"&r "},{"text":"&8[&c&lDENY&8]","clickEvent":{"action":"run_command","value":"/guild deny {uuid}"},"hoverEvent":{"action":"show_text","value":"&eClick to deny."}}]'
|
||||
- '{"text":""}'
|
||||
#guild-is-full: '&cSorry, your guild is full.' -Unused right now
|
||||
guild-joined: '&eYou successfully joined &6{owner}&e''s guild.'
|
||||
guild-joined-other: '&6{player}&e joined your guild!'
|
||||
@ -150,11 +163,11 @@ transfer-guild-ownership: '&eYou were transfered the guild ownership.'
|
||||
kick-from-guild: '&eYou successfully kicked &6{player}&e from the guild.'
|
||||
guild-invite-cooldown: '&cPlease wait {cooldown} before inviting {player}.'
|
||||
guild-creation:
|
||||
failed: "&cCouldn't create guild: {reason}"
|
||||
reasons:
|
||||
invalid-characters: "&eInvalid character(s)!"
|
||||
invalid-length: "&eThe length must be between {min} and {max}!"
|
||||
already-exists: "&eThat guild tag already exists!"
|
||||
failed: "&cCouldn't create guild: {reason}"
|
||||
reasons:
|
||||
invalid-characters: "&eInvalid character(s)!"
|
||||
invalid-length: "&eThe length must be between {min} and {max}!"
|
||||
already-exists: "&eThat guild tag already exists!"
|
||||
|
||||
# Quests
|
||||
already-on-quest: '&cYou are already on a quest.'
|
||||
@ -175,9 +188,9 @@ attribute-level-up: '&eYou successfully leveled up your &6{attribute}&e.' # {lev
|
||||
|
||||
# Class selection
|
||||
cant-choose-new-class:
|
||||
- '&cYou need one class point to perform this action.'
|
||||
- '&cYou need one class point to perform this action.'
|
||||
no-permission-for-class:
|
||||
- "&cYou don't have the permission to choose this class."
|
||||
- "&cYou don't have the permission to choose this class."
|
||||
|
||||
# Skills
|
||||
no-class-skill: '&cYour class has no skill.'
|
||||
|
@ -22,7 +22,7 @@ exp-sources: {}
|
||||
on-fish:
|
||||
overriding-drop-table:
|
||||
conditions:
|
||||
- 'region{name=swamp,second-region}'
|
||||
- 'region{name="swamp,second-region"}'
|
||||
- 'biome{name=beach}'
|
||||
|
||||
# When drop table is read, one of these
|
||||
|
Loading…
Reference in New Issue
Block a user