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
2 changes: 1 addition & 1 deletion core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
dependencies {
implementation("org.apache.commons:commons-math4-core:4.0-beta1")
implementation("com.github.ben-manes.caffeine:caffeine:3.2.2")
implementation("com.github.Chronoken:EffectLib:1da888c")
implementation("com.github.Chronoken:EffectLib:071cc3c")
implementation("org.incendo:cloud-paper:2.0.0-beta.16")
implementation("org.incendo:cloud-minecraft-extras:2.0.0-beta.16")
implementation("org.incendo:cloud-processors-requirements:1.0.0-rc.1")
Expand Down
39 changes: 27 additions & 12 deletions core/src/main/java/com/nisovin/magicspells/MagicSpells.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
import java.util.function.Predicate;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.annotation.Annotation;

import java.net.URL;
Expand Down Expand Up @@ -1955,20 +1959,30 @@ public static void registerEvents(final Listener listener, EventPriority customP
}

for (final Method method : methods) {
final EventHandler eh = method.getAnnotation(EventHandler.class);
if (eh == null) continue;
EventPriority priority = eh.priority();
final EventHandler handler = method.getAnnotation(EventHandler.class);
if (handler == null) continue;
EventPriority priority = handler.priority();

if (hasAnnotation(method, OverridePriority.class)) priority = customPriority;

final Class<?> checkClass = method.getParameterTypes()[0];
if (!Event.class.isAssignableFrom(checkClass) || method.getParameterTypes().length != 1) {
final Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1 || !Event.class.isAssignableFrom(paramTypes[0])) {
plugin.getLogger().severe("Wrong method arguments used for event type registered");
continue;
}

final Class<? extends Event> eventClass = checkClass.asSubclass(Event.class);
final Class<? extends Event> eventClass = paramTypes[0].asSubclass(Event.class);
method.setAccessible(true);
final MethodHandle methodHandle;
try {
MethodHandle handle = MethodHandles.lookup().unreflect(method);
if (!Modifier.isStatic(method.getModifiers())) handle = handle.bindTo(listener);
methodHandle = handle.asType(MethodType.methodType(void.class, Event.class));
} catch (IllegalAccessException e) {
plugin.getLogger().severe("Failed to create method handle for " + method.getName() + ": " + e.getMessage());
continue;
}

EventExecutor executor = new EventExecutor() {
final String eventKey = plugin.enableProfiling ? "Event:" + listener.getClass().getName().replace("com.nisovin.magicspells.", "") + '.' + method.getName() + '(' + eventClass.getSimpleName() + ')' : null;

Expand All @@ -1977,23 +1991,24 @@ public void execute(@NotNull Listener listener, @NotNull Event event) {
try {
if (!eventClass.isAssignableFrom(event.getClass())) return;
long start = System.nanoTime();
method.invoke(listener, event);
methodHandle.invokeExact((Event) event);
if (plugin.enableProfiling) {
Long total = plugin.profilingTotalTime.get(eventKey);
if (total == null) total = (long) 0;
if (total == null) total = 0L;
total += System.nanoTime() - start;
plugin.profilingTotalTime.put(eventKey, total);
Integer runs = plugin.profilingRuns.get(eventKey);
if (runs == null) runs = 0;
runs += 1;
runs++;
plugin.profilingRuns.put(eventKey, runs);
}
} catch (Exception ex) {
handleException(ex);
} catch (Throwable ex) {
if (ex instanceof Error e) throw e;
handleException(ex instanceof Exception exception ? exception : new RuntimeException(ex));
}
}
};
Bukkit.getPluginManager().registerEvent(eventClass, listener, priority, executor, plugin, eh.ignoreCancelled());
Bukkit.getPluginManager().registerEvent(eventClass, listener, priority, executor, plugin, handler.ignoreCancelled());
}
}

Expand Down
34 changes: 23 additions & 11 deletions core/src/main/java/com/nisovin/magicspells/Spell.java
Original file line number Diff line number Diff line change
Expand Up @@ -1078,14 +1078,17 @@ public PostCastAction castSpell(LivingEntity caster, SpellCastState state, float
}

protected SpellCastState getCastState(LivingEntity caster) {
if (caster instanceof Player player && !MagicSpells.getSpellbook(player).canCast(this))
if (caster instanceof Player player && !MagicSpells.getSpellbook(player).canCast(this)) {
return SpellCastState.CANT_CAST;
if (worldRestrictions != null && !worldRestrictions.contains(caster.getWorld().getName()))
}
if (worldRestrictions != null && !worldRestrictions.contains(caster.getWorld().getName())) {
return SpellCastState.WRONG_WORLD;
if (MagicSpells.getNoMagicZoneManager() != null && MagicSpells.getNoMagicZoneManager().willFizzle(caster, this))
return SpellCastState.NO_MAGIC_ZONE;
}
if (onCooldown(caster)) return SpellCastState.ON_COOLDOWN;
if (!hasReagents(caster)) return SpellCastState.MISSING_REAGENTS;
if (MagicSpells.getNoMagicZoneManager() != null && MagicSpells.getNoMagicZoneManager().willFizzle(caster, this)) {
return SpellCastState.NO_MAGIC_ZONE;
}
return SpellCastState.NORMAL;
}

Expand Down Expand Up @@ -1145,7 +1148,7 @@ public SpellCastEvent preCast(@NotNull SpellData data) {
}

if (castEvent.hasSpellCastStateChanged()) debug(2, " Spell cast state changed: " + state);
if (Perm.NO_CAST_TIME.has(data.caster())) castEvent.setCastTime(0);
if (castEvent.getCastTime() > 0 && Perm.NO_CAST_TIME.has(data.caster())) castEvent.setCastTime(0);

return castEvent;
}
Expand Down Expand Up @@ -1331,15 +1334,24 @@ public ConfigData<Float> getCooldown() {
* @return whether the spell is on cooldown
*/
public boolean onCooldown(LivingEntity livingEntity) {
if (Perm.NO_COOLDOWN.has(livingEntity)) return false;
UUID uuid = livingEntity.getUniqueId();
long timeMillis = System.currentTimeMillis();

ChargeState state = chargeStates.get(livingEntity.getUniqueId());
if (state != null && state.isDepleted()) return true;
ChargeState state = chargeStates.get(uuid);
boolean depleted = state != null && state.isDepleted();

if (serverCooldown > 0 && nextCastServer > System.currentTimeMillis()) return true;
if (!depleted && serverCooldown > 0 && nextCastServer > timeMillis) {
depleted = true;
}

Long next = nextCast.get(livingEntity.getUniqueId());
return next != null && next > System.currentTimeMillis();
if (!depleted) {
Long next = nextCast.get(uuid);
if (next != null && next > timeMillis) {
depleted = true;
}
}

return depleted && !Perm.NO_COOLDOWN.has(livingEntity);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ public void onSpellTarget(SpellTargetEvent event) {
Spell spell = event.getSpell();
if (target == null) return;

if (isMSEntity(target)) {
event.setCancelled(true);
return;
}

if (spell != null && noMagicZoneManager != null && noMagicZoneManager.willFizzle(target, spell)) {
event.setCancelled(true);
return;
}

if (Perm.NO_TARGET.has(target)) event.setCancelled(true);
if (spell != null && noMagicZoneManager != null && noMagicZoneManager.willFizzle(target, spell)) event.setCancelled(true);
if (isMSEntity(target)) event.setCancelled(true);
}

@EventHandler
Expand Down
12 changes: 9 additions & 3 deletions core/src/main/java/com/nisovin/magicspells/util/SpellUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ public static boolean hasReagents(LivingEntity livingEntity, SpellReagents reage
* @return true if the player has all the reagents, false otherwise
*/
public static boolean hasReagents(LivingEntity livingEntity, SpellReagents.ReagentItem[] reagents, double healthCost, int manaCost, int hungerCost, int experienceCost, int levelsCost, int durabilityCost, float moneyCost, Map<String, Double> variables) {
// Is the livingEntity exempt from reagent costs?
if (Perm.NO_REAGENTS.has(livingEntity)) return true;
return meetsCosts(livingEntity, reagents, healthCost, manaCost, hungerCost, experienceCost, levelsCost, durabilityCost, moneyCost, variables) || Perm.NO_REAGENTS.has(livingEntity);
}

private static boolean meetsCosts(LivingEntity livingEntity, SpellReagents.ReagentItem[] reagents, double healthCost, int manaCost, int hungerCost, int experienceCost, int levelsCost, int durabilityCost, float moneyCost, Map<String, Double> variables) {
// player reagents
if (livingEntity instanceof Player player) {
// Mana costs
Expand Down Expand Up @@ -147,7 +148,12 @@ public static void removeReagents(LivingEntity livingEntity, SpellReagents reage
* @param manaCost the mana to remove
*/
public static void removeReagents(LivingEntity livingEntity, SpellReagents.ReagentItem[] reagents, double healthCost, int manaCost, int hungerCost, int experienceCost, int levelsCost, int durabilityCost, float moneyCost, Map<String, Double> variables) {
if (Perm.NO_REAGENTS.has(livingEntity)) return;
boolean hasCosts = (reagents != null && reagents.length > 0)
|| healthCost != 0 || manaCost != 0 || hungerCost != 0
|| experienceCost != 0 || levelsCost != 0 || durabilityCost != 0
|| moneyCost != 0 || (variables != null && !variables.isEmpty());

if (!hasCosts || Perm.NO_REAGENTS.has(livingEntity)) return;

if (reagents != null) {
for (SpellReagents.ReagentItem item : reagents) {
Expand Down
Loading