mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-23 00:05:52 +01:00
Fixed extra attributes not working on MI
This commit is contained in:
parent
a64a2d0ab8
commit
4cb58398b0
@ -0,0 +1,44 @@
|
||||
package net.Indyuce.mmocore.api.player.attribute;
|
||||
|
||||
import io.lumine.mythic.lib.api.stat.StatMap;
|
||||
import io.lumine.mythic.lib.api.stat.handler.StatHandler;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
|
||||
/**
|
||||
* This fixes an issue where registering new stat modifiers in ML
|
||||
* to add extra attribute points does NOT update the stats granted
|
||||
* by the attribute.
|
||||
* <p>
|
||||
* This stat handler MAY call subsequent stat handlers. There might
|
||||
* be infinite recursion problems if another attr. grants extra attribute pts.
|
||||
*/
|
||||
public class MMOCoreAttributeStatHandler implements StatHandler {
|
||||
private final PlayerAttribute attr;
|
||||
private final String statName;
|
||||
|
||||
public MMOCoreAttributeStatHandler(PlayerAttribute attr) {
|
||||
this.attr = attr;
|
||||
this.statName = "ADDITIONAL_" + attr.getId().toUpperCase().replace("-", "_");
|
||||
}
|
||||
|
||||
public String getStat() {
|
||||
return statName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdate(StatMap statMap) {
|
||||
final PlayerData playerData = MMOCore.plugin.dataProvider.getDataManager().get(statMap.getPlayerData().getUniqueId());
|
||||
playerData.getAttributes().getInstance(attr).updateStats();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBaseValue(StatMap statMap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTotalValue(StatMap statMap) {
|
||||
return statMap.getStat(statName);
|
||||
}
|
||||
}
|
@ -22,202 +22,206 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class PlayerAttributes {
|
||||
private final PlayerData data;
|
||||
private final Map<String, AttributeInstance> instances = new HashMap<>();
|
||||
private final PlayerData data;
|
||||
private final Map<String, AttributeInstance> instances = new HashMap<>();
|
||||
|
||||
public PlayerAttributes(PlayerData data) {
|
||||
this.data = data;
|
||||
}
|
||||
public PlayerAttributes(PlayerData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void load(ConfigurationSection config) {
|
||||
for (String key : config.getKeys(false))
|
||||
try {
|
||||
String id = key.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
|
||||
public void load(ConfigurationSection config) {
|
||||
for (String key : config.getKeys(false))
|
||||
try {
|
||||
String id = key.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
|
||||
|
||||
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
|
||||
AttributeInstance ins = new AttributeInstance(attribute.getId());
|
||||
ins.setBase(config.getInt(key));
|
||||
instances.put(id, ins);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
data.log(Level.WARNING, exception.getMessage());
|
||||
}
|
||||
}
|
||||
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
|
||||
AttributeInstance ins = new AttributeInstance(attribute.getId());
|
||||
ins.setBase(config.getInt(key));
|
||||
instances.put(id, ins);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
data.log(Level.WARNING, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void save(ConfigurationSection config) {
|
||||
instances.values().forEach(ins -> config.set(ins.id, ins.getBase()));
|
||||
}
|
||||
public void save(ConfigurationSection config) {
|
||||
instances.values().forEach(ins -> config.set(ins.id, ins.getBase()));
|
||||
}
|
||||
|
||||
public String toJsonString() {
|
||||
JsonObject json = new JsonObject();
|
||||
for (AttributeInstance ins : instances.values())
|
||||
json.addProperty(ins.getId(), ins.getBase());
|
||||
return json.toString();
|
||||
}
|
||||
public String toJsonString() {
|
||||
JsonObject json = new JsonObject();
|
||||
for (AttributeInstance ins : instances.values())
|
||||
json.addProperty(ins.getId(), ins.getBase());
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
public void load(String json) {
|
||||
Gson parser = new Gson();
|
||||
JsonObject jo = parser.fromJson(json, JsonObject.class);
|
||||
for (Entry<String, JsonElement> entry : jo.entrySet()) {
|
||||
try {
|
||||
String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
|
||||
public void load(String json) {
|
||||
Gson parser = new Gson();
|
||||
JsonObject jo = parser.fromJson(json, JsonObject.class);
|
||||
for (Entry<String, JsonElement> entry : jo.entrySet()) {
|
||||
try {
|
||||
String id = entry.getKey().toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Validate.isTrue(MMOCore.plugin.attributeManager.has(id), "Could not find attribute '" + id + "'");
|
||||
|
||||
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
|
||||
AttributeInstance ins = new AttributeInstance(attribute.getId());
|
||||
ins.setBase(entry.getValue().getAsInt());
|
||||
instances.put(id, ins);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
data.log(Level.WARNING, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
PlayerAttribute attribute = MMOCore.plugin.attributeManager.get(id);
|
||||
AttributeInstance ins = new AttributeInstance(attribute.getId());
|
||||
ins.setBase(entry.getValue().getAsInt());
|
||||
instances.put(id, ins);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
data.log(Level.WARNING, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerData getData() {
|
||||
return data;
|
||||
}
|
||||
public PlayerData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getAttribute(PlayerAttribute attribute) {
|
||||
return getInstance(attribute).getTotal();
|
||||
}
|
||||
public int getAttribute(PlayerAttribute attribute) {
|
||||
return getInstance(attribute).getTotal();
|
||||
}
|
||||
|
||||
public Collection<AttributeInstance> getInstances() {
|
||||
return instances.values();
|
||||
}
|
||||
public Collection<AttributeInstance> getInstances() {
|
||||
return instances.values();
|
||||
}
|
||||
|
||||
public Map<String, Integer> mapPoints() {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
instances.values().forEach(ins -> map.put(ins.id, ins.spent));
|
||||
return map;
|
||||
}
|
||||
public Map<String, Integer> mapPoints() {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
instances.values().forEach(ins -> map.put(ins.id, ins.spent));
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AttributeInstance getInstance(String attribute) {
|
||||
return instances.computeIfAbsent(attribute, AttributeInstance::new);
|
||||
}
|
||||
@NotNull
|
||||
public AttributeInstance getInstance(String attribute) {
|
||||
return instances.computeIfAbsent(attribute, AttributeInstance::new);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AttributeInstance getInstance(PlayerAttribute attribute) {
|
||||
return getInstance(attribute.getId());
|
||||
}
|
||||
@NotNull
|
||||
public AttributeInstance getInstance(PlayerAttribute attribute) {
|
||||
return getInstance(attribute.getId());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int countSkillPoints() {
|
||||
return countPoints();
|
||||
}
|
||||
@Deprecated
|
||||
public int countSkillPoints() {
|
||||
return countPoints();
|
||||
}
|
||||
|
||||
public int countPoints() {
|
||||
int n = 0;
|
||||
for (AttributeInstance ins : instances.values())
|
||||
n += ins.getBase();
|
||||
return n;
|
||||
}
|
||||
public int countPoints() {
|
||||
int n = 0;
|
||||
for (AttributeInstance ins : instances.values())
|
||||
n += ins.getBase();
|
||||
return n;
|
||||
}
|
||||
|
||||
public class AttributeInstance {
|
||||
private int spent;
|
||||
public class AttributeInstance {
|
||||
private int spent;
|
||||
|
||||
private final String id, enumName;
|
||||
private final Map<String, AttributeModifier> map = new HashMap<>();
|
||||
private final String id, enumName;
|
||||
private final Map<String, AttributeModifier> map = new HashMap<>();
|
||||
|
||||
public AttributeInstance(String id) {
|
||||
this.id = id;
|
||||
this.enumName = UtilityMethods.enumName(this.id);
|
||||
}
|
||||
public AttributeInstance(String id) {
|
||||
this.id = id;
|
||||
this.enumName = UtilityMethods.enumName(this.id);
|
||||
}
|
||||
|
||||
public int getBase() {
|
||||
return spent;
|
||||
}
|
||||
public int getBase() {
|
||||
return spent;
|
||||
}
|
||||
|
||||
public void setBase(int value) {
|
||||
spent = Math.max(0, value);
|
||||
public void setBase(int value) {
|
||||
spent = Math.max(0, value);
|
||||
|
||||
if (data.isOnline())
|
||||
update();
|
||||
}
|
||||
if (data.isOnline())
|
||||
updateStats();
|
||||
}
|
||||
|
||||
public void addBase(int value) {
|
||||
setBase(spent + value);
|
||||
}
|
||||
public void addBase(int value) {
|
||||
setBase(spent + value);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) two types of attributes: flat attributes which add X to the value,
|
||||
* and relative attributes which add X% and which must be applied
|
||||
* afterwards 2) the 'd' parameter lets you choose if the relative
|
||||
* attributes also apply on the base stat, or if they only apply on the
|
||||
* instances stat value
|
||||
*/
|
||||
public int getTotal() {
|
||||
double d = spent;
|
||||
/*
|
||||
* 1) two types of attributes: flat attributes which add X to the value,
|
||||
* and relative attributes which add X% and which must be applied
|
||||
* afterwards 2) the 'd' parameter lets you choose if the relative
|
||||
* attributes also apply on the base stat, or if they only apply on the
|
||||
* instances stat value
|
||||
*/
|
||||
public int getTotal() {
|
||||
double d = spent;
|
||||
|
||||
for (AttributeModifier attr : map.values())
|
||||
if (attr.getType() == ModifierType.FLAT)
|
||||
d += attr.getValue();
|
||||
for (AttributeModifier attr : map.values())
|
||||
if (attr.getType() == ModifierType.FLAT)
|
||||
d += attr.getValue();
|
||||
|
||||
d += data.getMMOPlayerData().getStatMap().getStat("ADDITIONAL_" + enumName);
|
||||
d += data.getMMOPlayerData().getStatMap().getStat("ADDITIONAL_" + enumName);
|
||||
|
||||
for (AttributeModifier attr : map.values())
|
||||
if (attr.getType() == ModifierType.RELATIVE)
|
||||
d *= attr.getValue();
|
||||
for (AttributeModifier attr : map.values())
|
||||
if (attr.getType() == ModifierType.RELATIVE)
|
||||
d *= attr.getValue();
|
||||
|
||||
d *= 1 + data.getMMOPlayerData().getStatMap().getStat("ADDITIONAL_" + enumName + "_PERCENT") / 100;
|
||||
d *= 1 + data.getMMOPlayerData().getStatMap().getStat("ADDITIONAL_" + enumName + "_PERCENT") / 100;
|
||||
|
||||
// cast to int at the last moment
|
||||
return (int) d;
|
||||
}
|
||||
// cast to int at the last moment
|
||||
return (int) d;
|
||||
}
|
||||
|
||||
public AttributeModifier getModifier(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
public AttributeModifier getModifier(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public AttributeModifier addModifier(String key, double value) {
|
||||
return addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));
|
||||
}
|
||||
public AttributeModifier addModifier(String key, double value) {
|
||||
return addModifier(new AttributeModifier(key, id, value, ModifierType.FLAT, EquipmentSlot.OTHER, ModifierSource.OTHER));
|
||||
}
|
||||
|
||||
public AttributeModifier addModifier(AttributeModifier modifier) {
|
||||
AttributeModifier mod = map.put(modifier.getKey(), modifier);
|
||||
update();
|
||||
return mod;
|
||||
}
|
||||
public AttributeModifier addModifier(AttributeModifier modifier) {
|
||||
final AttributeModifier current = map.put(modifier.getKey(), modifier);
|
||||
|
||||
public Set<String> getKeys() {
|
||||
return map.keySet();
|
||||
}
|
||||
if (current != null && current instanceof Closeable)
|
||||
((Closeable) current).close();
|
||||
|
||||
public boolean contains(String key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
updateStats();
|
||||
return current;
|
||||
}
|
||||
|
||||
public AttributeModifier removeModifier(String key) {
|
||||
AttributeModifier mod = map.remove(key);
|
||||
public Set<String> getKeys() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
/*
|
||||
* Closing stat is really important with temporary stats because
|
||||
* otherwise the runnable will try to remove the key from the map
|
||||
* even though the attribute was cancelled before hand
|
||||
*/
|
||||
if (mod != null) {
|
||||
if (mod instanceof Closeable)
|
||||
((Closeable) mod).close();
|
||||
update();
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
public boolean contains(String key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
|
||||
int total = getTotal();
|
||||
attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
|
||||
}
|
||||
public AttributeModifier removeModifier(String key) {
|
||||
final AttributeModifier mod = map.remove(key);
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Closing stat is really important with temporary stats because
|
||||
* otherwise the runnable will try to remove the key from the map
|
||||
* even though the attribute was cancelled before hand
|
||||
*/
|
||||
if (mod != null) {
|
||||
if (mod instanceof Closeable)
|
||||
((Closeable) mod).close();
|
||||
updateStats();
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
|
||||
public void setBaseAttribute(String id, int value) {
|
||||
getInstances().forEach(ins -> {
|
||||
if (ins.getId().equals(id))
|
||||
ins.setBase(value);
|
||||
});
|
||||
}
|
||||
public void updateStats() {
|
||||
final PlayerAttribute attr = MMOCore.plugin.attributeManager.get(id);
|
||||
final int total = getTotal();
|
||||
attr.getBuffs().forEach(buff -> buff.multiply(total).register(data.getMMOPlayerData()));
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public void setBaseAttribute(String id, int value) {
|
||||
getInstances().forEach(ins -> {
|
||||
if (ins.getId().equals(id))
|
||||
ins.setBase(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,55 @@
|
||||
package net.Indyuce.mmocore.manager;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.api.player.attribute.MMOCoreAttributeStatHandler;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class AttributeManager implements MMOCoreManager {
|
||||
private final Map<String, PlayerAttribute> map = new HashMap<>();
|
||||
private final Map<String, PlayerAttribute> map = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
public PlayerAttribute get(String id) {
|
||||
return map.get(id);
|
||||
}
|
||||
@Nullable
|
||||
public PlayerAttribute get(String id) {
|
||||
return map.get(id);
|
||||
}
|
||||
|
||||
public boolean has(String id) {
|
||||
return map.containsKey(id);
|
||||
}
|
||||
public boolean has(String id) {
|
||||
return map.containsKey(id);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<PlayerAttribute> getAll() {
|
||||
return map.values();
|
||||
}
|
||||
@NotNull
|
||||
public Collection<PlayerAttribute> getAll() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(boolean clearBefore) {
|
||||
if (clearBefore)
|
||||
map.clear();
|
||||
@Override
|
||||
public void initialize(boolean clearBefore) {
|
||||
if (clearBefore) {
|
||||
map.clear();
|
||||
MythicLib.plugin.getStats().clearRegisteredStats(handler -> handler instanceof MMOCoreAttributeStatHandler);
|
||||
}
|
||||
|
||||
ConfigFile config = new ConfigFile("attributes");
|
||||
for (String key : config.getConfig().getKeys(false))
|
||||
try {
|
||||
String path = key.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
map.put(path, new PlayerAttribute(config.getConfig().getConfigurationSection(key)));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load attribute '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
final ConfigFile config = new ConfigFile("attributes");
|
||||
for (String key : config.getConfig().getKeys(false))
|
||||
try {
|
||||
String path = key.toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
map.put(path, new PlayerAttribute(config.getConfig().getConfigurationSection(key)));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load attribute '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
|
||||
for (PlayerAttribute attr : getAll()) {
|
||||
final MMOCoreAttributeStatHandler handler = new MMOCoreAttributeStatHandler(attr);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat(), handler);
|
||||
MythicLib.plugin.getStats().registerStat(handler.getStat() + "_PERCENT", handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user