forked from Upstream/mmocore
force-class-selection fixes
This commit is contained in:
parent
e939b6e868
commit
651e46697e
@ -141,7 +141,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.phoenixdevt</groupId>
|
||||
<artifactId>MMOProfiles-Dist</artifactId>
|
||||
<artifactId>Profile-API</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
|
@ -29,13 +29,13 @@ import net.Indyuce.mmocore.guild.GuildModuleType;
|
||||
import net.Indyuce.mmocore.guild.GuildRelationHandler;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule;
|
||||
import net.Indyuce.mmocore.guild.provided.YAMLGuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.*;
|
||||
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.LegacyDataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
|
||||
import net.Indyuce.mmocore.guild.provided.YAMLGuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.profession.*;
|
||||
import net.Indyuce.mmocore.manager.social.BoosterManager;
|
||||
import net.Indyuce.mmocore.manager.social.PartyManager;
|
||||
@ -258,8 +258,7 @@ public class MMOCore extends JavaPlugin {
|
||||
* that after registering all the professses otherwise the player datas can't
|
||||
* recognize what profess the player has and professes will be lost
|
||||
*/
|
||||
playerDataManager.setupAll();
|
||||
playerDataManager.registerEvents(EventPriority.NORMAL, EventPriority.NORMAL);
|
||||
playerDataManager.initialize(EventPriority.NORMAL, EventPriority.NORMAL);
|
||||
|
||||
// load guild data after loading player data
|
||||
dataProvider.getGuildManager().load();
|
||||
@ -271,25 +270,6 @@ public class MMOCore extends JavaPlugin {
|
||||
MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot();
|
||||
getCommand("mmocore").setExecutor(mmoCoreCommand);
|
||||
getCommand("mmocore").setTabCompleter(mmoCoreCommand);
|
||||
|
||||
if (getConfig().getBoolean("auto-save.enabled"))
|
||||
|
||||
{
|
||||
int autosave = getConfig().getInt("auto-save.interval") * 20;
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
|
||||
// Save player data
|
||||
for (PlayerData data : PlayerData.getAll())
|
||||
if (data.isSynchronized())
|
||||
dataProvider.getDataManager().getDataHandler().saveData(data, false);
|
||||
|
||||
// Save guild info
|
||||
for (Guild guild : dataProvider.getGuildManager().getAll())
|
||||
dataProvider.getGuildManager().save(guild);
|
||||
}
|
||||
}.runTaskTimerAsynchronously(MMOCore.plugin, autosave, autosave);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -306,8 +286,6 @@ public class MMOCore extends JavaPlugin {
|
||||
for (PlayerData data : PlayerData.getAll())
|
||||
if (data.isSynchronized()) {
|
||||
data.close();
|
||||
// Saves player health before saveData as the player will be considered offline into it if it is async.
|
||||
data.setHealth(data.getPlayer().getHealth());
|
||||
dataProvider.getDataManager().getDataHandler().saveData(data, true);
|
||||
}
|
||||
|
||||
|
@ -427,6 +427,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
// Saves player health before saveData as the player will be considered offline into it if it is async
|
||||
health = getPlayer().getHealth();
|
||||
|
||||
// Remove from party if it is MMO Party Module
|
||||
|
@ -1,17 +1,26 @@
|
||||
package net.Indyuce.mmocore.comp.profile;
|
||||
|
||||
import fr.phoenixdevt.profile.ProfileDataModule;
|
||||
import fr.phoenixdevt.profile.event.ProfileCreateEvent;
|
||||
import fr.phoenixdevt.profile.event.ProfileDeleteEvent;
|
||||
import fr.phoenixdevt.profile.placeholder.PlaceholderRequest;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.comp.profile.ProfileDataModuleImpl;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.experience.Profession;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MMOCoreProfileDataModule extends ProfileDataModuleImpl {
|
||||
public MMOCoreProfileDataModule() {
|
||||
super(MMOCore.plugin);
|
||||
public class MMOCoreProfileDataModule implements ProfileDataModule, Listener {
|
||||
|
||||
@Override
|
||||
public JavaPlugin getOwningPlugin() {
|
||||
return MMOCore.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,4 +52,22 @@ public class MMOCoreProfileDataModule extends ProfileDataModuleImpl {
|
||||
placeholderRequest.validate();
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileCreate(ProfileCreateEvent event) {
|
||||
|
||||
// Force to choose class first
|
||||
if (MMOCore.plugin.configManager.forceClassSelection) {
|
||||
final PlayerData playerData = PlayerData.get(event.getPlayerData().getUniqueId());
|
||||
InventoryManager.CLASS_SELECT.newInventory(playerData, () -> event.validate(this)).open();
|
||||
}
|
||||
|
||||
// Validate event directly
|
||||
else event.validate(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileDelete(ProfileDeleteEvent event) {
|
||||
event.validate(this);
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,11 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ClassConfirmation extends EditableInventory {
|
||||
private final PlayerClass playerClass;
|
||||
|
||||
@ -37,7 +40,11 @@ public class ClassConfirmation extends EditableInventory {
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, PluginInventory last, boolean subclass) {
|
||||
return new ClassConfirmationInventory(data, this, playerClass, last, subclass);
|
||||
return newInventory(data, last, subclass, null);
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, PluginInventory last, boolean subclass, @Nullable Runnable profileRunnable) {
|
||||
return new ClassConfirmationInventory(data, this, playerClass, last, subclass, profileRunnable);
|
||||
}
|
||||
|
||||
public class UnlockedItem extends InventoryItem<ClassConfirmationInventory> {
|
||||
@ -105,26 +112,33 @@ public class ClassConfirmation extends EditableInventory {
|
||||
private final PluginInventory last;
|
||||
private final boolean subclass;
|
||||
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last, boolean subclass) {
|
||||
@Nullable
|
||||
private final Runnable profileRunnable;
|
||||
|
||||
private boolean canClose;
|
||||
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last, boolean subclass, @Nullable Runnable profileRunnable) {
|
||||
super(playerData, editable);
|
||||
|
||||
this.profess = profess;
|
||||
this.last = last;
|
||||
this.subclass = subclass;
|
||||
this.profileRunnable = profileRunnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClicked(InventoryClickContext context, InventoryItem item) {
|
||||
if (item.getFunction().equals("back"))
|
||||
if (item.getFunction().equals("back")) {
|
||||
canClose = true;
|
||||
last.open();
|
||||
|
||||
else if (item.getFunction().equals("yes")) {
|
||||
} else if (item.getFunction().equals("yes")) {
|
||||
|
||||
PlayerChangeClassEvent called = new PlayerChangeClassEvent(playerData, profess);
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (called.isCancelled())
|
||||
return;
|
||||
|
||||
canClose = true;
|
||||
playerData.giveClassPoints(-1);
|
||||
if (subclass)
|
||||
playerData.setClass(profess);
|
||||
@ -134,9 +148,22 @@ public class ClassConfirmation extends EditableInventory {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("class-select", "class", profess.getName()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SELECT_CLASS).playTo(player);
|
||||
player.closeInventory();
|
||||
if (profileRunnable != null) profileRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
canClose = false;
|
||||
super.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClosed(InventoryCloseEvent event) {
|
||||
if (profileRunnable != null && !canClose)
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> open(), 2 * 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String calculateName() {
|
||||
return getName().replace("{class}", profess.getName());
|
||||
|
@ -16,14 +16,17 @@ import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@ -41,7 +44,11 @@ public class ClassSelect extends EditableInventory {
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data) {
|
||||
return new ProfessSelectionInventory(data, this);
|
||||
return newInventory(data, null);
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, @Nullable Runnable profileRunnable) {
|
||||
return new ProfessSelectionInventory(data, this, profileRunnable);
|
||||
}
|
||||
|
||||
public class ClassItem extends SimplePlaceholderItem<ProfessSelectionInventory> {
|
||||
@ -51,6 +58,7 @@ public class ClassSelect extends EditableInventory {
|
||||
|
||||
public ClassItem(ConfigurationSection config) {
|
||||
super(Material.BARRIER, config);
|
||||
|
||||
Validate.isTrue(config.getString("function").length() > 6, "Couldn't find the class associated to: " + config.getString("function"));
|
||||
String classId = UtilityMethods.enumName(config.getString("function").substring(6));
|
||||
this.playerClass = Objects.requireNonNull(MMOCore.plugin.classManager.get(classId), classId + " does not correspond to any classId.");
|
||||
@ -93,8 +101,16 @@ public class ClassSelect extends EditableInventory {
|
||||
}
|
||||
|
||||
public class ProfessSelectionInventory extends GeneratedInventory {
|
||||
public ProfessSelectionInventory(PlayerData playerData, EditableInventory editable) {
|
||||
|
||||
@Nullable
|
||||
private final Runnable profileRunnable;
|
||||
|
||||
private boolean canClose;
|
||||
|
||||
public ProfessSelectionInventory(PlayerData playerData, EditableInventory editable, @Nullable Runnable profileRunnable) {
|
||||
super(playerData, editable);
|
||||
|
||||
this.profileRunnable = profileRunnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -107,7 +123,7 @@ public class ClassSelect extends EditableInventory {
|
||||
if (item instanceof ClassItem) {
|
||||
PlayerClass profess = ((ClassItem) item).playerClass;
|
||||
|
||||
if (playerData.getClassPoints() < 1) {
|
||||
if (profileRunnable == null && playerData.getClassPoints() < 1) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
|
||||
new ConfigMessage("cant-choose-new-class").send(player);
|
||||
return;
|
||||
@ -125,10 +141,23 @@ public class ClassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
canClose = true;
|
||||
final PlayerClass playerClass = findDeepestSubclass(playerData, profess);
|
||||
InventoryManager.CLASS_CONFIRM.get(MMOCoreUtils.ymlName(playerClass.getId())).newInventory(playerData, this, false).open();
|
||||
InventoryManager.CLASS_CONFIRM.get(MMOCoreUtils.ymlName(playerClass.getId())).newInventory(playerData, this, false, profileRunnable).open();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
canClose = false;
|
||||
super.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClosed(InventoryCloseEvent event) {
|
||||
if (profileRunnable != null && !canClose)
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> open(), 2 * 20);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ public class SubclassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryManager.CLASS_CONFIRM.get(classId).newInventory(playerData, this, true).open();
|
||||
InventoryManager.CLASS_CONFIRM.get(classId).newInventory(playerData, this, true, null).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
public GeneratedInventory(PlayerData playerData, EditableInventory editable) {
|
||||
super(playerData);
|
||||
|
||||
this.editable = editable;
|
||||
this.adaptor = editable.getAdaptorType().supply(this);
|
||||
}
|
||||
@ -66,6 +67,8 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
if (!getPlayerData().isOnline()) return;
|
||||
|
||||
/*
|
||||
* Very important, in order to prevent ghost items, the loaded items map
|
||||
* must be cleared when the inventory is updated or open at least twice
|
||||
|
@ -28,7 +28,7 @@ public class ConfigManager {
|
||||
public final CommandVerbose commandVerbose = new CommandVerbose();
|
||||
|
||||
public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, splitMainExp, splitProfessionExp, disableQuestBossBar,
|
||||
pvpModeEnabled, pvpModeInvulnerabilityCanDamage;
|
||||
pvpModeEnabled, pvpModeInvulnerabilityCanDamage, forceClassSelection;
|
||||
public String partyChatPrefix, noSkillBoundPlaceholder;
|
||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||
@ -133,6 +133,7 @@ public class ConfigManager {
|
||||
splitMainExp = MMOCore.plugin.getConfig().getBoolean("party.main-exp-split");
|
||||
splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
|
||||
disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar");
|
||||
forceClassSelection = MMOCore.plugin.getConfig().getBoolean("force-class-selection");
|
||||
|
||||
// Combat
|
||||
pvpModeEnabled = config.getBoolean("pvp_mode.enabled");
|
||||
|
@ -41,6 +41,10 @@ public abstract class GuildDataManager {
|
||||
delete(guild);
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
for (Guild guild : guilds.values()) save(guild);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Guild getGuild(String guild) {
|
||||
return guilds.get(guild);
|
||||
|
@ -33,4 +33,9 @@ public class PlayerDataManager extends SynchronizedDataManager<PlayerData, Offli
|
||||
public void loadDefaultData(ConfigurationSection config) {
|
||||
defaultData = new DefaultPlayerData(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenAutoSaved() {
|
||||
MMOCore.plugin.nativeGuildManager.saveAll();
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,6 @@ public class MMOCoreBukkit {
|
||||
if (plugin.getConfig().getBoolean("vanilla-exp-redirection.enabled"))
|
||||
Bukkit.getPluginManager().registerEvents(new RedirectVanillaExp(plugin.getConfig().getDouble("vanilla-exp-redirection.ratio")), plugin);
|
||||
|
||||
if (plugin.getConfig().getBoolean("force-class-choose-on-first-login"))
|
||||
Bukkit.getPluginManager().registerEvents(new ForceChooseClassListener(), MMOCore.plugin);
|
||||
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new WaypointsListener(), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), plugin);
|
||||
|
@ -1,47 +0,0 @@
|
||||
package net.Indyuce.mmocore.listener.option;
|
||||
|
||||
import io.lumine.mythic.lib.api.event.SynchronizedDataLoadEvent;
|
||||
import io.lumine.mythic.lib.api.util.TemporaryListener;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
|
||||
public class ForceChooseClassListener implements Listener {
|
||||
@EventHandler
|
||||
public void onJoin(SynchronizedDataLoadEvent event) {
|
||||
if (event.getManager().getOwningPlugin().equals(MMOCore.plugin)) {
|
||||
PlayerData playerData = PlayerData.get(event.getHolder().getProfileId());
|
||||
if (playerData.isProfessNull()) {
|
||||
|
||||
// Open GUI
|
||||
InventoryManager.CLASS_SELECT.newInventory(playerData).open();
|
||||
|
||||
// Re-open GUI till the player
|
||||
new TemporaryListener(PlayerChangeClassEvent.getHandlerList(), InventoryCloseEvent.getHandlerList()) {
|
||||
|
||||
@EventHandler
|
||||
public void whenClosed(InventoryCloseEvent event) {
|
||||
if (event.getPlayer().equals(playerData.getPlayer()))
|
||||
InventoryManager.CLASS_SELECT.newInventory(playerData).open();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void whenChoose(PlayerChangeClassEvent event) {
|
||||
if (event.getPlayer().equals(playerData.getPlayer())) close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClosed() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -193,10 +193,14 @@ vanilla-exp-redirection:
|
||||
# Requires a SERVER reload when changed.
|
||||
override-vanilla-exp: true
|
||||
|
||||
# Forces the player to choose a class at first join.
|
||||
force-class-choose-on-first-login: false
|
||||
# When enabled and when using a profile plugin, MMOCore will
|
||||
# force the user to choose a class. The profile will not be
|
||||
# created until they choose a class.
|
||||
#
|
||||
# This option is useless unless you have installed a profile plugin.
|
||||
force-class-selection: true
|
||||
|
||||
# Check the target player's RPG profile when shift when shift right clicking.
|
||||
# Check the target player's RPG profile on shift-right click.
|
||||
shift-click-player-profile-check: false
|
||||
|
||||
# If main class experience holograms should be displayed
|
||||
@ -215,7 +219,7 @@ max-skill-slots: 8
|
||||
|
||||
# When set to true, passive skills must be bound in order to take effect.
|
||||
# When set to false, unlocked skills will take effect right away.
|
||||
# Temporarily disabled.
|
||||
# Disabled for now.
|
||||
# passive-skill-need-bound: true
|
||||
|
||||
# Fun extra RPG feature that switches the player's hotbar with
|
||||
|
Loading…
Reference in New Issue
Block a user