mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-27 00:45:40 +01:00
Fixed login trigger type not working on class skills & scripts
This commit is contained in:
parent
947637127e
commit
47cd5c15c9
@ -147,7 +147,6 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
public void reload() {
|
||||
try {
|
||||
profess = profess == null ? null : MMOCore.plugin.classManager.get(profess.getId());
|
||||
getStats().updateStats();
|
||||
} catch (NullPointerException exception) {
|
||||
MMOCore.log(Level.SEVERE, "[Userdata] Could not find class " + getProfess().getId() + " while refreshing player data.");
|
||||
}
|
||||
@ -172,20 +171,69 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
if (!nodeLevels.containsKey(node)) nodeLevels.put(node, 0);
|
||||
|
||||
setupSkillTree();
|
||||
setupRemovableTrigger();
|
||||
updateTemporaryTriggers();
|
||||
getStats().updateStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* This script is called when the player data has been successfully
|
||||
* loaded from the SQL/local text database.
|
||||
*/
|
||||
@Override
|
||||
public void markAsSynchronized() {
|
||||
|
||||
/*
|
||||
* If the player is not dead and the health is 0, this means that the data was
|
||||
* missing from the database and it gives full health to the player. If the
|
||||
* player is dead however, it must not account for that subtle edge case.
|
||||
*/
|
||||
if (isOnline() && !getPlayer().isDead())
|
||||
getPlayer().setHealth(MMOCoreUtils.fixResource(getHealth(), getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
|
||||
setupSkillTree();
|
||||
updateTemporaryTriggers();
|
||||
getStats().updateStats(true);
|
||||
|
||||
// Finally mark synchronized
|
||||
super.markAsSynchronized();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setupRemovableTrigger() {
|
||||
//We remove all the stats and buffs associated to triggers.
|
||||
updateTemporaryTriggers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some triggers are marked with the Removable interface as
|
||||
* they are non-permanent triggers and they need to be updated
|
||||
* everytime their MMOPlayerData gets flushed from ML cache.
|
||||
* <p>
|
||||
* This method should go through ALL {@link ExperienceTable}
|
||||
* that the player has spent points into and register all
|
||||
* non-permanent triggers.
|
||||
* <p>
|
||||
* For ease of implementation, these non-permanent triggers are
|
||||
* refreshed everytime the player joins the server ie on every
|
||||
* player data fetch.
|
||||
*
|
||||
* @see {@link net.Indyuce.mmocore.api.quest.trigger.api.Removable}
|
||||
*/
|
||||
public void updateTemporaryTriggers() {
|
||||
|
||||
// Remove all stats and buffs associated to triggers
|
||||
getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals));
|
||||
getMMOPlayerData().getSkillModifierMap().getInstances().forEach(skillModifierInstance -> skillModifierInstance.removeIf(Trigger.STAT_MODIFIER_KEY::equals));
|
||||
|
||||
// Experience tables from main class
|
||||
if (profess.hasExperienceTable())
|
||||
profess.getExperienceTable().claimRemovableTrigger(this, profess);
|
||||
|
||||
// Experience tables from professions
|
||||
for (Profession profession : MMOCore.plugin.professionManager.getAll())
|
||||
if (profession.hasExperienceTable())
|
||||
profession.getExperienceTable().claimRemovableTrigger(this, profession);
|
||||
// Stat triggers setup
|
||||
|
||||
// Experience tables from skill tree nodes
|
||||
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
|
||||
for (SkillTreeNode node : skillTree.getNodes())
|
||||
node.getExperienceTable().claimRemovableTrigger(this, node);
|
||||
@ -358,7 +406,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
/**
|
||||
* @return If the item is unlocked by the player
|
||||
* This is used for skills that can be locked & unlocked.
|
||||
* This is used for skills that can be locked & unlocked.
|
||||
*/
|
||||
public boolean hasUnlocked(Unlockable unlockable) {
|
||||
return unlockable.isUnlockedByDefault() || unlockedItems.contains(unlockable.getUnlockNamespacedKey());
|
||||
@ -506,10 +554,10 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public List<ClassSkill> getUnlockedSkills() {
|
||||
return getProfess().getSkills().stream()
|
||||
.filter((classSkill) -> hasUnlocked(classSkill))
|
||||
.filter(skill -> hasUnlocked(skill) && hasUnlockedLevel(skill))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -567,9 +615,8 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = Math.max(1, level);
|
||||
|
||||
if (isOnline()) {
|
||||
getStats().updateStats();
|
||||
if (isSynchronized()) getStats().updateStats();
|
||||
refreshVanillaExp();
|
||||
}
|
||||
}
|
||||
@ -1018,7 +1065,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
/**
|
||||
* @return If the PlayerEnterCastingModeEvent successfully put the player
|
||||
* into casting mode, otherwise if the event is cancelled, returns false.
|
||||
* into casting mode, otherwise if the event is cancelled, returns false.
|
||||
*/
|
||||
public boolean setSkillCasting() {
|
||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||
@ -1037,7 +1084,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
|
||||
/**
|
||||
* @return If player successfully left skill casting i.e the Bukkit
|
||||
* event has not been cancelled
|
||||
* event has not been cancelled
|
||||
*/
|
||||
public boolean leaveSkillCasting() {
|
||||
return leaveSkillCasting(false);
|
||||
@ -1046,7 +1093,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
/**
|
||||
* @param skipEvent Skip firing the exit event
|
||||
* @return If player successfully left skill casting i.e the Bukkit
|
||||
* event has not been cancelled
|
||||
* event has not been cancelled
|
||||
*/
|
||||
public boolean leaveSkillCasting(boolean skipEvent) {
|
||||
Validate.isTrue(isCasting(), "Player not in casting mode");
|
||||
@ -1166,10 +1213,10 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
// Clear bound skills
|
||||
boundSkills.forEach((slot, info) -> info.close());
|
||||
boundSkills.clear();
|
||||
setupRemovableTrigger();
|
||||
updateTemporaryTriggers();
|
||||
|
||||
// Update stats
|
||||
if (isOnline()) getStats().updateStats();
|
||||
if (isOnline() && isSynchronized()) getStats().updateStats();
|
||||
}
|
||||
|
||||
public boolean hasSkillBound(int slot) {
|
||||
@ -1225,7 +1272,7 @@ public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerD
|
||||
* checks if they could potentially upgrade to one of these
|
||||
*
|
||||
* @return If the player can change its current class to
|
||||
* a subclass
|
||||
* a subclass
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canChooseSubclass() {
|
||||
|
@ -352,12 +352,12 @@ public class SavedClassInformation implements ClassDataContainer {
|
||||
|
||||
// This needs to be done at the end to make sure the MAX_HEALTH/MAX_MANA/... stats are loaded.
|
||||
player.getPlayer().setHealth(MMOCoreUtils.fixResource(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
player.setHealth(health);
|
||||
player.setMana(mana);
|
||||
player.setStellium(stellium);
|
||||
player.setStamina(stamina);
|
||||
player.setupRemovableTrigger();
|
||||
// Updates level on exp bar
|
||||
player.refreshVanillaExp();
|
||||
player.updateTemporaryTriggers();
|
||||
player.getStats().updateStats();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,12 @@ import io.lumine.mythic.lib.player.modifier.ModifierSource;
|
||||
import io.lumine.mythic.lib.player.modifier.ModifierType;
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkill;
|
||||
import io.lumine.mythic.lib.player.skill.PassiveSkillMap;
|
||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.Profession;
|
||||
import net.Indyuce.mmocore.player.stats.StatInfo;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
|
||||
public class PlayerStats {
|
||||
private final PlayerData data;
|
||||
@ -65,14 +67,22 @@ public class PlayerStats {
|
||||
return data.getProfess().calculateStat(stat, profession == null ? data.getLevel() : data.getCollectionSkills().getLevel(profession));
|
||||
}
|
||||
|
||||
public void updateStats() {
|
||||
updateStats(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to update MMOCore stat modifiers due to class and send them over to
|
||||
* MythicLib. Must be ran everytime the player levels up or changes class.
|
||||
* MythicLib. Must be ran everytime the player levels up, changes class or
|
||||
* when the plugin reloads.
|
||||
* <p>
|
||||
* This is also called when reloading the plugin to make class setup easier,
|
||||
* see {@link PlayerData#reload()} for more info
|
||||
* Login scripts are a pretty special case of scripts/skills since they are
|
||||
* not loaded yet when MythicLib triggers them naturally. Therefore, they
|
||||
* need to be cast as soon as they are loaded into the MMOCore player data.
|
||||
*
|
||||
* @param castLoginScripts Should login scripts be cast
|
||||
*/
|
||||
public synchronized void updateStats() {
|
||||
public synchronized void updateStats(boolean castLoginScripts) {
|
||||
|
||||
// Update player stats
|
||||
for (String stat : MMOCore.plugin.statManager.getRegistered()) {
|
||||
@ -91,19 +101,33 @@ public class PlayerStats {
|
||||
packet.runUpdate();
|
||||
}
|
||||
|
||||
// Updates the player's unbindable passive skills.
|
||||
// Updates the player's unbindable CLASS passive skills
|
||||
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
|
||||
skillMap.removeModifiers("MMOCorePassiveSkillNotBound");
|
||||
data.getProfess().getSkills().stream()
|
||||
.filter((classSkill) -> !classSkill.needsBound() && classSkill.getSkill().getTrigger().isPassive() && data.hasUnlocked(classSkill) && data.hasUnlockedLevel(classSkill))
|
||||
.forEach(classSkill -> skillMap.addModifier(classSkill.toPassive(data)));
|
||||
for (ClassSkill skill : data.getProfess().getSkills())
|
||||
if (!skill.needsBound()
|
||||
&& skill.getSkill().getTrigger().isPassive()
|
||||
&& skill.getSkill().getTrigger() != TriggerType.LOGIN
|
||||
&& data.hasUnlocked(skill)
|
||||
&& data.hasUnlockedLevel(skill))
|
||||
skillMap.addModifier(skill.toPassive(data));
|
||||
|
||||
/*
|
||||
* Updates the player's class scripts, which act just
|
||||
* like non-bindable passive skills.
|
||||
*/
|
||||
// Updates the player's CLASS scripts
|
||||
skillMap.removeModifiers("MMOCoreClassScript");
|
||||
for (PassiveSkill script : data.getProfess().getScripts())
|
||||
skillMap.addModifier(script);
|
||||
if (script.getType() != TriggerType.LOGIN) skillMap.addModifier(script);
|
||||
|
||||
// If data hasn't been synchronized yet, cast LOGIN scripts
|
||||
if (castLoginScripts) {
|
||||
|
||||
// Call class login skills
|
||||
for (ClassSkill skill : data.getProfess().getSkills())
|
||||
if (skill.getSkill().getTrigger() == TriggerType.LOGIN)
|
||||
skill.toCastable(data).cast(data.getMMOPlayerData());
|
||||
|
||||
// Call class login scripts
|
||||
for (PassiveSkill skill : data.getProfess().getScripts())
|
||||
if (skill.getType() == TriggerType.LOGIN) skill.getTriggeredSkill().cast(data.getMMOPlayerData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package net.Indyuce.mmocore.api.quest.trigger.api;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
// TODO rename to non-permanent
|
||||
// TODO merge with MythicLib
|
||||
public interface Removable {
|
||||
public void remove(PlayerData playerData);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ public class SkillList extends EditableInventory {
|
||||
super(playerData, editable);
|
||||
skills = playerData.getProfess().getSkills()
|
||||
.stream()
|
||||
.filter((classSkill) -> playerData.hasUnlocked(classSkill))
|
||||
.filter(skill -> playerData.hasUnlocked(skill))
|
||||
.sorted(Comparator.comparingInt(ClassSkill::getUnlockLevel))
|
||||
.collect(Collectors.toList());
|
||||
skillSlots = getEditable().getByFunction("skill").getSlots();
|
||||
|
@ -16,7 +16,6 @@ import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@ -68,7 +67,6 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
getData().setNodeLevel(skillTreeNode, json.has(skillTreeNode.getFullId()) ? json.get(skillTreeNode.getFullId()).getAsInt() : 0);
|
||||
}
|
||||
}
|
||||
getData().setupSkillTree();
|
||||
Set<String> unlockedItems = new HashSet<>();
|
||||
if (!isEmpty(result.getString("unlocked_items"))) {
|
||||
JsonArray unlockedItemsArray = MythicLib.plugin.getGson().fromJson(result.getString("unlocked_items"), JsonArray.class);
|
||||
@ -101,7 +99,6 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
ClassSkill skill = getData().getProfess().getSkill(entry.getValue().getAsString());
|
||||
if (skill != null) getData().bindSkill(Integer.parseInt(entry.getKey()), skill);
|
||||
|
||||
}
|
||||
}
|
||||
if (!isEmpty(result.getString("class_info"))) {
|
||||
@ -121,20 +118,10 @@ public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
* These should be loaded after to make sure that the
|
||||
* MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
|
||||
*/
|
||||
getData().setHealth(result.getDouble("health"));
|
||||
getData().setMana(result.getDouble("mana"));
|
||||
getData().setStamina(result.getDouble("stamina"));
|
||||
getData().setStellium(result.getDouble("stellium"));
|
||||
getData().setupRemovableTrigger();
|
||||
if (getData().isOnline() && !getData().getPlayer().isDead()) {
|
||||
|
||||
/*
|
||||
* If the player is not dead and the health is 0, this means that the data was
|
||||
* missing from the data base and it gives full health to the player. If the
|
||||
* player is dead however, it must not account for that subtle edge case.
|
||||
*/
|
||||
final double health = MMOCoreUtils.fixResource(result.getDouble("health"), getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
getData().getPlayer().setHealth(health);
|
||||
}
|
||||
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", String.format("{ class: %s, level: %d }", getData().getProfess().getId(), getData().getLevel()));
|
||||
}
|
||||
|
@ -110,20 +110,15 @@ public class YAMLPlayerDataHandler extends YAMLSynchronizedDataHandler<PlayerDat
|
||||
for (SkillTreeNode node : MMOCore.plugin.skillTreeManager.getAllNodes()) {
|
||||
data.setNodeLevel(node, config.getInt("skill-tree-level." + node.getFullId(), 0));
|
||||
}
|
||||
data.setupSkillTree();
|
||||
|
||||
// Load class slots, use try so the player can log in.
|
||||
if (config.contains("class-info"))
|
||||
for (
|
||||
String key : config.getConfigurationSection("class-info").
|
||||
|
||||
getKeys(false))
|
||||
for (String key : config.getConfigurationSection("class-info").getKeys(false))
|
||||
try {
|
||||
PlayerClass profess = MMOCore.plugin.classManager.get(key);
|
||||
Validate.notNull(profess, "Could not find class '" + key + "'");
|
||||
data.applyClassInfo(profess, new SavedClassInformation(config.getConfigurationSection("class-info." + key)));
|
||||
} catch (
|
||||
IllegalArgumentException exception) {
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load class info '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
@ -135,9 +130,6 @@ public class YAMLPlayerDataHandler extends YAMLSynchronizedDataHandler<PlayerDat
|
||||
data.setMana(config.contains("mana") ? config.getDouble("mana") : data.getStats().getStat("MAX_MANA"));
|
||||
data.setStamina(config.contains("stamina") ? config.getDouble("stamina") : data.getStats().getStat("MAX_STAMINA"));
|
||||
data.setStellium(config.contains("stellium") ? config.getDouble("stellium") : data.getStats().getStat("MAX_STELLIUM"));
|
||||
data.setupRemovableTrigger();
|
||||
if (data.isOnline() && !data.getPlayer().isDead())
|
||||
data.getPlayer().setHealth(MMOCoreUtils.fixResource(config.getDouble("health"), data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +33,7 @@ public class BoundSkillInfo implements Closeable {
|
||||
if (skillModifierTrigger.getTargetSkills().contains(classSkill.getSkill().getHandler()))
|
||||
skillModifierTrigger.apply(playerData, classSkill.getSkill().getHandler());
|
||||
|
||||
if (classSkill.getSkill().getTrigger().isPassive()&& classSkill.needsBound()) {
|
||||
if (classSkill.getSkill().getTrigger().isPassive() && classSkill.needsBound()) {
|
||||
registered = classSkill.toPassive(playerData);
|
||||
registered.register(playerData.getMMOPlayerData());
|
||||
} else registered = null;
|
||||
|
Loading…
Reference in New Issue
Block a user