1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-21 12:15:50 +00:00
Slimefun4/src/main/java/me/mrCookieSlime/Slimefun/Objects/Research.java

273 lines
8.8 KiB
Java
Raw Normal View History

2016-04-14 16:24:03 +00:00
package me.mrCookieSlime.Slimefun.Objects;
import java.util.Iterator;
import java.util.LinkedList;
2016-04-14 16:24:03 +00:00
import java.util.List;
2019-08-31 15:52:20 +00:00
import java.util.logging.Level;
2016-04-14 16:24:03 +00:00
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
2019-12-12 01:52:24 +00:00
import io.github.thebusybiscuit.slimefun4.api.events.ResearchUnlockEvent;
2020-03-01 13:49:00 +00:00
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideSettings;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
2020-02-02 17:27:32 +00:00
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
2020-01-09 23:13:01 +00:00
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
2019-08-31 09:36:45 +00:00
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
2016-04-14 16:24:03 +00:00
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.PlayerProfile;
2017-06-23 11:06:08 +00:00
import me.mrCookieSlime.Slimefun.api.Slimefun;
2016-04-14 16:24:03 +00:00
2017-06-23 11:06:08 +00:00
/**
2017-06-23 16:01:44 +00:00
* Statically handles researches. Represents a research, which is bound to one
* {@link SlimefunItem} or more and require XP levels to unlock this/these item(s).
2020-02-11 21:22:33 +00:00
*
2017-06-23 16:01:44 +00:00
* See {@link ResearchSetup} for the built-in researches.
2017-06-23 11:06:08 +00:00
*
* @author TheBusyBiscuit
*/
public class Research implements Keyed {
2019-03-27 19:38:30 +00:00
private static final int[] RESEARCH_PROGRESS = {23, 44, 57, 92};
private final NamespacedKey key;
2019-12-26 17:36:21 +00:00
private final int id;
2017-06-23 11:06:08 +00:00
private String name;
private int cost;
private final List<SlimefunItem> items = new LinkedList<>();
private boolean enabled = true;
2017-06-23 11:06:08 +00:00
/**
* The constructor for a {@link Research}.
2020-02-11 21:22:33 +00:00
*
2020-02-27 16:11:32 +00:00
* Create a new research, then bind this research to the Slimefun items you want by calling
2017-06-23 11:06:08 +00:00
* {@link #addItems(SlimefunItem...)}. Once you're finished, call {@link #register()}
* to register it.
2020-02-11 21:22:33 +00:00
*
2017-06-23 11:06:08 +00:00
* To speed up, directly setup the research by calling
* {@link Slimefun#registerResearch(Research, org.bukkit.inventory.ItemStack...)}.
*
* @param key A unique identifier for this {@link Research}
* @param id old way of identifying researches
* @param name The displayed name of this {@link Research}
* @param defaultCost The Cost in XP levels to unlock this {@link Research}
2017-06-23 11:06:08 +00:00
*
*/
public Research(NamespacedKey key, int id, String name, int defaultCost) {
this.key = key;
this.id = id;
this.name = name;
this.cost = defaultCost;
}
@Override
public NamespacedKey getKey() {
return key;
}
public boolean isEnabled() {
2019-08-31 09:36:45 +00:00
return SlimefunPlugin.getSettings().researchesEnabled && enabled;
2016-04-14 16:24:03 +00:00
}
2017-06-23 11:06:08 +00:00
/**
* Gets the ID of this {@link Research}.
* This is the old way of identifying Researches, use a {@link NamespacedKey} in the future.
2017-06-23 11:06:08 +00:00
*
* @return The ID of this {@link Research}
2017-06-23 11:06:08 +00:00
*/
2016-04-14 16:24:03 +00:00
public int getID() {
2017-06-23 11:06:08 +00:00
return id;
2016-04-14 16:24:03 +00:00
}
/**
* This method gives you a localized name for this {@link Research}.
* The name is automatically taken from the currently selected {@link Language} of
* the specified {@link Player}.
*
* @param p The {@link Player} to translate this name for.
* @return The localized Name of this {@link Research}.
*/
public String getName(Player p) {
String localized = SlimefunPlugin.getLocal().getResearchName(p, key);
return localized != null ? localized: name;
}
2017-06-23 11:06:08 +00:00
/**
* Gets the cost in XP levels to unlock this {@link Research}.
*
* @return The cost in XP levels for this {@link Research}
2017-06-23 11:06:08 +00:00
*/
public int getCost() {
return cost;
2016-04-14 16:24:03 +00:00
}
2017-06-23 11:06:08 +00:00
/**
* Sets the cost in XP levels to unlock this {@link Research}.
*
* @param cost The cost in XP levels
2017-06-23 11:06:08 +00:00
*/
public void setCost(int cost) {
this.cost = cost;
2017-06-23 11:06:08 +00:00
}
2017-06-23 11:06:08 +00:00
/**
* Bind the specified Slimefun items to this {@link Research}.
2017-06-23 11:06:08 +00:00
*
* @param items Instances of {@link SlimefunItem} to bind to this {@link Research}
2017-06-23 11:06:08 +00:00
*/
2016-04-14 16:24:03 +00:00
public void addItems(SlimefunItem... items) {
for (SlimefunItem item : items) {
if (item != null) {
item.bindToResearch(this);
}
2016-04-14 16:24:03 +00:00
}
}
2017-06-23 11:06:08 +00:00
/**
* Lists every {@link SlimefunItem} that is bound to this {@link Research}.
2017-06-23 11:06:08 +00:00
*
* @return The Slimefun items bound to this {@link Research}.
2017-06-23 11:06:08 +00:00
*/
public List<SlimefunItem> getAffectedItems() {
2017-06-23 11:06:08 +00:00
return items;
2016-04-14 16:24:03 +00:00
}
2017-06-23 11:06:08 +00:00
/**
* Checks if the {@link Player} can unlock this {@link Research}.
2017-06-23 11:06:08 +00:00
*
* @param p The {@link Player} to check
* @return Whether that {@link Player} can unlock this {@link Research}
2017-06-23 11:06:08 +00:00
*/
public boolean canUnlock(Player p) {
if (!isEnabled()) return true;
2019-08-31 09:36:45 +00:00
return (p.getGameMode() == GameMode.CREATIVE && SlimefunPlugin.getSettings().researchesFreeInCreative) || p.getLevel() >= this.cost;
2017-06-23 11:06:08 +00:00
}
2017-06-23 11:06:08 +00:00
/**
2020-03-01 14:06:35 +00:00
* Unlocks this {@link Research} for the specified {@link Player}.
2017-06-23 11:06:08 +00:00
*
2020-03-01 14:06:35 +00:00
* @param p The {@link Player} for which to unlock this {@link Research}
* @param instant Whether to unlock the research instantly
2017-06-23 11:06:08 +00:00
*/
2016-04-14 16:24:03 +00:00
public void unlock(final Player p, boolean instant) {
if (!instant) {
Slimefun.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.progress", true, msg -> msg.replace("%research%", getName(p)).replace("%progress%", "0%"));
}, 10L);
}
PlayerProfile.get(p, profile -> {
if (!profile.hasUnlocked(this)) {
Runnable runnable = () -> {
profile.setResearched(this, true);
SlimefunPlugin.getLocal().sendMessage(p, "messages.unlocked", true, msg -> msg.replace("%research%", getName(p)));
2020-03-01 13:49:00 +00:00
if (SlimefunPlugin.getSettings().researchFireworksEnabled && (!PersistentDataAPI.hasByte(p, SlimefunGuideSettings.FIREWORKS_KEY) || PersistentDataAPI.getByte(p, SlimefunGuideSettings.FIREWORKS_KEY) == (byte) 1)) {
2019-12-29 21:13:00 +00:00
FireworkUtils.launchRandom(p, 1);
2019-03-27 19:38:30 +00:00
}
};
2019-11-28 18:35:28 +00:00
Slimefun.runSync(() -> {
ResearchUnlockEvent event = new ResearchUnlockEvent(p, this);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
if (instant) {
runnable.run();
}
else if (SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().add(p.getUniqueId())) {
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.start", true, msg -> msg.replace("%research%", getName(p)));
2019-11-28 18:35:28 +00:00
for (int i = 1; i < RESEARCH_PROGRESS.length + 1; i++) {
2019-11-28 18:35:28 +00:00
int j = i;
Slimefun.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.progress", true, msg -> msg.replace("%research%", getName(p)).replace("%progress%", RESEARCH_PROGRESS[j - 1] + "%"));
2019-11-28 18:35:28 +00:00
}, i * 20L);
}
Slimefun.runSync(() -> {
2019-11-28 18:35:28 +00:00
runnable.run();
SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().remove(p.getUniqueId());
}, (RESEARCH_PROGRESS.length + 1) * 20L);
}
}
2019-11-28 18:35:28 +00:00
});
2016-04-14 16:24:03 +00:00
}
});
2016-04-14 16:24:03 +00:00
}
2017-06-23 11:06:08 +00:00
/**
2020-03-01 14:06:35 +00:00
* Registers this {@link Research}.
2017-06-23 11:06:08 +00:00
*/
2016-04-14 16:24:03 +00:00
public void register() {
2019-08-31 09:36:45 +00:00
SlimefunPlugin.getResearchCfg().setDefaultValue("enable-researching", true);
2020-02-22 17:54:23 +00:00
2020-02-27 16:11:32 +00:00
String path = key.getNamespace() + '.' + key.getKey();
2020-02-22 17:54:23 +00:00
migrate(id, path);
2020-02-22 17:54:23 +00:00
if (SlimefunPlugin.getResearchCfg().contains(path + ".enabled") && !SlimefunPlugin.getResearchCfg().getBoolean(path + ".enabled")) {
2016-04-14 16:24:03 +00:00
Iterator<SlimefunItem> iterator = items.iterator();
while (iterator.hasNext()) {
SlimefunItem item = iterator.next();
if (item != null) item.bindToResearch(null);
iterator.remove();
}
return;
}
2020-02-22 17:54:23 +00:00
SlimefunPlugin.getResearchCfg().setDefaultValue(path + ".cost", this.getCost());
SlimefunPlugin.getResearchCfg().setDefaultValue(path + ".enabled", true);
2020-02-22 17:54:23 +00:00
this.cost = SlimefunPlugin.getResearchCfg().getInt(path + ".cost");
this.enabled = SlimefunPlugin.getResearchCfg().getBoolean(path + ".enabled");
SlimefunPlugin.getRegistry().getResearches().add(this);
SlimefunPlugin.getRegistry().getResearchIds().add(this);
2019-08-31 15:52:20 +00:00
if (SlimefunPlugin.getSettings().printOutLoading) {
Slimefun.getLogger().log(Level.INFO, "Loaded Research \"{0}\"", name);
2019-08-31 15:52:20 +00:00
}
2016-04-14 16:24:03 +00:00
}
2020-03-01 14:06:35 +00:00
// Temporary migration method from ids to Namespaced Keys.
2020-02-22 17:54:23 +00:00
private void migrate(int id, String path) {
if (SlimefunPlugin.getResearchCfg().contains(id + ".enabled")) {
SlimefunPlugin.getResearchCfg().setValue(path + ".enabled", SlimefunPlugin.getResearchCfg().getBoolean(id + ".enabled"));
}
if (SlimefunPlugin.getResearchCfg().contains(id + ".cost")) {
SlimefunPlugin.getResearchCfg().setValue(path + ".cost", SlimefunPlugin.getResearchCfg().getInt(id + ".cost"));
}
SlimefunPlugin.getResearchCfg().setValue(String.valueOf(id), null);
}
2017-06-23 11:06:08 +00:00
/**
2020-03-01 14:06:35 +00:00
* Attempts to get a {@link Research} with the given ID.
2017-06-23 11:06:08 +00:00
*
* We will use {@link NamespacedKey} for this in the future.
*
* @param id ID of the research to get
* @return {@link Research} if found, or null
2017-06-23 11:06:08 +00:00
*/
2016-04-14 16:24:03 +00:00
public static Research getByID(int id) {
2020-02-11 21:22:33 +00:00
for (Research research : SlimefunPlugin.getRegistry().getResearches()) {
2016-04-14 16:24:03 +00:00
if (research.getID() == id) return research;
}
return null;
}
2019-09-04 07:54:24 +00:00
@Override
public String toString() {
2019-09-05 22:09:25 +00:00
return "Research {" + id + ',' + name + "}";
2019-09-04 07:54:24 +00:00
}
}