Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
Expand All @@ -16,6 +17,7 @@
import studio.magemonkey.codex.hooks.NHook;
import studio.magemonkey.codex.util.StringUT;
import studio.magemonkey.divinity.Divinity;
import studio.magemonkey.divinity.api.event.DivinityDamageEvent;
import studio.magemonkey.divinity.config.EngineCfg;
import studio.magemonkey.divinity.hooks.HookClass;
import studio.magemonkey.divinity.hooks.HookLevel;
Expand All @@ -28,9 +30,12 @@
import studio.magemonkey.fabled.Fabled;
import studio.magemonkey.fabled.api.DefaultCombatProtection;
import studio.magemonkey.fabled.api.enums.ExpSource;
import studio.magemonkey.fabled.api.enums.Operation;
import studio.magemonkey.fabled.api.event.DynamicTriggerEvent;
import studio.magemonkey.fabled.api.event.PlayerManaGainEvent;
import studio.magemonkey.fabled.api.event.PlayerMaxManaChangeEvent;
import studio.magemonkey.fabled.api.event.SkillDamageEvent;
import studio.magemonkey.fabled.api.player.PlayerAttributeModifier;
import studio.magemonkey.fabled.api.player.PlayerData;
import studio.magemonkey.fabled.api.player.PlayerSkill;
import studio.magemonkey.fabled.api.skills.Skill;
Expand Down Expand Up @@ -118,6 +123,17 @@ public void onRegen(PlayerManaGainEvent e) {
}
}

@EventHandler
public void onMaxManaChange(PlayerMaxManaChangeEvent e) {
Player player = e.getPlayerData().getPlayer();
if (player == null) return;

double bonus = EntityStats.get(player).getItemStat(TypedStat.Type.MAX_MANA, false);
if (bonus != 0) {
e.setMaxMana(e.getMaxMana() + bonus);
}
}

@Override
public void takeMana(@NotNull Player player, double amount, boolean ofMax) {
PlayerData data = Fabled.getData(player);
Expand All @@ -133,7 +149,7 @@ public void takeMana(@NotNull Player player, double amount, boolean ofMax) {
data.setMana(Math.max(0, cur - amount));
}

private final List<UUID> divinityIgnored = new ArrayList<>();
private final Set<UUID> divinityIgnored = new HashSet<>();

@EventHandler(priority = EventPriority.MONITOR)
public void skillDamage(SkillDamageEvent event) {
Expand All @@ -145,10 +161,38 @@ public void skillDamage(SkillDamageEvent event) {

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void damage(EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof LivingEntity))
return;
UUID damagerUuid = null;
if (event.getDamager() instanceof LivingEntity) {
damagerUuid = ((LivingEntity) event.getDamager()).getUniqueId();
} else if (event.getDamager() instanceof Projectile) {
Projectile proj = (Projectile) event.getDamager();
if (proj.getShooter() instanceof LivingEntity)
damagerUuid = ((LivingEntity) proj.getShooter()).getUniqueId();
}
if (damagerUuid != null)
divinityIgnored.remove(damagerUuid);
}

divinityIgnored.remove(event.getDamager().getUniqueId());
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onDivinityDamageStart(DivinityDamageEvent.Start e) {
LivingEntity damager = e.getDamager();
if (damager == null || !damager.hasMetadata("fabled_dmg_flags")) return;

int flags = damager.getMetadata("fabled_dmg_flags").get(0).asInt();
if ((flags & 0x01) != 0) e.getDamageMeta().setIgnoreCrit(true);
if ((flags & 0x04) != 0) e.getDamageMeta().setBlockModifier(1.0);
if ((flags & 0x08) != 0) e.getDamagerItemStatsMap().put(TypedStat.Type.BLEED_RATE, 0.0);
if ((flags & 0x10) != 0) e.getDamagerItemStatsMap().put(TypedStat.Type.VAMPIRISM, 0.0);
if ((flags & 0x20) != 0) e.getDamageMeta().setIgnoreSkillCrit(true);
}

@EventHandler
public void onDivinityDodge(DivinityDamageEvent.Dodge e) {
LivingEntity damager = e.getDamager();
if (damager == null || !damager.hasMetadata("fabled_dmg_flags")) return;

int flags = damager.getMetadata("fabled_dmg_flags").get(0).asInt();
if ((flags & 0x02) != 0) e.setCancelled(true);
}

public void ignoreDivinity(LivingEntity player, boolean ignore) {
Expand Down Expand Up @@ -241,6 +285,58 @@ public ItemStack getAttributeIndicator(String attributeId) {
return itemStack;
}

private final Map<UUID, List<UUID>> playerAttrModifiers = new HashMap<>();

public void updateFabledAttributes(Player player) {
new BukkitRunnable() {
@Override
public void run() {
if (!Fabled.hasPlayerData(player)) return;
PlayerData data = Fabled.getData(player);
if (data == null) return;

List<UUID> oldUuids = playerAttrModifiers.remove(player.getUniqueId());
if (oldUuids != null) {
for (UUID uuid : oldUuids) {
data.removeAttributeModifier(uuid, false);
}
}

List<UUID> newUuids = new ArrayList<>();
PlayerInventory inventory = player.getInventory();
int[] slots = {inventory.getHeldItemSlot(), 36, 37, 38, 39, 40};
for (int slot : slots) {
ItemStack item = inventory.getItem(slot);
if (item == null) continue;
for (FabledAttribute attr : getAttributes()) {
Integer value = attr.getRaw(item);
if (value == null || value == 0) continue;
PlayerAttributeModifier modifier = new PlayerAttributeModifier(
"divinity.fabled_attr", value, Operation.ADD_NUMBER, false);
newUuids.add(modifier.getUUID());
data.addAttributeModifier(attr.getId(), modifier, false);
}
}

if (!newUuids.isEmpty()) {
playerAttrModifiers.put(player.getUniqueId(), newUuids);
}

data.updatePlayerStat(player);
}
}.runTaskLater(plugin, 1L);
}

public void clearFabledAttributes(Player player) {
List<UUID> uuids = playerAttrModifiers.remove(player.getUniqueId());
if (uuids == null || !Fabled.hasPlayerData(player)) return;
PlayerData data = Fabled.getData(player);
if (data == null) return;
for (UUID uuid : uuids) {
data.removeAttributeModifier(uuid, false);
}
}

public void updateSkills(Player player) {
new BukkitRunnable() {
@Override
Expand Down Expand Up @@ -284,6 +380,22 @@ public void run() {
}
}
}.runTaskLater(plugin, 1L);
updateFabledAttributes(player);
}

/**
* Scales a Divinity stat value using Fabled's attribute and stat modifier system.
* Fabled attributes.yml can reference Divinity stat names (lowercase type names, e.g. "critical_rate").
*/
public double applyStatScale(@NotNull Player player, @NotNull String statId, double value) {
try {
if (!Fabled.hasPlayerData(player)) return value;
PlayerData data = Fabled.getData(player);
if (data == null) return value;
return data.scaleStat(statId, value);
} catch (Exception ignored) {
return value;
}
}

public boolean isFakeDamage(EntityDamageByEntityEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,9 @@ public CombatLogManager getCombatLogManager() {
public MoneyManager getMoneyManager() {
return this.moneyManager;
}

@Nullable
public ConsumablesManager getConsumablesManager() {
return this.consumablesManager;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ public void onPlayerJoin(PlayerJoinEvent event) {
}
}

@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
FabledHook fabledHook = (FabledHook) this.plugin.getHook(EHook.SKILL_API);
if (fabledHook != null) {
fabledHook.clearFabledAttributes(event.getPlayer());
}
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void playerDeath(PlayerDeathEvent event) {
FabledHook fabledHook = (FabledHook) this.plugin.getHook(EHook.SKILL_API);
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/studio/magemonkey/divinity/stats/EntityStats.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import studio.magemonkey.divinity.config.EngineCfg;
import studio.magemonkey.divinity.data.api.DivinityUser;
import studio.magemonkey.divinity.data.api.UserProfile;
import studio.magemonkey.divinity.hooks.EHook;
import studio.magemonkey.divinity.hooks.external.FabledHook;
import studio.magemonkey.divinity.manager.damage.DamageMeta;
import studio.magemonkey.divinity.manager.effects.IEffect;
import studio.magemonkey.divinity.manager.effects.IEffectType;
Expand Down Expand Up @@ -691,6 +693,10 @@ public Map<DamageAttribute, Double> getDamageTypes(boolean safe, @Nullable ItemS
double value = Rnd.getDouble(range[0], range[1]);
value *= dmgAtt.getDamageModifierByBiome(bio); // Multiply by Biome
value = this.getEffectBonus(dmgAtt, safe).applyAsDouble(value);
if (this.isPlayer()) {
FabledHook fHook = (FabledHook) Divinity.getInstance().getHook(EHook.SKILL_API);
if (fHook != null) value = fHook.applyStatScale(this.player, "damage_" + dmgAtt.getId(), value);
}

if (value > 0D) {
map.put(dmgAtt, value);
Expand Down Expand Up @@ -724,6 +730,10 @@ public Map<DefenseAttribute, Double> getDefenseTypes(boolean safe) {

double value = BonusCalculator.SIMPLE_FULL.apply(0D, bonuses);
value = this.getEffectBonus(dt, safe).applyAsDouble(value);
if (this.isPlayer()) {
FabledHook fHook = (FabledHook) Divinity.getInstance().getHook(EHook.SKILL_API);
if (fHook != null) value = fHook.applyStatScale(this.player, "defense_" + dt.getId(), value);
}
if (value > 0D) {
map.put(dt, value);
}
Expand Down Expand Up @@ -794,6 +804,14 @@ public double getItemStat(@NotNull SimpleStat.Type type, boolean safe, @Nullable
}
}

// Apply Fabled attribute/stat scaling if player and Fabled is loaded
if (this.isPlayer()) {
FabledHook fHook = (FabledHook) Divinity.getInstance().getHook(EHook.SKILL_API);
if (fHook != null) {
value = fHook.applyStatScale(this.player, type.name().toLowerCase(), value);
}
}

return value;
}

Expand All @@ -808,6 +826,12 @@ public double getPenetration(@NotNull PenetrationStat pen) {
if (pen.getCapacity() >= 0 && value > pen.getCapacity()) {
value = pen.getCapacity();
}
if (this.isPlayer()) {
FabledHook fHook = (FabledHook) Divinity.getInstance().getHook(EHook.SKILL_API);
if (fHook != null) {
value = fHook.applyStatScale(this.player, "penetration_" + pen.getPenId(), value);
}
}
return value;
}

Expand All @@ -822,6 +846,14 @@ public double getDynamicBuff(@NotNull DynamicBuffStat buff) {
if (buff.getCapacity() >= 0 && value > buff.getCapacity()) {
value = buff.getCapacity();
}
if (this.isPlayer()) {
FabledHook fHook = (FabledHook) Divinity.getInstance().getHook(EHook.SKILL_API);
if (fHook != null) {
String buffKey = (buff.getBuffTarget() == DynamicBuffStat.BuffTarget.DAMAGE ? "damagebuff_" : "defensebuff_")
+ buff.getBuffId();
value = fHook.applyStatScale(this.player, buffKey, value);
}
}
return value;
}

Expand Down