forked from Upstream/mmocore
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
57db8b91c3
@ -60,6 +60,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer {
|
||||
@ -376,6 +377,10 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
// Close quest data
|
||||
questData.close();
|
||||
|
||||
// Stop skill casting
|
||||
if (isCasting())
|
||||
leaveSkillCasting();
|
||||
}
|
||||
|
||||
public MMOPlayerData getMMOPlayerData() {
|
||||
@ -786,21 +791,28 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
if (value <= 0)
|
||||
return;
|
||||
|
||||
if (hasReachedMaxLevel()) {
|
||||
setExperience(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Splitting exp through party members
|
||||
AbstractParty party;
|
||||
if (splitExp && (party = getParty()) != null) {
|
||||
List<PlayerData> onlineMembers = party.getOnlineMembers();
|
||||
value /= onlineMembers.size();
|
||||
for (PlayerData member : onlineMembers)
|
||||
if (!equals(member))
|
||||
final List<PlayerData> nearbyMembers = party.getOnlineMembers().stream()
|
||||
.filter(pd -> {
|
||||
if (equals(pd) || pd.hasReachedMaxLevel())
|
||||
return false;
|
||||
|
||||
final double maxDis = MMOCore.plugin.configManager.partyMaxExpSplitRange;
|
||||
return maxDis <= 0 || pd.getPlayer().getLocation().distanceSquared(getPlayer().getLocation()) < maxDis * maxDis;
|
||||
}).collect(Collectors.toList());
|
||||
value /= (nearbyMembers.size() + 1);
|
||||
for (PlayerData member : nearbyMembers)
|
||||
member.giveExperience(value, source, null, false);
|
||||
}
|
||||
|
||||
// Must be placed after exp splitting
|
||||
if (hasReachedMaxLevel()) {
|
||||
setExperience(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply buffs AFTER splitting exp
|
||||
value *= (1 + getStats().getStat("ADDITIONAL_EXPERIENCE") / 100) * MMOCore.plugin.boosterManager.getMultiplier(null);
|
||||
|
||||
|
@ -0,0 +1,52 @@
|
||||
package net.Indyuce.mmocore.api.player.attribute;
|
||||
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.api.stat.handler.StatHandler;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
/**
|
||||
* This fixes an issue where registering new stat modifiers in ML
|
||||
* to add extra attribute points does NOT update the stats granted
|
||||
* by the attribute.
|
||||
* <p>
|
||||
* This stat handler MAY call subsequent stat handlers. There might
|
||||
* be infinite recursion problems if another attr. grants extra attribute pts.
|
||||
*/
|
||||
public class MMOCoreAttributeStatHandler implements StatHandler {
|
||||
private final PlayerAttribute attr;
|
||||
private final String statName;
|
||||
|
||||
public MMOCoreAttributeStatHandler(PlayerAttribute attr) {
|
||||
this.attr = attr;
|
||||
this.statName = "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_");
|
||||
}
|
||||
|
||||
public String getStat() {
|
||||
return statName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on login but the MMOCore playerData
|
||||
* is not loaded yet, hence the try/catch clause
|
||||
*/
|
||||
@Override
|
||||
public void runUpdate(StatMap statMap) {
|
||||
try {
|
||||
final PlayerData playerData = MMOCore.plugin.dataProvider.getDataManager().get(statMap.getPlayerData().getUniqueId());
|
||||
playerData.getAttributes().getInstance(attr).updateStats();
|
||||
} catch (NullPointerException exception) {
|
||||
// Player data is not loaded yet so there's nothing to update.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseValue(StatMap statMap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTotalValue(StatMap statMap) {
|
||||
return statMap.getStat(statName);
|
||||
}
|
||||
}
|
@ -132,7 +132,7 @@ public class PlayerAttributes {
|
||||
spent = Math.max(0, value);
|
||||
|
||||
if (data.isOnline())
|
||||
update();
|
||||
updateStats();
|
||||
}
|
||||
|
||||
public void addBase(int value) {
|
||||
@ -174,9 +174,13 @@ public class PlayerAttributes {
|
||||
}
|
||||
|
||||
public AttributeModifier addModifier(AttributeModifier modifier) {
|
||||
AttributeModifier mod = map.put(modifier.getKey(), modifier);
|
||||
update();
|
||||
return mod;
|
||||
final AttributeModifier current = map.put(modifier.getKey(), modifier);
|
||||
|
||||
if (current != null && current instanceof Closeable)
|
||||
((Closeable) current).close();
|
||||
|
||||
updateStats();
|
||||
return current;
|
||||
}
|
||||
|
||||
public Set<String> getKeys() {
|
||||
@ -188,7 +192,7 @@ public class PlayerAttributes {
|
||||
}
|
||||
|
||||
public AttributeModifier removeModifier(String key) {
|
||||
AttributeModifier mod = map.remove(key);
|
||||
final AttributeModifier mod = map.remove(key);
|
||||
|
||||
/*
|
||||
* Closing stat is really important with temporary stats because
|
||||
@ -198,14 +202,14 @@ public class PlayerAttributes {
|
||||
if (mod != null) {
|
||||
if (mod instanceof Closeable)
|
||||
((Closeable) mod).close();
|
||||
update();
|
||||
updateStats();
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
|
||||
int total = getTotal();
|
||||
public void updateStats() {
|
||||
final PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
|
||||
final int total = getTotal();
|
||||
attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,18 @@
|
||||
package net.Indyuce.mmocore.manager;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.api.player.attribute.MMOCoreAttributeStatHandler;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class AttributeManager implements MMOCoreManager {
|
||||
private final Map<String, PlayerAttribute> map = new HashMap<>();
|
||||
|
||||
@ -30,10 +32,12 @@ public class AttributeManager implements MMOCoreManager {
|
||||
|
||||
@Override
|
||||
public void initialize(boolean clearBefore) {
|
||||
if (clearBefore)
|
||||
if (clearBefore) {
|
||||
map.clear();
|
||||
MythicLib.plugin.getStats().clearRegisteredStats(handler -> handler instanceof MMOCoreAttributeStatHandler);
|
||||
}
|
||||
|
||||
ConfigFile config = new ConfigFile("attributes");
|
||||
final ConfigFile config = new ConfigFile("attributes");
|
||||
for (String key : config.getConfig().getKeys(false))
|
||||
try {
|
||||
String path = key.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
@ -41,5 +45,11 @@ public class AttributeManager implements MMOCoreManager {
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load attribute '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
for (PlayerAttribute attr : getAll()) {
|
||||
final MMOCoreAttributeStatHandler handler = new MMOCoreAttributeStatHandler(attr);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat(), handler);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat() + "_PERCENT", handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class ConfigManager {
|
||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||
public double lootChestsChanceWeight,dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange;
|
||||
public int maxPartyLevelDifference, maxBoundActiveSkills, maxBoundPassiveSkills, waypointWarpTime;
|
||||
public int maxPartyLevelDifference, maxBoundActiveSkills, maxBoundPassiveSkills;
|
||||
|
||||
private final FileConfiguration messages;
|
||||
|
||||
@ -82,8 +82,6 @@ public class ConfigManager {
|
||||
loadDefaultFile("skill-trees","rogue-marksman.yml");
|
||||
loadDefaultFile("skill-trees","warrior-paladin.yml");
|
||||
loadDefaultFile("skill-trees","general.yml");
|
||||
|
||||
|
||||
}
|
||||
|
||||
loadDefaultFile("attributes.yml");
|
||||
|
@ -31,15 +31,18 @@ public class SkillBar implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void a(PlayerKeyPressEvent event) {
|
||||
public void enterSkillCasting(PlayerKeyPressEvent event) {
|
||||
if (event.getPressed() != mainKey) return;
|
||||
|
||||
// Extra option to improve support with other plugins
|
||||
final Player player = event.getPlayer();
|
||||
if (disableSneak && player.isSneaking()) return;
|
||||
|
||||
// Always cancel event
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Enter spell casting
|
||||
Player player = event.getData().getPlayer();
|
||||
PlayerData playerData = event.getData();
|
||||
final PlayerData playerData = event.getData();
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills()
|
||||
.isEmpty()) {
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
@ -64,10 +67,9 @@ public class SkillBar implements Listener {
|
||||
public void onSkillCast(PlayerItemHeldEvent event) {
|
||||
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
||||
|
||||
if (!getCaster().isOnline()) {
|
||||
getCaster().leaveSkillCasting();
|
||||
return;
|
||||
}
|
||||
// Extra option to improve support with other plugins
|
||||
final Player player = event.getPlayer();
|
||||
if (disableSneak && player.isSneaking()) return;
|
||||
|
||||
/*
|
||||
* When the event is cancelled, another playerItemHeldEvent is
|
||||
@ -76,10 +78,6 @@ public class SkillBar implements Listener {
|
||||
*/
|
||||
if (event.getPreviousSlot() == event.getNewSlot()) return;
|
||||
|
||||
// Extra option to improve support with other plugins
|
||||
final Player player = event.getPlayer();
|
||||
if (disableSneak && player.isSneaking()) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
|
||||
|
||||
@ -97,8 +95,14 @@ public class SkillBar implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void stopCasting(PlayerKeyPressEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPressed() == mainKey && event.getPlayer().equals(getCaster().getPlayer())) {
|
||||
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
|
||||
|
||||
if (event.getPressed() != mainKey) return;
|
||||
|
||||
// Extra option to improve support with other plugins
|
||||
final Player player = event.getPlayer();
|
||||
if (disableSneak && player.isSneaking()) return;
|
||||
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_END).playTo(player);
|
||||
|
||||
new BukkitRunnable() {
|
||||
@ -109,7 +113,6 @@ public class SkillBar implements Listener {
|
||||
}.runTask(MMOCore.plugin);
|
||||
getCaster().leaveSkillCasting();
|
||||
}
|
||||
}
|
||||
|
||||
private String getFormat(PlayerData data) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
@ -90,6 +90,7 @@ should-cobblestone-generators-give-exp: false
|
||||
skill-casting:
|
||||
mode: SKILL_BAR
|
||||
open: SWAP_HANDS
|
||||
disable-sneak: false
|
||||
|
||||
loot-chests:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user