Merge remote-tracking branch 'origin/Ka0rX'

# Conflicts:
#	src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java
#	src/main/resources/config.yml
This commit is contained in:
Indyuce 2022-05-23 09:38:25 +02:00
commit e9aa71b616
58 changed files with 1495 additions and 410 deletions

38
pom.xml
View File

@ -39,10 +39,21 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>C:\Users\guill\Minecraft Server\Server\plugins</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>9</source>
<target>9</target>
@ -215,6 +226,33 @@
<scope>provided</scope>
</dependency>
<!--Quest Plugin-->
<dependency>
<groupId>me.blackvein</groupId>
<artifactId>Quests</artifactId>
<version>4.4.1-b340</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>fr.skytasul.quests</groupId>
<artifactId>BeautyQuests</artifactId>
<version>0.19.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.guillaumevdn</groupId>
<artifactId>QuestCreator</artifactId>
<version>6.39.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.guillaumevdn</groupId>
<artifactId>GCore</artifactId>
<version>8.39.0</version>
<scope>provided</scope>
</dependency>
<!-- Guild plugins -->
<dependency>
<groupId>com.massivecraft</groupId>

View File

@ -230,6 +230,19 @@ public class MMOCore extends LuminePlugin {
DebugMode.enableActionBar();
}
// Load quest module
try {
String questPluginName = UtilityMethods.enumName(getConfig().getString("quest-plugin"));
PartyModuleType moduleType = PartyModuleType.valueOf(questPluginName);
Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed");
partyModule = moduleType.provideModule();
} catch (RuntimeException exception) {
getLogger().log(Level.WARNING, "Could not initialize quest module: " + exception.getMessage());
partyModule = new MMOCorePartyModule();
}
// Load party module
try {
String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin"));
@ -241,6 +254,7 @@ public class MMOCore extends LuminePlugin {
partyModule = new MMOCorePartyModule();
}
// Skill casting
try {
SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));

View File

@ -16,14 +16,14 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel
private final Profession profession;
private final EXPSource source;
private int experience;
private double experience;
private boolean cancelled;
public PlayerExperienceGainEvent(PlayerData player, int experience, EXPSource source) {
public PlayerExperienceGainEvent(PlayerData player, double experience, EXPSource source) {
this(player, null, experience, source);
}
public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, int experience, EXPSource source) {
public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, double experience, EXPSource source) {
super(player);
this.profession = profession;
@ -31,7 +31,7 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel
this.source = source;
}
public int getExperience() {
public double getExperience() {
return experience;
}

View File

@ -1,26 +1,19 @@
package net.Indyuce.mmocore.api.load;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.loot.droptable.condition.*;
import net.Indyuce.mmocore.experience.source.*;
import net.Indyuce.mmocore.loot.chest.condition.*;
import org.bukkit.configuration.ConfigurationSection;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.api.block.SkullBlockType;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem;
import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem;
import net.Indyuce.mmocore.loot.droptable.dropitem.NoteDropItem;
import net.Indyuce.mmocore.loot.droptable.dropitem.VanillaDropItem;
import net.Indyuce.mmocore.experience.source.BrewPotionExperienceSource;
import net.Indyuce.mmocore.experience.source.CraftItemExperienceSource;
import net.Indyuce.mmocore.experience.source.EnchantItemExperienceSource;
import net.Indyuce.mmocore.experience.source.FishItemExperienceSource;
import net.Indyuce.mmocore.experience.source.KillMobExperienceSource;
import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource;
import net.Indyuce.mmocore.experience.source.PlaceBlockExperienceSource;
import net.Indyuce.mmocore.experience.source.RepairItemExperienceSource;
import net.Indyuce.mmocore.experience.source.SmeltItemExperienceSource;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.quest.objective.ClickonObjective;
import net.Indyuce.mmocore.api.quest.objective.GoToObjective;
@ -105,7 +98,7 @@ public class DefaultMMOLoader extends MMOLoader {
@Override
public Condition loadCondition(MMOLineConfig config) {
if(config.getKey().equals("distance"))
if (config.getKey().equals("distance"))
return new DistanceCondition(config);
if (config.getKey().equals("world"))
@ -125,8 +118,32 @@ public class DefaultMMOLoader extends MMOLoader {
@Override
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
if (config.getKey().equals("fishitem"))
return new FishItemExperienceSource(dispenser, config);
if (config.getKey().equals("resource"))
return new ResourceExperienceSource(dispenser, config);
if (config.getKey().equals("climb"))
return new ClimbExperienceSource(dispenser, config);
if (config.getKey().equals("damagedealt"))
return new DamageDealtExperienceSource(dispenser, config);
if (config.getKey().equals("damagetaken"))
return new DamageTakenExperienceSource(dispenser, config);
if (config.getKey().equals("move"))
return new MoveExperienceSource(dispenser, config);
if (config.getKey().equals("play"))
return new PlayExperienceSource(dispenser, config);
if (config.getKey().equals("projectile"))
return new ProjectileExperienceSource(dispenser, config);
if (config.getKey().equals("ride"))
return new RideExperienceSource(dispenser, config);
if (config.getKey().equals("tame"))
return new TameExperienceSource(dispenser, config);
if (config.getKey().equals("killmob"))
return new KillMobExperienceSource(dispenser, config);

View File

@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;

View File

@ -68,7 +68,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*/
@Nullable
private PlayerClass profess;
private int level, experience, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints,
private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints,
private double experience;
private double mana, stamina, stellium;
private Guild guild;
private SkillCastingHandler skillCasting;
@ -322,7 +323,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
giveExperience(total, source);
}
public void setExperience(int value) {
public void setExperience(double value) {
experience = Math.max(0, value);
refreshVanillaExp();
}
@ -518,7 +519,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* @param value Experience to give the player
* @param source How the player earned experience
*/
public void giveExperience(int value, EXPSource source) {
public void giveExperience(double value, EXPSource source) {
giveExperience(value, source, null, true);
}
@ -552,7 +553,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
member.giveExperience(value, EXPSource.PARTY_SHARING, null, false);
}
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, (int) value, source);
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
@ -593,7 +594,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
refreshVanillaExp();
}
public int getExperience() {
public double getExperience() {
return experience;
}

View File

@ -17,13 +17,14 @@ import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData;
public class SavedClassInformation {
private final int level, experience, skillPoints, attributePoints, attributeReallocationPoints;
private final int level, skillPoints, attributePoints, attributeReallocationPoints;
private final double experience;
private final Map<String, Integer> attributes;
private final Map<String, Integer> skills;
public SavedClassInformation(ConfigurationSection config) {
level = config.getInt("level");
experience = config.getInt("experience");
experience = config.getDouble("experience");
skillPoints = config.getInt("skill-points");
attributePoints = config.getInt("attribute-points");
attributeReallocationPoints = config.getInt("attribute-realloc-points");
@ -38,7 +39,7 @@ public class SavedClassInformation {
public SavedClassInformation(JsonObject json) {
level = json.get("level").getAsInt();
experience = json.get("experience").getAsInt();
experience = json.get("experience").getAsDouble();
skillPoints = json.get("skill-points").getAsInt();
attributePoints = json.get("attribute-points").getAsInt();
attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt();
@ -63,11 +64,11 @@ public class SavedClassInformation {
this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints());
}
public SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints) {
public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints) {
this(level, experience, skillPoints, attributePoints, attributeReallocationPoints, new HashMap<>(), new HashMap<>());
}
private SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints,
private SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints,
Map<String, Integer> attributes, Map<String, Integer> skills) {
this.level = level;
this.experience = experience;
@ -82,7 +83,7 @@ public class SavedClassInformation {
return level;
}
public int getExperience() {
public double getExperience() {
return experience;
}

View File

@ -3,8 +3,8 @@ package net.Indyuce.mmocore.comp.region;
import java.util.Arrays;
import java.util.List;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import io.lumine.mythic.lib.api.MMOLineConfig;
public class RegionCondition extends Condition {

View File

@ -1,6 +1,6 @@
package net.Indyuce.mmocore.comp.region;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.api.load.MMOLoader;
import io.lumine.mythic.lib.api.MMOLineConfig;

View File

@ -26,7 +26,7 @@ import java.util.Map;
import java.util.Map.Entry;
public class PlayerProfessions {
private final Map<String, Integer> exp = new HashMap<>();
private final Map<String, Double> exp = new HashMap<>();
private final Map<String, Integer> level = new HashMap<>();
private final PlayerData playerData;
@ -41,7 +41,7 @@ public class PlayerProfessions {
public PlayerProfessions load(ConfigurationSection config) {
for (String key : config.getKeys(false))
if (MMOCore.plugin.professionManager.has(key)) {
exp.put(key, config.getInt(key + ".exp"));
exp.put(key, config.getDouble(key + ".exp"));
level.put(key, config.getInt(key + ".level"));
}
@ -89,7 +89,7 @@ public class PlayerProfessions {
for (Entry<String, JsonElement> entry : obj.entrySet())
if (MMOCore.plugin.professionManager.has(entry.getKey())) {
JsonObject value = entry.getValue().getAsJsonObject();
exp.put(entry.getKey(), value.get("exp").getAsInt());
exp.put(entry.getKey(), value.get("exp").getAsDouble());
level.put(entry.getKey(), value.get("level").getAsInt());
}
@ -111,11 +111,11 @@ public class PlayerProfessions {
return getLevel(profession.getId());
}
public int getExperience(String id) {
return exp.getOrDefault(id, 0);
public double getExperience(String id) {
return exp.getOrDefault(id, 0.);
}
public int getExperience(Profession profession) {
public double getExperience(Profession profession) {
return getExperience(profession.getId());
}
@ -136,7 +136,7 @@ public class PlayerProfessions {
level.put(profession.getId(), Math.max(1, current - value));
}
public void setExperience(Profession profession, int value) {
public void setExperience(Profession profession, double value) {
exp.put(profession.getId(), value);
}
@ -147,7 +147,7 @@ public class PlayerProfessions {
giveExperience(profession, total, source);
}
public void giveExperience(Profession profession, int value, EXPSource source) {
public void giveExperience(Profession profession, double value, EXPSource source) {
giveExperience(profession, value, source, null);
}
@ -174,13 +174,14 @@ public class PlayerProfessions {
if (hologramLocation != null)
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source);
PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, value, source);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0) + event.getExperience()));
int needed, exp, level, oldLevel = getLevel(profession);
exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0.) + event.getExperience()));
int level, oldLevel = getLevel(profession);
double needed,exp;
/*
* Loop for exp overload when leveling up, will continue
@ -197,7 +198,7 @@ public class PlayerProfessions {
this.exp.put(profession.getId(), exp - needed);
this.level.put(profession.getId(), level + 1);
check = true;
playerData.giveExperience((int) profession.getExperience().calculate(level), null);
playerData.giveExperience(profession.getExperience().calculate(level), null);
}
if (check) {

View File

@ -17,7 +17,7 @@ public class ClassExperienceDispenser 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;
playerData.giveExperience(experience, source, hologramLocation, true);
}

View File

@ -16,7 +16,7 @@ public class ProfessionExperienceDispenser implements ExperienceDispenser {
@Override
public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) {
hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null
: hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation;
: hologramLocation;
playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation);
}

View File

@ -13,7 +13,10 @@ import java.util.Random;
public class ExperienceItem {
private final String id;
//A period of 0 means the item will only trigger one time.
private final int period;
private final int firstTrigger;
private final double claimChance, failReduction;
private final List<Trigger> triggers;
@ -23,6 +26,7 @@ public class ExperienceItem {
* One item for an experience table
*
* @param period The experience item is claimed every X level ups
* @param firstTrigger The experience item if claimed for the first time at X level ups.
* @param claimChance Chance for that item to be claimed every X level ups
* @param failReduction Between 0 and 1, by how much the fail chance is reduced
* every time the item is not claimed when leveling up.
@ -32,19 +36,22 @@ public class ExperienceItem {
* where n is the amount of successive claiming fails
* @param triggers Actions cast when the exp item is claimed
*/
public ExperienceItem(String id, int period, double claimChance, double failReduction, List<Trigger> triggers) {
public ExperienceItem(String id, int period, int firstTrigger,double claimChance, double failReduction, List<Trigger> triggers) {
this.id = id;
this.period = period;
this.claimChance = claimChance;
this.failReduction = failReduction;
this.triggers = triggers;
this.firstTrigger=firstTrigger;
}
public ExperienceItem(ConfigurationSection config) {
Validate.notNull(config, "Config cannot be null");
Validate.isTrue(config.contains("triggers"));
id = config.getName();
period = config.getInt("period", 1);
period = config.getInt("period", 0);
firstTrigger=config.getInt("first-trigger",period);
claimChance = config.getDouble("chance", 100) / 100;
failReduction = config.getDouble("fail-reduction", 80) / 100;
triggers = new ArrayList<>();
@ -64,7 +71,7 @@ public class ExperienceItem {
* account the randomness factor from the 'chance' parameter
*/
public boolean roll(int professionLevel, int timesCollected) {
int claimsRequired = professionLevel - (timesCollected + 1) * period;
int claimsRequired = professionLevel+1 - (firstTrigger-+timesCollected * period);
if (claimsRequired < 1)
return false;

View File

@ -168,7 +168,7 @@ public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
*/
// exp += getTotal(mapEffectDurations());
getDispenser().giveExperience(PlayerData.get(player), (int) exp * multiplier, null, EXPSource.SOURCE);
getDispenser().giveExperience(PlayerData.get(player), exp * multiplier, player.getLocation(), EXPSource.SOURCE);
}
}
}

View File

@ -0,0 +1,75 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.Vector;
public class ClimbExperienceSource extends SpecificExperienceSource<Material> {
//Can be Ladder,Vines,Twisting Vines,Weeping Vines.
private final Material type;
/**
* Gives Experience when a player climbs on a ladder, a vine, a twisting vine or a weeping vine depending
* on the type precised (if no type is precised it will give xp for the 4)
* The xp given depends on the vertical distance travelled, the random amount given correspond
* to the xp when you climb, one block
*/
public ClimbExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
//If no type precised Ladder and all vines types work
if (!config.contains("type"))
type = null;
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
Validate.isTrue(str.equals("LADDER") ||
str.equals("VINE") || str.equals("TWISTING_VINES_PLANT") || str.equals("WEEPING_VINES"),
"ClimbExperienceSource problem: The type must be ladder, vine, twisted-vines or weeping-vines");
type = Material.valueOf(str);
}
}
@Override
public ExperienceSourceManager<ClimbExperienceSource> newManager() {
return new ExperienceSourceManager<ClimbExperienceSource>() {
@EventHandler
public void onClimb(PlayerMoveEvent e) {
double delta=e.getTo().getBlockY()-e.getFrom().getBlockY();
if (delta > 0) {
if (e.getPlayer().hasMetadata("NPC"))
return;
PlayerData playerData = PlayerData.get(e.getPlayer());
for (ClimbExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, e.getFrom().getBlock().getType()))
source.giveExperience(playerData, delta, null);
}
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, Material material) {
if (type == null)
return material.equals(Material.LADDER) || material.equals(Material.VINE) ||
material.equals(Material.WEEPING_VINES) || material.equals(Material.TWISTING_VINES) ||
material.equals(Material.WEEPING_VINES_PLANT) || material.equals(Material.TWISTING_VINES_PLANT);
if (type.equals(Material.WEEPING_VINES))
return material.equals(Material.WEEPING_VINES) || material.equals(Material.WEEPING_VINES_PLANT);
if (type.equals(Material.TWISTING_VINES))
return material.equals(Material.TWISTING_VINES) || material.equals(Material.TWISTING_VINES_PLANT);
return material.equals(type);
}
}

View File

@ -0,0 +1,72 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.damage.DamagePacket;
import io.lumine.mythic.lib.damage.DamageType;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.event.EventHandler;
import scala.Enumeration;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public class DamageDealtExperienceSource extends SpecificExperienceSource<DamageType> {
private final DamageType type;
/**
* Gives experience when a player deals damage of a certain type. If no type is given it will give xp for all
* the damage type. The random value you give correspond to the xp you get per damage dealt.
*/
public DamageDealtExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("type"))
type = null;
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
//Checks if the damage type correspond to a value of the damage type enum
Validate.isTrue(Arrays.stream(DamageType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str),
"Type value not allowed. Type value allowed: magic, physical, weapon, skill, projectile," +
" unarmed, on-hit, minion, dot.");
type = DamageType.valueOf(str);
}
}
@Override
public ExperienceSourceManager<DamageDealtExperienceSource> newManager() {
return new ExperienceSourceManager<DamageDealtExperienceSource>() {
@EventHandler
public void onDamageDealt(PlayerAttackEvent e) {
PlayerData playerData = PlayerData.get(e.getPlayer());
for (DamageDealtExperienceSource source : getSources()) {
double value = 0;
for (DamagePacket packet : e.getDamage().getPackets()) {
for (DamageType damageType : packet.getTypes()) {
if (source.matchesParameter(playerData, damageType))
value += packet.getFinalValue();
}
}
source.giveExperience(playerData, value, null);
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, DamageType damageType) {
if (type == null)
return true;
else
return type.equals(damageType);
}
}

View File

@ -0,0 +1,72 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.damage.DamageType;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public class DamageTakenExperienceSource extends SpecificExperienceSource<EntityDamageEvent.DamageCause> {
private final EntityDamageEvent.DamageCause cause;
/**
* Gives experience when a player takes damage from a certain cause. If no cause is given it will give xp for all
* the damage causes. The random value you give correspond to the xp you get per damage taken.
*/
public DamageTakenExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("cause"))
cause = null;
else {
String str = config.getString("cause").toUpperCase().replace("-", "_");
//Checks if the damage type correspond to a value of the damage type enum
Validate.isTrue(Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Objects::toString).collect(Collectors.toList()).contains(str),
"Cause not allowed. Go check at all the Damage Causes in EntityDamageEvent.DamageCause enum.");
cause = EntityDamageEvent.DamageCause.valueOf(str);
}
}
@Override
public ExperienceSourceManager<DamageTakenExperienceSource> newManager() {
return new ExperienceSourceManager<DamageTakenExperienceSource>() {
@EventHandler
public void onDamageTaken(EntityDamageEvent e) {
if (e.getEntity() instanceof Player && !e.getEntity().hasMetadata("NPC")) {
double amount = e.getDamage();
PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity());
//We wait 2 tick to check if the player is Dead
new BukkitRunnable() {
@Override
public void run() {
for (DamageTakenExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, e.getCause()))
source.giveExperience(playerData, amount, null);
}
}
}.runTaskLater(MMOCore.plugin, 2);
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) {
if (player.getPlayer().isDead())
return false;
if (cause == null)
return true;
return damageCause.equals(cause);
}
}

View File

@ -0,0 +1,58 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang3.Validate;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.inventory.ItemStack;
public class EatExperienceSource extends SpecificExperienceSource<ItemStack> {
private final Material type;
/**
* Gives xp when you eat a certain type of food. If not type is given it will give xp from all the food sources.
* The amount of xp given is the xp per food regenerated.
*/
public EatExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if(!config.contains("type"))
type=null;
else {
Material material=Material.valueOf(config.getString("type").toUpperCase().replace("-","_"));
Validate.isTrue(material!=null,"You must precise a valid material!");
type=material;
}
}
@Override
public ExperienceSourceManager<EatExperienceSource> newManager() {
return new ExperienceSourceManager<EatExperienceSource>() {
@EventHandler
public void a(FoodLevelChangeEvent e) {
if (!(e.getEntity() instanceof Player) || e.getEntity().hasMetadata("NPC"))
return;
PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity());
for (EatExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, e.getItem()))
source.giveExperience(playerData, e.getFoodLevel(), null);
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, ItemStack obj) {
if(type==null)
return true;
return type.equals(obj.getType());
}
}

View File

@ -60,7 +60,7 @@ public class EnchantItemExperienceSource extends ExperienceSource<Void> {
double exp = 0;
for (Entry<Enchantment, Integer> entry : applicableEnchants.entrySet())
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
getDispenser().giveExperience(player, (int) exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE);
getDispenser().giveExperience(player, exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE);
}
}
};

View File

@ -0,0 +1,87 @@
package net.Indyuce.mmocore.experience.source;
import com.mojang.datafixers.types.Func;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.damage.DamageType;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import org.xml.sax.SAXParseException;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
public class MoveExperienceSource extends SpecificExperienceSource {
MovingType type;
public MoveExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("type"))
type = null;
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
//Checks if the damage type correspond to a value of the damage type enum
Validate.isTrue(Arrays.stream(MoveExperienceSource.MovingType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str),
"moving-type value not allowed. Moving type values allowed: sneak, fly, swim, sprint, walk.");
type = MovingType.valueOf(str);
}
}
@Override
public ExperienceSourceManager<MoveExperienceSource> newManager() {
return new ExperienceSourceManager<MoveExperienceSource>() {
@EventHandler
public void onMove(PlayerMoveEvent e) {
double deltax=e.getTo().getBlockX()-e.getFrom().getBlockX();
double deltay=e.getTo().getBlockY()-e.getFrom().getBlockY();
double deltaz=e.getTo().getBlockZ()-e.getFrom().getBlockZ();
if(deltax!=0&&deltay!=0&&deltaz!=0) {
double delta=Math.sqrt(deltax*deltax+deltay*deltay+deltaz*deltaz);
if(e.getPlayer().hasMetadata("NPC"))
return;
Player player=e.getPlayer();
PlayerData playerData =PlayerData.get(player);
for(MoveExperienceSource source:getSources()) {
if(source.matchesParameter(playerData,null)) {
giveExperience(playerData,delta,null);
}
}
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, Object obj) {
return type==null||type.matches(player.getPlayer());
}
public enum MovingType {
SNEAK(Player::isSneaking),
FLY((p)->p.isFlying()||p.isGliding()),
SWIM((p)->p.getLocation().getBlock().isLiquid()),
SPRINT(Player::isSprinting),
WALK((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.getLocation().getBlock().isLiquid());
private final Function<Player, Boolean> matching;
MovingType(Function<Player, Boolean> matching) {
this.matching = matching;
}
public boolean matches(Player player) {
return !player.isInsideVehicle()&&matching.apply(player);
}
}
}

View File

@ -0,0 +1,96 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable;
public class PlayExperienceSource extends SpecificExperienceSource {
private final World world;
private final double x1, x2, z1, z2;
private final boolean inCombat;
/**
* Experience source giving the specified amount of xp to all the players online each second in certain world bounds.
* If no bounds are given, it will give the xp to every player online. You can also specifiy if the player
* has to be inCombat or not to get the xp.
*/
public PlayExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("in-combat"))
inCombat = false;
else {
inCombat = config.getBoolean("in-combat");
}
if (!config.contains("world"))
world = null;
else {
String name = config.getString("world");
Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world"));
}
if (!config.contains("x1") || !config.contains("x2")) {
x1 = Double.NEGATIVE_INFINITY;
x2 = Double.POSITIVE_INFINITY;
} else {
x1 = Math.min(config.getInt("x1"), config.getInt("x2"));
x2 = Math.max(config.getInt("x1"), config.getInt("x2"));
}
if (!config.contains("z1") || !config.contains("z2")) {
z1 = Double.NEGATIVE_INFINITY;
z2 = Double.POSITIVE_INFINITY;
} else {
z1 = Math.min(config.getInt("z1"), config.getInt("z2"));
z2 = Math.max(config.getInt("z1"), config.getInt("z2"));
}
}
@Override
public ExperienceSourceManager<PlayExperienceSource> newManager() {
return new PlayingExperienceSourceManager();
}
@Override
public boolean matchesParameter(PlayerData player, Object obj) {
if (inCombat && !player.isInCombat())
return false;
if (world == null)
return true;
Location location = player.getPlayer().getLocation();
return location.getWorld().equals(world) && location.getX() > x1 && location.getX() < x2
&& location.getZ() > z1 && location.getZ() < z2;
}
private class PlayingExperienceSourceManager extends ExperienceSourceManager<PlayExperienceSource> {
public PlayingExperienceSourceManager() {
new BukkitRunnable() {
@Override
public void run() {
Bukkit.getOnlinePlayers().forEach((player) -> {
if (!player.hasMetadata("NPC")) {
PlayerData playerData = PlayerData.get(player);
for (PlayExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, null))
giveExperience(playerData, 1, null);
}
}
});
}
}.runTaskTimer(MMOCore.plugin, 0, 20);
}
}
}

View File

@ -0,0 +1,129 @@
package net.Indyuce.mmocore.experience.source;
import de.schlichtherle.key.passwd.swing.BasicUnknownKeyFeedback;
import io.lumine.mythic.core.skills.mechanics.ShootMechanic;
import io.lumine.mythic.lib.api.MMOLineConfig;
import me.glaremasters.guilds.utils.BackupUtils;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ProjectileExperienceSource extends SpecificExperienceSource<Projectile> {
private final ProjectileType projectileType;
public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("type"))
projectileType = null;
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
Validate.isTrue(Arrays.stream(ProjectileType.values()).map(ProjectileType::toString).collect(Collectors.toList()).contains(str));
projectileType = ProjectileType.valueOf(str);
}
}
@Override
public ExperienceSourceManager<ProjectileExperienceSource> newManager() {
return new ExperienceSourceManager<ProjectileExperienceSource>() {
HashMap<Projectile, Location> projectiles = new HashMap<>();
@EventHandler
public void onHit(ProjectileHitEvent e) {
if (e.getHitBlock() != null && projectiles.containsKey(e.getEntity()))
projectiles.remove(e.getEntity());
}
@EventHandler
public void onDamage(EntityDamageByEntityEvent e) {
if (e.getEntity() instanceof Projectile) {
Projectile projectile = (Projectile) e.getEntity();
if(!projectiles.containsKey(projectile))
return;
if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) {
Player player = (Player) projectile.getShooter();
PlayerData playerData = PlayerData.get(player);
double distance = projectiles.get(projectile).distance(e.getEntity().getLocation());
for (ProjectileExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, projectile))
source.giveExperience(playerData, e.getFinalDamage() * distance, null);
}
}
projectiles.remove(projectile);
}
}
//Mark every arrow with the the location at which it was shot to calculate the distance
@EventHandler
public void onLaunch(ProjectileLaunchEvent e) {
if (e.getEntity().getShooter() instanceof Player) {
Player player = (Player) e.getEntity().getShooter();
if (player.hasMetadata("NPC"))
return;
projectiles.put(e.getEntity(), e.getLocation());
//Remove the projectile 15 s after it was launched
new BukkitRunnable() {
@Override
public void run() {
projectiles.remove(e.getEntity());
}
}.runTaskLater(MMOCore.plugin, 60 * 20L);
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, Projectile projectile) {
if (projectileType == null)
return true;
return projectileType.matches(projectile);
}
public enum ProjectileType {
ARROW((p) -> p instanceof Arrow),
TRIDENT((p) -> p instanceof Trident);
private final Function<Projectile, Boolean> matching;
ProjectileType(Function<Projectile, Boolean> matching) {
this.matching = matching;
}
public boolean matches(Projectile projectile) {
return matching.apply(projectile);
}
}
}

View File

@ -75,7 +75,7 @@ public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
*/
double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType())
* Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100;
getDispenser().giveExperience(data, (int) exp, null, EXPSource.SOURCE);
getDispenser().giveExperience(data, exp, data.getPlayer().getLocation(), EXPSource.SOURCE);
}
}
}

View File

@ -0,0 +1,62 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.event.EventHandler;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public class ResourceExperienceSource extends SpecificExperienceSource<PlayerResource> {
private final PlayerResource resource;
/**
* Gives experience when the player uses a specific resoure. If no resource is precised it will trigger for
* mana, stamina and stellium. The amount specified si the xp given per resource consummed.
*/
public ResourceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("resource"))
resource = null;
else {
String str = config.getString("resource").toUpperCase().replace("-", "_");
Validate.isTrue(str.equals("MANA") || str.equals("STELLIUM") || str.equals("STAMINA"),
"ResourceExperienceSource problem: The resource can only be mana, stamina or STELLIUM");
resource = PlayerResource.valueOf(str);
}
}
@Override
public ExperienceSourceManager<ResourceExperienceSource> newManager() {
return new ExperienceSourceManager<ResourceExperienceSource>() {
@EventHandler
public void onResource(PlayerResourceUpdateEvent e) {
if (e.getPlayer().hasMetadata("NPC"))
return;
PlayerData playerData = PlayerData.get(e.getPlayer());
if(e.getAmount()<0)
for (ResourceExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, e.getResource()))
source.giveExperience(playerData, -e.getAmount(), null);
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, PlayerResource obj) {
if (resource == null)
return !obj.equals(PlayerResource.HEALTH);
return resource.equals(obj);
}
}

View File

@ -0,0 +1,74 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public class RideExperienceSource extends SpecificExperienceSource<EntityType> {
private final EntityType type;
/**
* Gives experience when a player moves riding a certain entity. If no entity type is given it will give xp if you move
* while riding an entity whatever it is.
* The random value you give correspond to the xp you get per block travelled while riding.
*/
public RideExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
if (!config.contains("type"))
type = null;
else {
String str = config.getString("type").toUpperCase().replace("-", "_");
Validate.isTrue(Arrays.stream(EntityType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str),
"The type must correspond to an entity that exist in the game.");
type = EntityType.valueOf(str);
}
}
@Override
public ExperienceSourceManager<RideExperienceSource> newManager() {
return new ExperienceSourceManager<RideExperienceSource>() {
@EventHandler
public void onRide(PlayerMoveEvent e) {
if (e.getPlayer().isInsideVehicle()) {
double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX();
double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY();
double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ();
if (deltax != 0 && deltay != 0 && deltaz != 0) {
double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
if (e.getPlayer().hasMetadata("NPC"))
return;
PlayerData playerData = PlayerData.get(e.getPlayer());
Entity vehicle = e.getPlayer().getVehicle();
for (RideExperienceSource source : getSources()) {
if (source.matchesParameter(playerData, vehicle.getType()))
giveExperience(playerData, e.getFrom().distance(e.getTo()), null);
}
}
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, EntityType obj) {
if (type == null)
return true;
return type.equals(obj);
}
}

View File

@ -0,0 +1,44 @@
package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
public class TameExperienceSource extends SpecificExperienceSource {
public TameExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config);
}
@Override
public ExperienceSourceManager<TameExperienceSource> newManager() {
return new ExperienceSourceManager<TameExperienceSource>() {
@EventHandler
public void onWolfHit(EntityDamageByEntityEvent e) {
if(e.getDamager() instanceof Wolf) {
Wolf wolf= (Wolf) e.getDamager();
if(wolf.getOwner() instanceof Player &&!((Player) wolf.getOwner()).hasMetadata("NPC")) {
PlayerData playerData=PlayerData.get((OfflinePlayer) wolf.getOwner());
for(TameExperienceSource source:getSources()) {
source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity()));
}
}
}
}
};
}
@Override
public boolean matchesParameter(PlayerData player, Object obj) {
return false;
}
}

View File

@ -5,11 +5,13 @@ import net.Indyuce.mmocore.experience.EXPSource;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.jetbrains.annotations.Nullable;
public abstract class SpecificExperienceSource<T> extends ExperienceSource<T> {
private final RandomAmount amount;
double counter = 0;
/**
* Used to register experience sources with SPECIFIC experience outputs.
@ -27,8 +29,8 @@ public abstract class SpecificExperienceSource<T> extends ExperienceSource<T> {
return amount;
}
public int rollAmount() {
return amount.calculateInt();
public double rollAmount() {
return amount.calculate();
}
/**

View File

@ -11,6 +11,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory;
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.manager.SkillManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import org.apache.commons.lang.Validate;
@ -38,8 +39,6 @@ public class SkillList extends EditableInventory {
if (function.equals("skill"))
return new SkillItem(config);
if (function.equals("switch"))
return new SwitchItem(config);
if (function.equals("level"))
return new LevelItem(config);
@ -49,7 +48,7 @@ public class SkillList extends EditableInventory {
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
RegisteredSkill selected = inv.selected.getSkill();
RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill();
Placeholders holders = new Placeholders();
holders.register("skill_caps", selected.getName().toUpperCase());
@ -59,10 +58,6 @@ public class SkillList extends EditableInventory {
return holders;
}
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return !inv.binding;
}
};
if (function.equals("slot"))
@ -74,7 +69,7 @@ public class SkillList extends EditableInventory {
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
RegisteredSkill selected = inv.selected.getSkill();
RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill();
RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null;
Placeholders holders = new Placeholders();
@ -82,7 +77,7 @@ public class SkillList extends EditableInventory {
holders.register("skill", skill == null ? none : skill.getName());
holders.register("index", "" + (n + 1));
holders.register("slot", MMOCoreUtils.intToRoman(n + 1));
holders.register("selected", selected.getName());
holders.register("selected", selected==null?none:selected.getName());
return holders;
}
@ -102,16 +97,28 @@ public class SkillList extends EditableInventory {
return item;
}
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return inv.binding;
}
@Override
public boolean hasDifferentDisplay() {
return true;
}
};
if (function.equals("previous"))
return new SimplePlaceholderItem<SkillViewerInventory>(config) {
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return inv.page > 0;
}
};
if (function.equals("next")) {
return new SimplePlaceholderItem<SkillViewerInventory>(config) {
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return inv.page < inv.skills.size() / 12;
}
};
}
return new SimplePlaceholderItem(config);
}
@ -120,30 +127,6 @@ public class SkillList extends EditableInventory {
return new SkillViewerInventory(data, this);
}
public class SwitchItem extends SimplePlaceholderItem<SkillViewerInventory> {
private final SimplePlaceholderItem binding, upgrading;
public SwitchItem(ConfigurationSection config) {
super(config);
Validate.isTrue(config.contains("binding"), "Config must have 'binding'");
Validate.isTrue(config.contains("upgrading"), "Config must have 'upgrading'");
binding = new SimplePlaceholderItem(config.getConfigurationSection("binding"));
upgrading = new SimplePlaceholderItem(config.getConfigurationSection("upgrading"));
}
@Override
public ItemStack display(SkillViewerInventory inv, int n) {
return inv.binding ? upgrading.display(inv) : binding.display(inv);
}
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return true;
}
}
public class LevelItem extends InventoryItem<SkillViewerInventory> {
private final int offset;
@ -189,24 +172,21 @@ public class SkillList extends EditableInventory {
return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem();
}
@Override
public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
return new Placeholders();
}
@Override
public boolean canDisplay(SkillViewerInventory inv) {
return !inv.binding;
}
}
public class SkillItem extends InventoryItem<SkillViewerInventory> {
private final int selectedSkillSlot;
public SkillItem(ConfigurationSection config) {
super(Material.BARRIER, config);
selectedSkillSlot = config.getInt("selected-slot");
}
@Override
@ -220,12 +200,16 @@ public class SkillList extends EditableInventory {
/*
* calculate placeholders
*/
ClassSkill skill = inv.skills.get(mod(n + inv.getPlayerData().skillGuiDisplayOffset, inv.skills.size()));
int index=n+inv.skillSlots.size()*inv.page;
if(index>=inv.skills.size())
return new ItemStack(Material.AIR);
ClassSkill skill = inv.skills.get(index);
Placeholders holders = getPlaceholders(inv.getPlayerData(), skill);
List<String> lore = new ArrayList<>(getLore());
int index = lore.indexOf("{lore}");
index = lore.indexOf("{lore}");
lore.remove(index);
List<String> skillLore = skill.calculateLore(inv.getPlayerData());
for (int j = 0; j < skillLore.size(); j++)
@ -272,8 +256,9 @@ public class SkillList extends EditableInventory {
private final List<Integer> skillSlots;
private final List<Integer> slotSlots;
private boolean binding;
//The skill the player Selected
private ClassSkill selected;
private int page = 0;
public SkillViewerInventory(PlayerData playerData, EditableInventory editable) {
super(playerData, editable);
@ -281,24 +266,23 @@ public class SkillList extends EditableInventory {
skills = new ArrayList<>(playerData.getProfess().getSkills());
skillSlots = getEditable().getByFunction("skill").getSlots();
slotSlots = getEditable().getByFunction("slot").getSlots();
selected=skills.get(page*skillSlots.size());
}
@Override
public String calculateName() {
return getName();
return getName().replace("{skill}", selected.getSkill().getName());
}
@Override
public void open() {
int selectedSkillSlot = ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot;
selected = skills.get(mod(selectedSkillSlot + playerData.skillGuiDisplayOffset, skills.size()));
super.open();
}
@Override
public void whenClicked(InventoryClickEvent event, InventoryItem item) {
/*
if (skillSlots.contains(event.getRawSlot())
&& event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
@ -306,24 +290,26 @@ public class SkillList extends EditableInventory {
open();
return;
}
*/
if (item.getFunction().equals("skill")) {
int index = skillSlots.size() * page + skillSlots.indexOf(event.getRawSlot());
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
selected = skills.get(index);
open();
return;
}
if (item.getFunction().equals("previous")) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset - 1) % skills.size();
page--;
open();
return;
}
if (item.getFunction().equals("next")) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + 1) % skills.size();
open();
return;
}
if (item.getFunction().equals("switch")) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
binding = !binding;
page++;
open();
return;
}
@ -331,10 +317,9 @@ public class SkillList extends EditableInventory {
/*
* binding or unbinding skills.
*/
if (binding) {
for (int index = 0; index < slotSlots.size(); index++) {
int slot = slotSlots.get(index);
if (event.getRawSlot() == slot) {
if (item.getFunction().equals("slot")) {
int index = slotSlots.indexOf(event.getRawSlot());
// unbind if there is a current spell.
if (event.getAction() == InventoryAction.PICKUP_HALF) {
@ -370,12 +355,12 @@ public class SkillList extends EditableInventory {
open();
return;
}
}
/*
* upgrading a player skill
*/
} else if (item.getFunction().equals("upgrade")) {
if (item.getFunction().equals("upgrade")) {
if (!playerData.hasSkillUnlocked(selected)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
@ -402,6 +387,7 @@ public class SkillList extends EditableInventory {
open();
}
}
}
private int mod(int x, int n) {

View File

@ -11,7 +11,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource;
import net.Indyuce.mmocore.loot.LootBuilder;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;

View File

@ -16,7 +16,7 @@ public class RedirectVanillaExp implements Listener {
@EventHandler
public void a(PlayerExpChangeEvent event) {
int a = (int) (event.getAmount() * ratio);
double a = (event.getAmount() * ratio);
if (a > 0)
PlayerData.get(event.getPlayer()).giveExperience(a, EXPSource.VANILLA);
}

View File

@ -80,7 +80,7 @@ public class FishingListener implements Listener {
public FishingData(Player player, FishHook hook, FishingDropTable table) {
this.location = hook.getLocation();
this.caught = table.getRandomItem();
this.caught = table.getRandomItem(PlayerData.get(player));
this.playerData = PlayerData.get(this.player = player);
this.hook = hook;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import java.util.Arrays;
import java.util.List;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import io.lumine.mythic.lib.api.MMOLineConfig;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import java.util.List;
import java.util.stream.Stream;

View File

@ -1,15 +1,10 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import io.lumine.mythic.lib.api.MMOLineConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.generator.WorldInfo;
import java.util.stream.Collectors;
public class DistanceCondition extends Condition{
private final Location location;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import net.Indyuce.mmocore.api.player.PlayerData;
import io.lumine.mythic.lib.api.MMOLineConfig;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import io.lumine.mythic.lib.api.MMOLineConfig;
import org.bukkit.entity.Player;

View File

@ -1,4 +1,4 @@
package net.Indyuce.mmocore.loot.droptable.condition;
package net.Indyuce.mmocore.loot.chest.condition;
import java.util.Arrays;
import java.util.List;

View File

@ -5,8 +5,8 @@ import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
@ -73,7 +73,7 @@ public class DropTable extends PostLoadObject {
public List<ItemStack> collect(LootBuilder builder) {
for (DropItem item : drops)
if (item.rollChance() && builder.getCapacity() >= item.getWeight()) {
if (item.rollChance(builder.getEntity()) && builder.getCapacity() >= item.getWeight()) {
item.collect(builder);
builder.reduceCapacity(item.getWeight());
}

View File

@ -2,6 +2,8 @@ package net.Indyuce.mmocore.loot.droptable.dropitem;
import java.util.Random;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.LootBuilder;
import net.Indyuce.mmocore.api.util.math.formula.RandomAmount;
import io.lumine.mythic.lib.api.MMOLineConfig;
@ -34,8 +36,11 @@ public abstract class DropItem {
return amount.calculateInt();
}
public boolean rollChance() {
return random.nextDouble() < chance;
/**
* If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one.
*/
public boolean rollChance(PlayerData player) {
return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance;
}
public abstract void collect(LootBuilder builder);

View File

@ -3,7 +3,7 @@ package net.Indyuce.mmocore.loot.droptable.dropitem;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.DropTable;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.LootBuilder;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.apache.commons.lang.Validate;

View File

@ -11,7 +11,7 @@ import org.bukkit.configuration.ConfigurationSection;
import com.google.gson.JsonParseException;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
import net.Indyuce.mmocore.api.load.DefaultMMOLoader;

View File

@ -7,11 +7,10 @@ import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import net.Indyuce.mmocore.api.block.BlockType;
import net.Indyuce.mmocore.api.block.SkullBlockType;
import net.Indyuce.mmocore.api.block.VanillaBlockType;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.manager.profession.SpecificProfessionManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;

View File

@ -2,8 +2,10 @@ package net.Indyuce.mmocore.manager.profession;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
@ -90,12 +92,23 @@ public class FishingManager extends SpecificProfessionManager {
return conditions;
}
public FishingDropItem getRandomItem() {
double randomCoefficient = RANDOM.nextDouble() * maxWeight;
/**
* The Fishing Drop Item is calculated randomly bu the chance stat will make
* low weight items more likely to be caught.
*/
public FishingDropItem getRandomItem(PlayerData player) {
double chance = player.getStats().getStat(StatType.CHANCE);
for (FishingDropItem item : items)
if ((randomCoefficient -= item.getItem().getWeight()) <= 0)
//chance=0 ->the tier.chance remains the same
//chance ->+inf -> the tier.chance becomes the same for everyone, uniform law
//chance=8-> tierChance=sqrt(tierChance)
double sum = 0;
double randomCoefficient=RANDOM.nextDouble();
for (FishingDropItem item : items) {
sum += Math.pow(item.getItem().getWeight(), 1 / Math.log(1 + chance));
if(sum<randomCoefficient)
return item;
}
throw new NullPointerException("Could not find item in drop table");
}

View File

@ -58,8 +58,8 @@ public class BoosterManager {
return d;
}
public int calculateExp(Profession profession, double exp) {
return (int) (exp * getMultiplier(profession));
public double calculateExp(Profession profession, double exp) {
return (exp * getMultiplier(profession));
}
/**

View File

@ -3,4 +3,5 @@ package net.Indyuce.mmocore.quest;
public interface AbstractQuest {
public String getName();
public String getId();
}

View File

@ -0,0 +1,40 @@
package net.Indyuce.mmocore.quest;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.Quest;
import net.Indyuce.mmocore.quest.compat.QuestModule;
import org.bukkit.entity.Player;
public class MMOCoreQuestModule implements QuestModule {
@Override
public AbstractQuest getQuestOrThrow(String id) {
Quest quest=MMOCore.plugin.questManager.get(id);
if(quest==null)
return null;
return new MMOCoreQuest(quest);
}
@Override
public boolean hasCompletedQuest(String quest, Player player) {
return false;
}
public class MMOCoreQuest implements AbstractQuest {
Quest quest;
public MMOCoreQuest(Quest quest) {
this.quest = quest;
}
@Override
public String getName() {
return null;
}
@Override
public String getId() {
return null;
}
}
}

View File

@ -1,16 +0,0 @@
package net.Indyuce.mmocore.quest;
import net.Indyuce.mmocore.api.player.PlayerData;
public interface QuestModule<T extends AbstractQuest, U extends PlayerQuestData<T>> {
/**
* @return Quest with given name
*/
public T getQuestOrThrow(String id);
/**
* @return Info about the completed quests from a specific player
*/
public U getQuestData(PlayerData playerData);
}

View File

@ -0,0 +1,35 @@
package net.Indyuce.mmocore.quest;
import net.Indyuce.mmocore.party.PartyModule;
import net.Indyuce.mmocore.quest.compat.BeautyQuestModule;
import net.Indyuce.mmocore.quest.compat.BlackVeinQuestsModule;
import net.Indyuce.mmocore.quest.compat.QuestCreatorModule;
import net.Indyuce.mmocore.quest.compat.QuestModule;
import org.bukkit.Bukkit;
import javax.inject.Provider;
public enum QuestModuleType {
MMOCORE("MMOCore",MMOCoreQuestModule::new),
QUESTS("Quests", BlackVeinQuestsModule::new),
BEAUTY_QUEST("Beauty Quests", BeautyQuestModule::new),
QUEST_CREATOR("Quest Creator", QuestCreatorModule::new);
private final String pluginName;
private final Provider<QuestModule> provider;
QuestModuleType(String pluginName, Provider<QuestModule> provider) {
this.pluginName = pluginName;
this.provider = provider;
}
public boolean isValid() {
return Bukkit.getPluginManager().getPlugin(pluginName) != null;
}
public QuestModule provideModule() {
return provider.get();
}
}

View File

@ -0,0 +1,47 @@
package net.Indyuce.mmocore.quest.compat;
import fr.skytasul.quests.api.QuestsAPI;
import fr.skytasul.quests.players.PlayerAccount;
import fr.skytasul.quests.players.PlayerQuestDatas;
import fr.skytasul.quests.players.PlayersManager;
import fr.skytasul.quests.structure.Quest;
import net.Indyuce.mmocore.quest.AbstractQuest;
import org.bukkit.entity.Player;
public class BeautyQuestModule implements QuestModule<BeautyQuestModule.BeautyQuestQuest> {
@Override
public BeautyQuestQuest getQuestOrThrow(String questId) {
Quest quest=QuestsAPI.getQuests().getQuest(Integer.parseInt(questId));
return quest==null?null:new BeautyQuestQuest(quest);
}
@Override
public boolean hasCompletedQuest(String questId, Player player) {
PlayerAccount account=PlayersManager.getPlayerAccount(player);
PlayerQuestDatas quest=account.getQuestDatas(QuestsAPI.getQuests().getQuest(Integer.parseInt(questId)));
return quest.isFinished();
}
public class BeautyQuestQuest implements AbstractQuest {
Quest quest;
public BeautyQuestQuest(Quest quest) {
this.quest = quest;
}
@Override
public String getName() {
return quest.getName();
}
@Override
public String getId() {
return ""+quest.getID();
}
}
}

View File

@ -0,0 +1,53 @@
package net.Indyuce.mmocore.quest.compat;
import me.blackvein.quests.Quest;
import me.blackvein.quests.Quester;
import me.blackvein.quests.Quests;
import net.Indyuce.mmocore.quest.AbstractQuest;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class BlackVeinQuestsModule implements QuestModule<BlackVeinQuestsModule.BlackVeinQuestQuest> {
private final Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests");
@Override
public BlackVeinQuestQuest getQuestOrThrow(String id) {
Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests");
return plugin.getQuestById(id)==null?null:new BlackVeinQuestQuest(plugin.getQuestById(id));
}
@Override
public boolean hasCompletedQuest(String questId, Player player) {
Quester quester = plugin.getQuester(player.getUniqueId());
for(Quest quest:quester.getCompletedQuests()) {
if(quest.getId().equals(questId))
return true;
}
return false;
}
public class BlackVeinQuestQuest implements AbstractQuest {
private final Quest quest;
public BlackVeinQuestQuest(Quest quest) {
this.quest = quest;
}
@Override
public String getName() {
return quest.getName();
}
@Override
public String getId() {
return quest.getId();
}
}
}

View File

@ -0,0 +1,56 @@
package net.Indyuce.mmocore.quest.compat;
import com.guillaumevdn.questcreator.ConfigQC;
import com.guillaumevdn.questcreator.data.user.QuestHistoryElement;
import com.guillaumevdn.questcreator.data.user.UserQC;
import com.guillaumevdn.questcreator.lib.model.ElementModel;
import com.guillaumevdn.questcreator.lib.quest.QuestEndType;
import net.Indyuce.mmocore.quest.AbstractQuest;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.List;
public class QuestCreatorModule implements QuestModule<QuestCreatorModule.QuestCreatorQuest>{
@Override
public QuestCreatorQuest getQuestOrThrow(String id) {
return new QuestCreatorQuest(id);
}
@Override
public boolean hasCompletedQuest(String questId, Player player) {
UserQC playerData=UserQC.cachedOrNull(player);
Validate.notNull(playerData,"QuestCreator User hasn't been loaded!");
//Gets all the quests the player has succeeded at
List<QuestHistoryElement> elements=playerData.getQuestHistory().getElements(questId, Arrays.asList(QuestEndType.SUCCESS),0);
for(QuestHistoryElement el:elements) {
if(el.getModelId().equals(questId))
return true;
}
return false;
}
/**
*QC ElementModel corresponds to our quest and their quests correspond to our Quest progress class
*/
public class QuestCreatorQuest implements AbstractQuest {
ElementModel questModel;
public QuestCreatorQuest(String modelId) {
questModel=ConfigQC.models.getElement(modelId).orNull();
}
@Override
public String getName() {
return questModel.getDisplayName().getId();
}
@Override
public String getId() {
return questModel.getId();
}
}
}

View File

@ -0,0 +1,18 @@
package net.Indyuce.mmocore.quest.compat;
import net.Indyuce.mmocore.quest.AbstractQuest;
import org.bukkit.entity.Player;
public interface QuestModule<T extends AbstractQuest> {
/**
* @return Quest with given name
*/
public T getQuestOrThrow(String id);
/**
* @return If a specific player did a certain quest
*/
public boolean hasCompletedQuest(String quest, Player player);
}

View File

@ -2,11 +2,10 @@ package net.Indyuce.mmocore.waypoint;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.droptable.condition.Condition;
import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance;
import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
import net.Indyuce.mmocore.player.Unlockable;
import org.apache.commons.lang.Validate;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -15,7 +14,6 @@ import org.bukkit.craftbukkit.libs.jline.internal.Nullable;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.logging.Level;
public class Waypoint implements Unlockable {
private final String id, name;

View File

@ -58,6 +58,14 @@ protect-custom-mine: false
# - parties_and_friends
party-plugin: mmocore
## Edit the plugin handling parties here.
## Supported values (just copy and paste):
## - mmocore
## - beauty_quest
## - quest_creator
## - quests
quest-plugin: mmocore
# MythicLib introduces a CHANCE stat that is used in
# several different systems in MMOCore. By changing these
# weights you can define how much the Chance stat impacts
@ -67,7 +75,6 @@ party-plugin: mmocore
# the chance stat in one particular system. The weights are
# all set to 1 by default, this option is really server specific
chance-stat-weight:
loot-chests: 1
# Whether blocks generated with a "cobblegenerator" should

View File

@ -8,7 +8,7 @@
diamond-drop-table:
items:
- 'vanilla{type=DIAMOND} 1 1-3'
# - 'mmoitem{type=material;id=RARE_DIAMOND} .1 1-3'
# - 'mmoitem{type=material;id=RARE_DIAMOND;period=} .1 1-3'
- 'droptable{id=other-drop-table} .1'
other-drop-table:

View File

@ -1,18 +1,13 @@
# GUI display name
name: Your Skills
name: 'Selected Skill: &6{skill}'
# Number of slots in your inventory. Must be
# between 9 and 54 and must be a multiple of 9.
slots: 45
slots: 54
items:
skill:
slots: [11,12,13,14,15]
# Index from 'slots' of the skill
# currently selected in the GUI
selected-slot: 2
slots: [ 10,11,12,19,20,21,28,29,30,37,38,39]
function: skill
name: '&a{skill} &6[{level}]'
@ -24,33 +19,36 @@ items:
- ''
- '{lore}'
next:
slots: [16]
slots: [ 47 ]
function: next
item: PLAYER_HEAD
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
name: '&aNext'
lore: {}
lore: { }
previous:
slots: [10]
slots: [ 2 ]
function: previous
item: PLAYER_HEAD
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ==
name: '&aPrevious'
lore: {}
switch:
slots: [28]
function: switch
item: PLAYER_HEAD
binding:
item: PINK_STAINED_GLASS
name: '&aSwitch to Binding'
lore: {}
upgrading:
item: PINK_STAINED_GLASS
name: '&aSwitch to Upgrading'
lore: {}
lore: { }
#switch:
#
# slots: [28]
# function: switch
# item: PLAYER_HEAD
# binding:
# item: PINK_STAINED_GLASS
# name: '&aSwitch to Binding'
# lore: {}
# upgrading:
# item: PINK_STAINED_GLASS
# name: '&aSwitch to Upgrading'
# lore: {}
skill-slot:
slots: [29,30,31,32,33,34]
slots: [ 8,17,26,35,44,53 ]
function: slot
item: BOOK
@ -68,7 +66,7 @@ items:
- '&e► Left click to bind {selected}.'
- '&e► Right click to unbind.'
skill-level:
slots: [29,30,31,32,33,34]
slots: [ 6,15,24,33,42,51 ]
function: level
# Skill level offset, should be changed
@ -87,7 +85,7 @@ items:
- ''
- '{lore}'
upgrade:
slots: [31]
slots: [ 15 ]
function: upgrade
item: GREEN_STAINED_GLASS_PANE
name: '&a&lUPGRADE {skill_caps}'

View File

@ -68,7 +68,7 @@ items:
lore:
- '&7You can teleport to this waypoint.'
- '&7Intermediary waypoints : {intermediary_waypoints}'
- '&7Intermediary waypoints: {intermediary_waypoints}'
- '&7Click to teleport for &b{current_cost} &7Stellium.'
next: