Skip to content
Merged
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
24 changes: 24 additions & 0 deletions src/main/java/net/tfminecraft/magic/Cache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package net.tfminecraft.magic;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Set;

/**
* Runtime flags from config.yml.
*/
Expand All @@ -25,6 +30,11 @@ public final class Cache {
public static double castDriftMin = 0.01;
/** Seconds between repeat chat lines explaining why a weapon refused a spell. */
public static long refuseChatMillis = 30000L;
/**
* Extra MythicLib triggers treated as a cast, from {@code runes.keybinds}.
* Names are uppercase. {@code CAST} and {@code API} are always included in the check.
*/
public static volatile Set<String> castTriggers = Set.of();

public static double tickIntervalSeconds() {
return Math.max(1L, tickIntervalTicks) / 20.0;
Expand All @@ -35,5 +45,19 @@ public static double tickHours() {
return tickIntervalSeconds() / scale;
}

/** Replaces the configured cast triggers. Blank entries are dropped. */
public static void setCastTriggers(Iterable<String> names) {
LinkedHashSet<String> next = new LinkedHashSet<>();
if (names != null) {
for (String name : names) {
if (name == null || name.isBlank()) {
continue;
}
next.add(name.trim().toUpperCase(Locale.ROOT));
}
}
castTriggers = Collections.unmodifiableSet(next);
}

private Cache() {}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
package net.tfminecraft.magic.integration;

import java.util.Locale;

import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.skill.CastableSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.tfminecraft.magic.Cache;

public final class SkillIdResolver {

private SkillIdResolver() {}

/**
* True for MMOCore casts and for every trigger named in {@code runes.keybinds}.
* Rune abilities report their keybind ({@code RIGHT_CLICK} and the rest), not {@code CAST}.
*/
public static boolean isActiveCast(Skill cast) {
if (cast == null) {
return false;
}
TriggerType trigger = cast.getTrigger();
return trigger == TriggerType.CAST || trigger == TriggerType.API;
if (trigger == null) {
return false;
}
if (trigger == TriggerType.CAST || trigger == TriggerType.API) {
return true;
}
String name = trigger.name();
if (name != null && Cache.castTriggers.contains(name.toUpperCase(Locale.ROOT))) {
return true;
}
String lower = trigger.getLowerCaseId();
return lower != null && Cache.castTriggers.contains(lower.toUpperCase(Locale.ROOT));
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/net/tfminecraft/magic/loader/ConfigLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
Expand Down Expand Up @@ -89,6 +90,7 @@ public boolean loadSafe(File configFile) {
long seconds = cast.getLong("refuse_chat_seconds", 30L);
Cache.refuseChatMillis = Math.max(0L, seconds) * 1000L;
}
loadCastTriggers(config.getStringList("runes.keybinds"));

ConfigurationSection artifacts = config.getConfigurationSection("artifacts");
if (artifacts != null) {
Expand All @@ -111,6 +113,15 @@ public boolean loadSafe(File configFile) {
return true;
}

private static void loadCastTriggers(List<String> keybinds) {
Cache.setCastTriggers(keybinds);
if (Cache.castTriggers.isEmpty()) {
Magic.plugin.getLogger().info("[Magic] No rune keybinds configured; cast checks use CAST and API.");
return;
}
Magic.plugin.getLogger().info("[Magic] Cast triggers: CAST, API, " + String.join(", ", Cache.castTriggers));
}

private static void loadGear(ConfigurationSection section) {
if (section == null) {
return;
Expand Down
12 changes: 11 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ equilibrium:
0: { mana: 0, damage: 0, cooldown: 0 }
100: { mana: -0.20, damage: 0.25, cooldown: -0.05 }

# MythicLib triggers the cast listener treats as a spell, besides CAST and API.
# These match the keybinds a rune can be set to. A weapon still has to be attuned
# to the spell's element.
runes:
keybinds:
- RIGHT_CLICK
- LEFT_CLICK
- SHIFT_RIGHT_CLICK
- SHIFT_LEFT_CLICK

# Global tick cycle (one runnable for the whole plugin).
# interval_ticks: 20 = one second elapsed per tick.
# seconds_per_hour: real seconds that count as one in-game hour for per-hour rates
Expand Down Expand Up @@ -65,7 +75,7 @@ meditation:
cast:
refuse_chat_seconds: 30

# Drift from spending mana on a CAST/API skill. 40 mana -> 0.04 (mana / mana_divisor).
# Drift from spending mana on a gated cast. 40 mana -> 0.04 (mana / mana_divisor).
# Surge adds corruption (negative equilibrium). Flow adds tranquility (positive).
cast_drift:
mana_divisor: 1000
Expand Down