forked from Upstream/mmocore
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
e0bdfa2000
@ -46,8 +46,8 @@ import net.Indyuce.mmocore.skill.binding.BoundSkillInfo;
|
||||
import net.Indyuce.mmocore.skill.binding.SkillSlot;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeStatus;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeStatus;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import net.Indyuce.mmocore.waypoint.Waypoint;
|
||||
import net.Indyuce.mmocore.waypoint.WaypointOption;
|
||||
@ -351,7 +351,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
/**
|
||||
* @return If the item is unlocked by the player
|
||||
* This is used for skills that can be locked & unlocked.
|
||||
* This is used for skills that can be locked & unlocked.
|
||||
*/
|
||||
public boolean hasUnlocked(Unlockable unlockable) {
|
||||
return unlockable.isUnlockedByDefault() || unlockedItems.contains(unlockable.getUnlockNamespacedKey());
|
||||
@ -745,6 +745,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
final int y = getPlayer().getLocation().getBlockY();
|
||||
final int z = getPlayer().getLocation().getBlockZ();
|
||||
final int warpTime = target.getWarpTime();
|
||||
final boolean hasPerm = getPlayer().hasPermission("mmocore.bypass-waypoint-wait");
|
||||
int t;
|
||||
|
||||
public void run() {
|
||||
@ -757,7 +758,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
}
|
||||
|
||||
MMOCore.plugin.configManager.getSimpleMessage("warping-comencing", "left", String.valueOf((warpTime - t) / 20)).send(getPlayer());
|
||||
if (t++ >= warpTime) {
|
||||
if (hasPerm || t++ >= warpTime) {
|
||||
getPlayer().teleport(target.getLocation());
|
||||
getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20, 1, false, false));
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_TELEPORT).playTo(getPlayer());
|
||||
@ -1003,29 +1004,30 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
return skillCasting != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the PlayerEnterCastingModeEvent successfully put the player into casting mode, otherwise if the event is cancelled, returns false.
|
||||
* @apiNote Changed to a boolean to reflect the cancellation state of the event being fired
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setSkillCasting(@NotNull SkillCastingInstance skillCasting) {
|
||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||
PlayerEnterCastingModeEvent event = new PlayerEnterCastingModeEvent(getPlayer());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) return false;
|
||||
|
||||
if (event.isCancelled()){
|
||||
skillCasting.close();
|
||||
return false;
|
||||
}
|
||||
this.skillCasting = skillCasting;
|
||||
skillCasting.close();
|
||||
setSkillCasting();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* API Method
|
||||
* @return true if the PlayerEnterCastingModeEvent successfully put the player into casting mode, otherwise if the event is cancelled, returns false.
|
||||
* @apiNote Changed to a boolean to reflect the cancellation state of the event being fired
|
||||
*/
|
||||
public void setSkillCasting() {
|
||||
public boolean setSkillCasting() {
|
||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||
setSkillCasting(SkillCastingMode.getCurrent().newInstance(this));
|
||||
PlayerEnterCastingModeEvent event = new PlayerEnterCastingModeEvent(getPlayer());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) return false;
|
||||
|
||||
this.skillCasting = SkillCastingMode.getCurrent().newInstance(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -1035,27 +1037,25 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
/**
|
||||
* API Method to leave casting mode and fire the PlayerExitCastingModeEvent
|
||||
*
|
||||
* @return true if the skill casting mode was left, or false if the event was cancelled, keeping the player in casting mode.
|
||||
*/
|
||||
public boolean leaveSkillCasting(){
|
||||
return this.leaveSkillCasting(false);
|
||||
public boolean leaveSkillCasting() {
|
||||
return leaveSkillCasting(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skipEvent Skip Firing the PlayerExitCastingModeEvent
|
||||
* @return true if the PlayerExitCastingModeEvent is not cancelled, or if the event is skipped.
|
||||
*
|
||||
*/
|
||||
public boolean leaveSkillCasting(boolean skipEvent) {
|
||||
Validate.isTrue(isCasting(), "Player not in casting mode");
|
||||
if (!skipEvent) {
|
||||
PlayerExitCastingModeEvent event = new PlayerExitCastingModeEvent(getPlayer());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
if (event.isCancelled()) return false;
|
||||
}
|
||||
|
||||
skillCasting.close();
|
||||
this.skillCasting = null;
|
||||
setLastActivity(PlayerActivity.ACTION_BAR_MESSAGE, 0); // Reset action bar
|
||||
@ -1221,7 +1221,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
* checks if they could potentially upgrade to one of these
|
||||
*
|
||||
* @return If the player can change its current class to
|
||||
* a subclass
|
||||
* a subclass
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canChooseSubclass() {
|
||||
|
@ -1,9 +1,10 @@
|
||||
package net.Indyuce.mmocore.api.player.attribute;
|
||||
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.api.stat.StatInstance;
|
||||
import io.lumine.mythic.lib.api.stat.handler.StatHandler;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
/**
|
||||
* This fixes an issue where registering new stat modifiers in ML
|
||||
@ -13,17 +14,13 @@ import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
* 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 {
|
||||
public class MMOCoreAttributeStatHandler extends StatHandler {
|
||||
private final PlayerAttribute attr;
|
||||
private final String statName;
|
||||
|
||||
public MMOCoreAttributeStatHandler(PlayerAttribute attr) {
|
||||
public MMOCoreAttributeStatHandler(ConfigurationSection config, PlayerAttribute attr) {
|
||||
super(config, "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_"));
|
||||
|
||||
this.attr = attr;
|
||||
this.statName = "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_");
|
||||
}
|
||||
|
||||
public String getStat() {
|
||||
return statName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,22 +28,12 @@ public class MMOCoreAttributeStatHandler implements StatHandler {
|
||||
* is not loaded yet, hence the try/catch clause
|
||||
*/
|
||||
@Override
|
||||
public void runUpdate(StatMap statMap) {
|
||||
public void runUpdate(StatInstance instance) {
|
||||
try {
|
||||
final PlayerData playerData = MMOCore.plugin.dataProvider.getDataManager().get(statMap.getPlayerData().getUniqueId());
|
||||
final PlayerData playerData = MMOCore.plugin.dataProvider.getDataManager().get(instance.getMap().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);
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
|
||||
for (String key : config.getStringList("main-exp-sources"))
|
||||
try {
|
||||
MMOCore.plugin.experience.registerSource(MMOCore.plugin.loadManager.loadExperienceSource(new MMOLineConfig(key), this));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
} catch (RuntimeException exception) {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load exp source '" + key + "' from class '"
|
||||
+ id + "': " + exception.getMessage());
|
||||
}
|
||||
|
@ -39,8 +39,14 @@ public class MMOCoreUtils {
|
||||
: caseOnWords(item.getType().name().replace("_", " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param current Current value of resource
|
||||
* @param maxStat Maximum value of resource
|
||||
* @return Clamped resource value. If the provided current value is 0,
|
||||
* this function will return the maximum resource value.
|
||||
*/
|
||||
public static double fixResource(double current, double maxStat) {
|
||||
return current == 0 ? maxStat : Math.min(current, maxStat);
|
||||
return current == 0 ? maxStat : Math.max(0, Math.min(current, maxStat));
|
||||
}
|
||||
|
||||
public static String caseOnWords(String s) {
|
||||
@ -62,7 +68,6 @@ public class MMOCoreUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value an integer you want to convert
|
||||
* @return the string representing the integer but with roman letters
|
||||
*/
|
||||
@ -82,23 +87,25 @@ public class MMOCoreUtils {
|
||||
roman_numerals.put("IV", 4);
|
||||
roman_numerals.put("I", 1);
|
||||
String res = "";
|
||||
for(Map.Entry<String, Integer> entry : roman_numerals.entrySet()){
|
||||
int matches = value/entry.getValue();
|
||||
for (Map.Entry<String, Integer> entry : roman_numerals.entrySet()) {
|
||||
int matches = value / entry.getValue();
|
||||
res += repeat(entry.getKey(), matches);
|
||||
value = value % entry.getValue();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static String repeat(String s, int n) {
|
||||
if(s == null) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an in game indicator using a hologram. This uses
|
||||
* LumineUtils hologramFactory to summon holograms
|
||||
@ -260,8 +267,9 @@ public class MMOCoreUtils {
|
||||
* @param damage Damage that needs to be applied
|
||||
*/
|
||||
public static void decreaseDurability(Player player, EquipmentSlot slot, int damage) {
|
||||
|
||||
ItemStack item = player.getInventory().getItem(slot);
|
||||
if (item == null || item.getType().getMaxDurability() == 0 || !item.hasItemMeta() || !(item.getItemMeta() instanceof Damageable) || item.getItemMeta().isUnbreakable())
|
||||
if (item == null || item.getType().getMaxDurability() == 0 || item.getItemMeta().isUnbreakable())
|
||||
return;
|
||||
|
||||
PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, item, damage);
|
||||
@ -270,11 +278,12 @@ public class MMOCoreUtils {
|
||||
return;
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (event.getDamage() + ((Damageable) meta).getDamage() >= item.getType().getMaxDurability()) {
|
||||
final int newDamage = event.getDamage() + ((Damageable) meta).getDamage();
|
||||
if (newDamage >= item.getType().getMaxDurability()) {
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1F, 1F);
|
||||
player.getInventory().setItem(slot, null);
|
||||
} else {
|
||||
((Damageable) meta).setDamage(((Damageable) meta).getDamage() + event.getDamage());
|
||||
((Damageable) meta).setDamage(newDamage);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import io.lumine.mythic.lib.api.event.PlayerKillEntityEvent;
|
||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||
import io.lumine.mythic.lib.util.FlushableRegistry;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
@ -15,9 +16,11 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
||||
private final EntityType type;
|
||||
@ -37,17 +40,36 @@ public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
||||
public ExperienceSourceManager<KillMobExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<KillMobExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void a(PlayerKillEntityEvent event) {
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
|
||||
if (event.getTarget().isDead() && !event.getTarget().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING)) {
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
/**
|
||||
* This map is used to keep track of the last player who
|
||||
* hit some entity. It is flushed on entity death.
|
||||
*/
|
||||
private final FlushableRegistry<UUID, UUID> registry = new FlushableRegistry<>((entity, attacker) -> Bukkit.getEntity(entity) == null, 20 * 60);
|
||||
|
||||
for (KillMobExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getTarget()))
|
||||
source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getTarget()));
|
||||
}
|
||||
}, 2);
|
||||
@Override
|
||||
public void whenClosed() {
|
||||
registry.close();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void registerLastAttacker(PlayerAttackEvent event) {
|
||||
registry.getRegistry().put(event.getEntity().getUniqueId(), event.getAttacker().getData().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void giveExp(EntityDeathEvent event) {
|
||||
|
||||
// Always remove entry from map
|
||||
final @Nullable UUID lastAttacker = this.registry.getRegistry().remove(event.getEntity().getUniqueId());
|
||||
if (lastAttacker == null) return;
|
||||
|
||||
if (event.getEntity().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING))
|
||||
return;
|
||||
|
||||
final PlayerData data = PlayerData.get(lastAttacker);
|
||||
for (KillMobExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getEntity()))
|
||||
source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getEntity()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -8,18 +8,17 @@ import org.bukkit.block.Biome;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
|
||||
public class BiomeCondition extends Condition {
|
||||
private final List<String> names;
|
||||
private final List<String> names;
|
||||
|
||||
public BiomeCondition(MMOLineConfig config) {
|
||||
super(config);
|
||||
public BiomeCondition(MMOLineConfig config) {
|
||||
super(config);
|
||||
|
||||
config.validate("name");
|
||||
names = Arrays.asList(config.getString("name").toUpperCase().split(","));
|
||||
}
|
||||
config.validate("name");
|
||||
names = Arrays.asList(config.getString("name").toUpperCase().split(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
Biome currentBiome = entity.getEntity().getLocation().getBlock().getBiome();
|
||||
return names.contains(currentBiome.name());
|
||||
}
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance instance) {
|
||||
return names.contains(instance.getLocation().getBlock().getBiome().name());
|
||||
}
|
||||
}
|
||||
|
@ -6,36 +6,44 @@ import java.util.stream.Stream;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConditionInstance {
|
||||
private final Entity entity;
|
||||
private final Location applied;
|
||||
private final List<String> regions;
|
||||
private final Entity entity;
|
||||
private final Location applied;
|
||||
private final List<String> regions;
|
||||
|
||||
public ConditionInstance(Entity entity) {
|
||||
this(entity, entity.getLocation());
|
||||
}
|
||||
public ConditionInstance(@NotNull Entity entity) {
|
||||
this(entity, entity.getLocation());
|
||||
}
|
||||
|
||||
public ConditionInstance(Entity entity, Location applied) {
|
||||
this.entity = entity;
|
||||
this.regions = MMOCore.plugin.regionHandler.getRegions(this.applied = applied);
|
||||
|
||||
regions.add("__global__");
|
||||
}
|
||||
public ConditionInstance(@NotNull Entity entity, @NotNull Location applied) {
|
||||
this.entity = entity;
|
||||
this.regions = MMOCore.plugin.regionHandler.getRegions(this.applied = applied);
|
||||
|
||||
public boolean isInRegion(String name) {
|
||||
return regions.contains(name);
|
||||
}
|
||||
regions.add("__global__");
|
||||
}
|
||||
|
||||
public Location getAppliedLocation() {
|
||||
return applied;
|
||||
}
|
||||
public boolean isInRegion(String name) {
|
||||
return regions.contains(name);
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
@Deprecated
|
||||
public Location getAppliedLocation() {
|
||||
return applied;
|
||||
}
|
||||
|
||||
public Stream<String> getRegionStream() {
|
||||
return regions.stream();
|
||||
}
|
||||
@NotNull
|
||||
public Location getLocation() {
|
||||
return applied;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Stream<String> getRegionStream() {
|
||||
return regions.stream();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class DistanceCondition extends Condition{
|
||||
public class DistanceCondition extends Condition {
|
||||
private final Location location;
|
||||
private final double distance;
|
||||
|
||||
@ -17,18 +17,14 @@ public class DistanceCondition extends Condition{
|
||||
Validate.isTrue(config.contains("y"));
|
||||
Validate.isTrue(config.contains("z"));
|
||||
Validate.isTrue(config.contains("distance"));
|
||||
Validate.isTrue(Bukkit.getWorld(config.getString("world"))!=null,"This world doesn't exist");
|
||||
location=new Location(Bukkit.getWorld(config.getString("world")),config.getDouble("x"),
|
||||
config.getDouble("y"),config.getDouble("z"));
|
||||
distance=config.getDouble("distance");
|
||||
Validate.isTrue(Bukkit.getWorld(config.getString("world")) != null, "This world doesn't exist");
|
||||
location = new Location(Bukkit.getWorld(config.getString("world")), config.getDouble("x"),
|
||||
config.getDouble("y"), config.getDouble("z"));
|
||||
distance = config.getDouble("distance");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
Entity entity1=entity.getEntity();
|
||||
return entity1.getWorld().equals(location.getWorld())&&location.distance(entity1.getLocation())<distance;
|
||||
public boolean isMet(ConditionInstance instance) {
|
||||
return instance.getLocation().getWorld().equals(location.getWorld()) && location.distance(instance.getLocation()) < distance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -21,17 +21,13 @@ public class TimeCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
if (entity.getEntity() instanceof Player player) {
|
||||
long time = player.getWorld().getTime();
|
||||
long time = entity.getLocation().getWorld().getTime();
|
||||
|
||||
if (min < max) {
|
||||
return time > min && time < max;
|
||||
} else {
|
||||
// Allows for wrapping times, such as min=20000 max=6000
|
||||
return time > min || time < max;
|
||||
}
|
||||
if (min < max) {
|
||||
return time > min && time < max;
|
||||
} else {
|
||||
// Allows for wrapping times, such as min=20000 max=6000
|
||||
return time > min || time < max;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -18,15 +18,13 @@ public class WeatherCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
if (entity.getEntity() instanceof Player player) {
|
||||
boolean isClear = player.getWorld().isClearWeather();
|
||||
boolean hasStorm = player.getWorld().hasStorm();
|
||||
boolean isClear = entity.getLocation().getWorld().isClearWeather();
|
||||
boolean hasStorm = entity.getLocation().getWorld().hasStorm();
|
||||
|
||||
if (condition.equalsIgnoreCase("clear")) {
|
||||
return isClear;
|
||||
} else if (condition.equalsIgnoreCase("stormy")) {
|
||||
return hasStorm;
|
||||
}
|
||||
if (condition.equalsIgnoreCase("clear")) {
|
||||
return isClear;
|
||||
} else if (condition.equalsIgnoreCase("stormy")) {
|
||||
return hasStorm;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -17,6 +17,6 @@ public class WorldCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public boolean isMet(ConditionInstance entity) {
|
||||
return names.contains(entity.getEntity().getWorld().getName()) || names.contains("__global__");
|
||||
return names.contains(entity.getLocation().getWorld().getName()) || names.contains("__global__");
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ 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.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -46,8 +47,9 @@ public class AttributeManager implements MMOCoreManager {
|
||||
MMOCore.log(Level.WARNING, "Could not load attribute '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
final ConfigurationSection statsConfig = new ConfigFile(MythicLib.plugin, "", "stats").getConfig();
|
||||
for (PlayerAttribute attr : getAll()) {
|
||||
final MMOCoreAttributeStatHandler handler = new MMOCoreAttributeStatHandler(attr);
|
||||
final MMOCoreAttributeStatHandler handler = new MMOCoreAttributeStatHandler(statsConfig, attr);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat(), handler);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat() + "_PERCENT", handler);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
@ -25,10 +25,8 @@ public class ExperienceManager implements MMOCoreManager {
|
||||
* Experience sources from the exp-sources.yml config file where you can
|
||||
* input any exp source which can later be used along with the 'from'
|
||||
* exp source anywhere in the plugin.
|
||||
* <p>
|
||||
* TODO First needs to edit the exp-source current structure. This is going to break a lot of things
|
||||
*
|
||||
* @deprecated See TODO
|
||||
* @deprecated TODO First needs to edit the exp-source current structure. This is going to break a lot of things
|
||||
*/
|
||||
@Deprecated
|
||||
private final Map<String, List<ExperienceSource<?>>> publicExpSources = new HashMap<>();
|
||||
@ -55,6 +53,7 @@ public class ExperienceManager implements MMOCoreManager {
|
||||
return expCurves.containsKey(id);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ExpCurve getCurveOrThrow(String id) {
|
||||
Validate.isTrue(hasCurve(id), "Could not find exp curve with ID '" + id + "'");
|
||||
return expCurves.get(id);
|
||||
@ -70,10 +69,12 @@ public class ExperienceManager implements MMOCoreManager {
|
||||
return expTables.containsKey(id);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ExperienceTable getTableOrThrow(String id) {
|
||||
return Objects.requireNonNull(expTables.get(id), "Could not find exp table with ID '" + id + "'");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ExperienceTable loadExperienceTable(Object obj) {
|
||||
|
||||
if (obj instanceof ConfigurationSection)
|
||||
@ -99,7 +100,7 @@ public class ExperienceManager implements MMOCoreManager {
|
||||
expCurves.clear();
|
||||
expTables.clear();
|
||||
|
||||
managers.values().forEach(HandlerList::unregisterAll);
|
||||
managers.forEach((c, manager) -> manager.close());
|
||||
managers.clear();
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,9 @@ public class RestrictionManager implements MMOCoreManager {
|
||||
String parentFormat = formatId(config.getString("parent"));
|
||||
parent = Objects.requireNonNull(map.get(parentFormat), "Could not find parent with ID '" + parentFormat + "'");
|
||||
}
|
||||
for (String key : config.getStringList("can-mine"))
|
||||
mineable.add(MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(key)).generateKey());
|
||||
if (config.contains("can-mine"))
|
||||
for (String key : config.getStringList("can-mine"))
|
||||
mineable.add(MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(key)).generateKey());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,15 +78,12 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
getData().setUnlockedItems(unlockedItems);
|
||||
if (!isEmpty(result.getString("guild"))) {
|
||||
final Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
|
||||
if (guild != null)
|
||||
getData().setGuild(guild.hasMember(getData().getUniqueId()) ? guild : null);
|
||||
if (guild != null) getData().setGuild(guild.hasMember(getData().getUniqueId()) ? guild : null);
|
||||
}
|
||||
if (!isEmpty(result.getString("attributes")))
|
||||
getData().getAttributes().load(result.getString("attributes"));
|
||||
if (!isEmpty(result.getString("attributes"))) getData().getAttributes().load(result.getString("attributes"));
|
||||
if (!isEmpty(result.getString("professions")))
|
||||
getData().getCollectionSkills().load(result.getString("professions"));
|
||||
if (!isEmpty(result.getString("quests")))
|
||||
getData().getQuestData().load(result.getString("quests"));
|
||||
if (!isEmpty(result.getString("quests"))) getData().getQuestData().load(result.getString("quests"));
|
||||
getData().getQuestData().updateBossBar();
|
||||
if (!isEmpty(result.getString("waypoints")))
|
||||
getData().getWaypoints().addAll(MMOCoreUtils.jsonArrayToList(result.getString("waypoints")));
|
||||
@ -101,8 +98,7 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
JsonObject object = MythicLib.plugin.getGson().fromJson(result.getString("bound_skills"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
ClassSkill skill = getData().getProfess().getSkill(entry.getValue().getAsString());
|
||||
if (skill != null)
|
||||
getData().bindSkill(Integer.parseInt(entry.getKey()), skill);
|
||||
if (skill != null) getData().bindSkill(Integer.parseInt(entry.getKey()), skill);
|
||||
|
||||
}
|
||||
}
|
||||
@ -123,15 +119,17 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
* These should be loaded after to make sure that the
|
||||
* MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
|
||||
*/
|
||||
double health = result.getDouble("health");
|
||||
getData().setMana(result.getDouble("mana"));
|
||||
getData().setStamina(result.getDouble("stamina"));
|
||||
getData().setStellium(result.getDouble("stellium"));
|
||||
if (getData().isOnline()) {
|
||||
//If the player is not dead and the health is 0, this means that the data was
|
||||
//missing from the data base and it gives full health to the player.
|
||||
health = health == 0 && !getData().getPlayer().isDead() ? getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() : health;
|
||||
health = Math.max(Math.min(health, getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()), 0);
|
||||
if (getData().isOnline() && !getData().getPlayer().isDead()) {
|
||||
|
||||
/*
|
||||
* If the player is not dead and the health is 0, this means that the data was
|
||||
* missing from the data base and it gives full health to the player. If the
|
||||
* player is dead however, it must not account for that subtle edge case.
|
||||
*/
|
||||
final double health = MMOCoreUtils.fixResource(result.getDouble("health"), getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
getData().getPlayer().setHealth(health);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ public class YAMLPlayerDataHandler extends YAMLSynchronizedDataHandler<PlayerDat
|
||||
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 (data.isOnline())
|
||||
if (data.isOnline() && !data.getPlayer().isDead())
|
||||
data.getPlayer().setHealth(MMOCoreUtils.fixResource(config.getDouble("health"), data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,23 @@
|
||||
package net.Indyuce.mmocore.manager.profession;
|
||||
|
||||
import io.lumine.mythic.lib.util.Closeable;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ExperienceSourceManager<T extends ExperienceSource> implements Listener {
|
||||
public abstract class ExperienceSourceManager<T extends ExperienceSource> implements Listener, Closeable {
|
||||
|
||||
/**
|
||||
* List of all active experience sources
|
||||
*/
|
||||
private final Set<T> sources = new HashSet<>();
|
||||
private boolean open = true;
|
||||
|
||||
public ExperienceSourceManager() {
|
||||
Bukkit.getPluginManager().registerEvents(this, MMOCore.plugin);
|
||||
@ -23,6 +27,19 @@ public abstract class ExperienceSourceManager<T extends ExperienceSource> implem
|
||||
sources.add(source);
|
||||
}
|
||||
|
||||
public void whenClosed() {
|
||||
// Nothing by default
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
Validate.isTrue(open, "Manager is already closed");
|
||||
open = false;
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
whenClosed();
|
||||
}
|
||||
|
||||
public Set<T> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FishHook;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
@ -36,8 +39,9 @@ public class FishingManager extends SpecificProfessionManager {
|
||||
MMOCore.plugin.statManager.registerProfession("CRITICAL_FISHING_FAILURE_CHANCE", getLinkedProfession());
|
||||
}
|
||||
|
||||
public FishingDropTable calculateDropTable(Entity entity) {
|
||||
ConditionInstance conditionEntity = new ConditionInstance(entity);
|
||||
@NotNull
|
||||
public FishingDropTable calculateDropTable(@NotNull Player player, @NotNull FishHook hook) {
|
||||
ConditionInstance conditionEntity = new ConditionInstance(player, hook.getLocation());
|
||||
|
||||
for (FishingDropTable table : tables)
|
||||
if (table.areConditionsMet(conditionEntity))
|
||||
|
@ -16,7 +16,6 @@ import org.bukkit.GameMode;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -74,6 +73,9 @@ public class KeyCombos implements SkillCastingListener {
|
||||
if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast)
|
||||
return;
|
||||
|
||||
// Don't start combos if no skills are bound
|
||||
if (playerData.getBoundSkills().isEmpty()) return;
|
||||
|
||||
// Start combo when there is an initializer key
|
||||
if (!event.getData().isCasting() && initializerKey != null) {
|
||||
if (event.getPressed() == initializerKey) {
|
||||
@ -82,7 +84,7 @@ public class KeyCombos implements SkillCastingListener {
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Start combo
|
||||
if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)) && beginComboSound != null)
|
||||
if (playerData.setSkillCasting() && beginComboSound != null)
|
||||
beginComboSound.playTo(player);
|
||||
|
||||
}
|
||||
@ -97,10 +99,9 @@ public class KeyCombos implements SkillCastingListener {
|
||||
// Start combo when there is NO initializer key
|
||||
else {
|
||||
final @NotNull ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap);
|
||||
if (comboMap.isComboStart(event.getPressed())) {
|
||||
casting = new CustomSkillCastingInstance(playerData);
|
||||
if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData)) && beginComboSound != null)
|
||||
beginComboSound.playTo(player);
|
||||
if (comboMap.isComboStart(event.getPressed()) && playerData.setSkillCasting()) {
|
||||
casting = (CustomSkillCastingInstance) playerData.getSkillCasting();
|
||||
if (beginComboSound != null) beginComboSound.playTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +175,8 @@ public class KeyCombos implements SkillCastingListener {
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (actionBarOptions != null) if (actionBarOptions.isSubtitle)
|
||||
if (getCaster().getBoundSkills().isEmpty()) close();
|
||||
else if (actionBarOptions != null) if (actionBarOptions.isSubtitle)
|
||||
getCaster().getPlayer().sendTitle(" ", actionBarOptions.format(this), 0, 20, 0);
|
||||
else getCaster().displayActionBar(actionBarOptions.format(this));
|
||||
}
|
||||
|
@ -55,11 +55,9 @@ public class SkillBar implements SkillCastingListener {
|
||||
|
||||
// Enter spell casting
|
||||
final PlayerData playerData = event.getData();
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills().isEmpty()) {
|
||||
if (playerData.setSkillCasting(new CustomSkillCastingInstance(playerData))) {
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills().isEmpty())
|
||||
if (playerData.setSkillCasting())
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomSkillCastingInstance extends SkillCastingInstance {
|
||||
|
@ -60,6 +60,7 @@ public class SkillScroller implements SkillCastingListener {
|
||||
Player player = playerData.getPlayer();
|
||||
if (player.getGameMode() == GameMode.CREATIVE && !MMOCore.plugin.configManager.canCreativeCast)
|
||||
return;
|
||||
|
||||
if (event.getPressed() == enterKey) {
|
||||
|
||||
// Leave casting mode
|
||||
@ -80,7 +81,7 @@ public class SkillScroller implements SkillCastingListener {
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Enter casting mode
|
||||
if (!playerData.setSkillCasting(new CustomSkillCastingInstance(playerData))) {
|
||||
if (!playerData.setSkillCasting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class Ambers extends SkillHandler<SimpleSkillResult> implements Listener
|
||||
if (passive == null)
|
||||
return;
|
||||
|
||||
passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity()));
|
||||
passive.getTriggeredSkill().cast(new TriggerMetadata(event));
|
||||
}
|
||||
|
||||
public static class Amber extends BukkitRunnable {
|
||||
|
@ -45,6 +45,6 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
|
||||
if (skill == null)
|
||||
return;
|
||||
|
||||
skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity()));
|
||||
skill.getTriggeredSkill().cast(new TriggerMetadata(event));
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class FishingListener implements Listener {
|
||||
* Checks for drop tables. If no drop table, just plain vanilla
|
||||
* fishing OTHERWISE initialize fishing, register other listener.
|
||||
*/
|
||||
FishingDropTable table = MMOCore.plugin.fishingManager.calculateDropTable(player);
|
||||
FishingDropTable table = MMOCore.plugin.fishingManager.calculateDropTable(player, hook);
|
||||
if (table == null)
|
||||
return;
|
||||
|
||||
|
@ -24,6 +24,9 @@ permissions:
|
||||
mmocore.currency:
|
||||
description: Access to /deposit and /withdraw
|
||||
default: op
|
||||
mmocore.bypass-waypoint-wait:
|
||||
description: Bypass waypoint waiting time
|
||||
default: op
|
||||
mmocore.class-select:
|
||||
description: Access to /class
|
||||
default: op
|
||||
|
Loading…
Reference in New Issue
Block a user