forked from Upstream/mmocore
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:
commit
e9aa71b616
38
pom.xml
38
pom.xml
@ -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>
|
||||
|
@ -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")));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -40,130 +33,154 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
|
||||
public class DefaultMMOLoader extends MMOLoader {
|
||||
|
||||
@Override
|
||||
public Trigger loadTrigger(MMOLineConfig config) {
|
||||
if (config.getKey().equals("message"))
|
||||
return new MessageTrigger(config);
|
||||
@Override
|
||||
public Trigger loadTrigger(MMOLineConfig config) {
|
||||
if (config.getKey().equals("message"))
|
||||
return new MessageTrigger(config);
|
||||
|
||||
if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
|
||||
return new SoundTrigger(config);
|
||||
if (config.getKey().equals("sound") || config.getKey().equals("playsound"))
|
||||
return new SoundTrigger(config);
|
||||
|
||||
if (config.getKey().equals("mana"))
|
||||
return new ManaTrigger(config);
|
||||
if (config.getKey().equals("mana"))
|
||||
return new ManaTrigger(config);
|
||||
|
||||
if (config.getKey().equals("stamina"))
|
||||
return new StaminaTrigger(config);
|
||||
|
||||
if (config.getKey().equals("stellium"))
|
||||
return new StelliumTrigger(config);
|
||||
if (config.getKey().equals("stamina"))
|
||||
return new StaminaTrigger(config);
|
||||
|
||||
if (config.getKey().equals("command"))
|
||||
return new CommandTrigger(config);
|
||||
if (config.getKey().equals("stellium"))
|
||||
return new StelliumTrigger(config);
|
||||
|
||||
if (config.getKey().equals("item") || config.getKey().equals("vanilla"))
|
||||
return new ItemTrigger(config);
|
||||
if (config.getKey().equals("command"))
|
||||
return new CommandTrigger(config);
|
||||
|
||||
if (config.getKey().equals("exp") || config.getKey().equals("experience"))
|
||||
return new ExperienceTrigger(config);
|
||||
if (config.getKey().equals("item") || config.getKey().equals("vanilla"))
|
||||
return new ItemTrigger(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("exp") || config.getKey().equals("experience"))
|
||||
return new ExperienceTrigger(config);
|
||||
|
||||
@Override
|
||||
public DropItem loadDropItem(MMOLineConfig config) {
|
||||
if (config.getKey().equals("droptable"))
|
||||
return new DropTableDropItem(config);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (config.getKey().equals("vanilla"))
|
||||
return new VanillaDropItem(config);
|
||||
@Override
|
||||
public DropItem loadDropItem(MMOLineConfig config) {
|
||||
if (config.getKey().equals("droptable"))
|
||||
return new DropTableDropItem(config);
|
||||
|
||||
if (config.getKey().equals("note"))
|
||||
return new NoteDropItem(config);
|
||||
if (config.getKey().equals("vanilla"))
|
||||
return new VanillaDropItem(config);
|
||||
|
||||
if (config.getKey().equals("gold") || config.getKey().equals("coin"))
|
||||
return new GoldDropItem(config);
|
||||
if (config.getKey().equals("note"))
|
||||
return new NoteDropItem(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("gold") || config.getKey().equals("coin"))
|
||||
return new GoldDropItem(config);
|
||||
|
||||
@Override
|
||||
public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) {
|
||||
if (config.getKey().equals("goto"))
|
||||
return new GoToObjective(section, config);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (config.getKey().equals("mineblock"))
|
||||
return new MineBlockObjective(section, config);
|
||||
@Override
|
||||
public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) {
|
||||
if (config.getKey().equals("goto"))
|
||||
return new GoToObjective(section, config);
|
||||
|
||||
if (config.getKey().equals("killmob"))
|
||||
return new KillMobObjective(section, config);
|
||||
if (config.getKey().equals("mineblock"))
|
||||
return new MineBlockObjective(section, config);
|
||||
|
||||
if (config.getKey().equals("clickon"))
|
||||
return new ClickonObjective(section, config);
|
||||
if (config.getKey().equals("killmob"))
|
||||
return new KillMobObjective(section, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("clickon"))
|
||||
return new ClickonObjective(section, config);
|
||||
|
||||
@Override
|
||||
public Condition loadCondition(MMOLineConfig config) {
|
||||
if(config.getKey().equals("distance"))
|
||||
return new DistanceCondition(config);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (config.getKey().equals("world"))
|
||||
return new WorldCondition(config);
|
||||
@Override
|
||||
public Condition loadCondition(MMOLineConfig config) {
|
||||
if (config.getKey().equals("distance"))
|
||||
return new DistanceCondition(config);
|
||||
|
||||
if (config.getKey().equals("biome"))
|
||||
return new BiomeCondition(config);
|
||||
if (config.getKey().equals("world"))
|
||||
return new WorldCondition(config);
|
||||
|
||||
if (config.getKey().equals("level"))
|
||||
return new LevelCondition(config);
|
||||
|
||||
if (config.getKey().equals("permission"))
|
||||
return new PermissionCondition(config);
|
||||
if (config.getKey().equals("biome"))
|
||||
return new BiomeCondition(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("level"))
|
||||
return new LevelCondition(config);
|
||||
|
||||
@Override
|
||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||
if (config.getKey().equals("fishitem"))
|
||||
return new FishItemExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("permission"))
|
||||
return new PermissionCondition(config);
|
||||
|
||||
if (config.getKey().equals("killmob"))
|
||||
return new KillMobExperienceSource(dispenser, config);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (config.getKey().equals("mineblock"))
|
||||
return new MineBlockExperienceSource(dispenser, config);
|
||||
@Override
|
||||
public ExperienceSource<?> loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) {
|
||||
if (config.getKey().equals("resource"))
|
||||
return new ResourceExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("placeblock"))
|
||||
return new PlaceBlockExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("climb"))
|
||||
return new ClimbExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("brewpotion"))
|
||||
return new BrewPotionExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("damagedealt"))
|
||||
return new DamageDealtExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("smeltitem"))
|
||||
return new SmeltItemExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("damagetaken"))
|
||||
return new DamageTakenExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("enchantitem"))
|
||||
return new EnchantItemExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("move"))
|
||||
return new MoveExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("repairitem"))
|
||||
return new RepairItemExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("play"))
|
||||
return new PlayExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("craftitem"))
|
||||
return new CraftItemExperienceSource(dispenser, config);
|
||||
if (config.getKey().equals("projectile"))
|
||||
return new ProjectileExperienceSource(dispenser, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("ride"))
|
||||
return new RideExperienceSource(dispenser, config);
|
||||
|
||||
@Override
|
||||
public BlockType loadBlockType(MMOLineConfig config) {
|
||||
if (config.getKey().equals("tame"))
|
||||
return new TameExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equalsIgnoreCase("vanilla"))
|
||||
return new VanillaBlockType(config);
|
||||
|
||||
if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead"))
|
||||
return new SkullBlockType(config);
|
||||
if (config.getKey().equals("killmob"))
|
||||
return new KillMobExperienceSource(dispenser, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
if (config.getKey().equals("mineblock"))
|
||||
return new MineBlockExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("placeblock"))
|
||||
return new PlaceBlockExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("brewpotion"))
|
||||
return new BrewPotionExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("smeltitem"))
|
||||
return new SmeltItemExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("enchantitem"))
|
||||
return new EnchantItemExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("repairitem"))
|
||||
return new RepairItemExperienceSource(dispenser, config);
|
||||
|
||||
if (config.getKey().equals("craftitem"))
|
||||
return new CraftItemExperienceSource(dispenser, config);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType loadBlockType(MMOLineConfig config) {
|
||||
|
||||
if (config.getKey().equalsIgnoreCase("vanilla"))
|
||||
return new VanillaBlockType(config);
|
||||
|
||||
if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead"))
|
||||
return new SkullBlockType(config);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,51 +317,50 @@ 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) {
|
||||
if (!playerData.hasSkillBound(index)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
|
||||
playerData.unbindSkill(index);
|
||||
open();
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected == null)
|
||||
return;
|
||||
|
||||
if (selected.getSkill().getTrigger().isPassive()) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerData.hasSkillUnlocked(selected)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
|
||||
playerData.setBoundSkill(index, selected);
|
||||
open();
|
||||
// unbind if there is a current spell.
|
||||
if (event.getAction() == InventoryAction.PICKUP_HALF) {
|
||||
if (!playerData.hasSkillBound(index)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
|
||||
playerData.unbindSkill(index);
|
||||
open();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* upgrading a player skill
|
||||
*/
|
||||
} else if (item.getFunction().equals("upgrade")) {
|
||||
if (selected == null)
|
||||
return;
|
||||
|
||||
if (selected.getSkill().getTrigger().isPassive()) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerData.hasSkillUnlocked(selected)) {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player);
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
|
||||
playerData.setBoundSkill(index, selected);
|
||||
open();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upgrading a player skill
|
||||
*/
|
||||
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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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());
|
||||
}
|
||||
|
@ -2,41 +2,46 @@ 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;
|
||||
|
||||
public abstract class DropItem {
|
||||
protected static final Random random = new Random();
|
||||
protected static final Random random = new Random();
|
||||
|
||||
private final double chance, weight;
|
||||
private final RandomAmount amount;
|
||||
private final double chance, weight;
|
||||
private final RandomAmount amount;
|
||||
|
||||
public DropItem(MMOLineConfig config) {
|
||||
chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1;
|
||||
amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1);
|
||||
weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0;
|
||||
}
|
||||
public DropItem(MMOLineConfig config) {
|
||||
chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1;
|
||||
amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1);
|
||||
weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0;
|
||||
}
|
||||
|
||||
public RandomAmount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
public RandomAmount getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
public double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public int rollAmount() {
|
||||
return amount.calculateInt();
|
||||
}
|
||||
public int rollAmount() {
|
||||
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);
|
||||
public abstract void collect(LootBuilder builder);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,4 +3,5 @@ package net.Indyuce.mmocore.quest;
|
||||
public interface AbstractQuest {
|
||||
|
||||
public String getName();
|
||||
public String getId();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
35
src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java
Normal file
35
src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -1,97 +1,95 @@
|
||||
|
||||
# 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
|
||||
|
||||
function: skill
|
||||
name: '&a{skill} &6[{level}]'
|
||||
lore:
|
||||
- ''
|
||||
- '{unlocked}&a✔ Requires Level {unlock}'
|
||||
- '{locked}&c✖ Requires Level {unlock}'
|
||||
- '{max_level}&e✔ Maximum Level Hit!'
|
||||
- ''
|
||||
- '{lore}'
|
||||
next:
|
||||
slots: [16]
|
||||
function: next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext'
|
||||
lore: {}
|
||||
previous:
|
||||
slots: [10]
|
||||
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: {}
|
||||
skill-slot:
|
||||
slots: [29,30,31,32,33,34]
|
||||
function: slot
|
||||
item: BOOK
|
||||
|
||||
# Material used when the slot is empty
|
||||
empty-item: GRAY_DYE
|
||||
|
||||
name: '&aSkill Slot {slot}'
|
||||
no-skill: '&cNone'
|
||||
lore:
|
||||
- '&7Current Skill: &6{skill}'
|
||||
- ''
|
||||
- '&7&oCast this spell by pressing [F] followed'
|
||||
- '&7&oby the keybind displayed on the action bar.'
|
||||
- ''
|
||||
- '&e► Left click to bind {selected}.'
|
||||
- '&e► Right click to unbind.'
|
||||
skill-level:
|
||||
slots: [29,30,31,32,33,34]
|
||||
function: level
|
||||
|
||||
# Skill level offset, should be changed
|
||||
# according to the amount of inventory
|
||||
# slots the skill-level item occupies.
|
||||
offset: 2
|
||||
|
||||
# Item displayed if the skill level is
|
||||
# too low to display a level item in the GUI
|
||||
too-low:
|
||||
item: AIR
|
||||
|
||||
item: LIME_DYE
|
||||
name: '&a{skill} Level {roman}'
|
||||
lore:
|
||||
- ''
|
||||
- '{lore}'
|
||||
upgrade:
|
||||
slots: [31]
|
||||
function: upgrade
|
||||
item: GREEN_STAINED_GLASS_PANE
|
||||
name: '&a&lUPGRADE {skill_caps}'
|
||||
lore:
|
||||
- '&7Costs 1 skill point.'
|
||||
- ''
|
||||
- '&eCurrent Skill Points: {skill_points}'
|
||||
skill:
|
||||
slots: [ 10,11,12,19,20,21,28,29,30,37,38,39]
|
||||
|
||||
function: skill
|
||||
name: '&a{skill} &6[{level}]'
|
||||
lore:
|
||||
- ''
|
||||
- '{unlocked}&a✔ Requires Level {unlock}'
|
||||
- '{locked}&c✖ Requires Level {unlock}'
|
||||
- '{max_level}&e✔ Maximum Level Hit!'
|
||||
- ''
|
||||
- '{lore}'
|
||||
next:
|
||||
slots: [ 47 ]
|
||||
function: next
|
||||
item: PLAYER_HEAD
|
||||
texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19
|
||||
name: '&aNext'
|
||||
lore: { }
|
||||
previous:
|
||||
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: {}
|
||||
skill-slot:
|
||||
slots: [ 8,17,26,35,44,53 ]
|
||||
function: slot
|
||||
item: BOOK
|
||||
|
||||
# Material used when the slot is empty
|
||||
empty-item: GRAY_DYE
|
||||
|
||||
name: '&aSkill Slot {slot}'
|
||||
no-skill: '&cNone'
|
||||
lore:
|
||||
- '&7Current Skill: &6{skill}'
|
||||
- ''
|
||||
- '&7&oCast this spell by pressing [F] followed'
|
||||
- '&7&oby the keybind displayed on the action bar.'
|
||||
- ''
|
||||
- '&e► Left click to bind {selected}.'
|
||||
- '&e► Right click to unbind.'
|
||||
skill-level:
|
||||
slots: [ 6,15,24,33,42,51 ]
|
||||
function: level
|
||||
|
||||
# Skill level offset, should be changed
|
||||
# according to the amount of inventory
|
||||
# slots the skill-level item occupies.
|
||||
offset: 2
|
||||
|
||||
# Item displayed if the skill level is
|
||||
# too low to display a level item in the GUI
|
||||
too-low:
|
||||
item: AIR
|
||||
|
||||
item: LIME_DYE
|
||||
name: '&a{skill} Level {roman}'
|
||||
lore:
|
||||
- ''
|
||||
- '{lore}'
|
||||
upgrade:
|
||||
slots: [ 15 ]
|
||||
function: upgrade
|
||||
item: GREEN_STAINED_GLASS_PANE
|
||||
name: '&a&lUPGRADE {skill_caps}'
|
||||
lore:
|
||||
- '&7Costs 1 skill point.'
|
||||
- ''
|
||||
- '&eCurrent Skill Points: {skill_points}'
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user