Skip to content
Merged
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
timeout-minutes: 20
steps:
- name: Checkout project sources
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{github.event.pull_request.head.sha || github.sha}}

Expand All @@ -45,21 +45,21 @@ jobs:
run: echo "version=$(grep version gradle.properties | cut -d"=" -f2 | xargs)" >> $GITHUB_OUTPUT

- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 25

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v6

- name: Run build with Gradle Wrapper
run: ./gradlew "-Pversion=${{steps.version.outputs.version}}-${{steps.hash.outputs.sha_short}}" core:build

- name: Upload artifact
if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Build PR Jar')
id: artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: MagicSpells-${{steps.version.outputs.version}}-${{steps.hash.outputs.sha_short}}
if-no-files-found: error
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr_comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
- uses: actions/github-script@v9
with:
script: |
const label = "Build PR Jar";
Expand Down
13 changes: 9 additions & 4 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ plugins {
dependencies {
shadow("org.apache.commons:commons-math4-core:4.0-beta1")
shadow("com.github.ben-manes.caffeine:caffeine:3.2.2")
shadow("com.github.Chronoken:EffectLib:4e37625")
shadow("org.incendo:cloud-paper:2.0.0-beta.14")
shadow("org.incendo:cloud-minecraft-extras:2.0.0-beta.15")
shadow("com.github.Chronoken:EffectLib:1da888c")
shadow("org.incendo:cloud-paper:2.0.0-beta.16")
shadow("org.incendo:cloud-minecraft-extras:2.0.0-beta.16")
shadow("org.incendo:cloud-processors-requirements:1.0.0-rc.1")
shadow("org.bstats:bstats-bukkit:3.2.1")
shadow("com.github.ezylang:EvalEx:3.6.0")
shadow("com.github.ezylang:EvalEx:3.6.2")

shadow("org.antlr:antlr4-runtime:4.13.2")
antlr("org.antlr:antlr4:4.13.2")

shadow(project(path: ":nms:shared", configuration: "apiElements"))
shadow(project(path: ":nms:latest")) { transitive = false }
shadow(project(path: ":nms:v26_1_2")) { transitive = false }

implementation("com.github.retrooper:packetevents-spigot:2.11.2")
implementation("net.dmulloy2:ProtocolLib:5.4.0") { transitive = false }
Expand Down Expand Up @@ -62,6 +63,10 @@ shadowJar {
archiveClassifier.set("")
}

jar {
enabled = false
}

generateGrammarSource {
packageName = "com.nisovin.magicspells.util.grammars"
arguments += ["-visitor", "-no-listener"]
Expand Down
21 changes: 18 additions & 3 deletions core/src/main/java/com/nisovin/magicspells/Spell.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.MustBeInvokedByOverriders;

import de.slikey.effectlib.Effect;

Expand Down Expand Up @@ -537,6 +538,7 @@ protected SpellReagents getConfigReagents(String option) {
return reagents;
}

@MustBeInvokedByOverriders
protected void initializeVariables() {
// Variable options
if (varModsCast != null && !varModsCast.isEmpty()) {
Expand Down Expand Up @@ -584,6 +586,7 @@ protected void initializeVariables() {
if (reagents == null) reagents = new SpellReagents();
}

@MustBeInvokedByOverriders
protected void initializeSpellEffects() {
// Graphical effects
effectTrackerSet = new HashSet<>();
Expand Down Expand Up @@ -652,6 +655,7 @@ protected void initializeSpellEffect(ConfigurationSection section, String key) {

// DEBUG INFO: level 2, adding modifiers to internalname
// DEBUG INFO: level 2, adding target modifiers to internalname
@MustBeInvokedByOverriders
protected void initializeModifiers() {
// Modifiers
if (modifierStrings != null && !modifierStrings.isEmpty()) {
Expand Down Expand Up @@ -684,6 +688,7 @@ protected void initializeModifiers() {
/**
* This method is called immediately after all spells have been loaded.
*/
@MustBeInvokedByOverriders
protected void initialize() {
// Process shared cooldowns
List<?> rawSharedCooldowns = config.getList(internalKey + "shared-cooldowns", null);
Expand Down Expand Up @@ -1236,7 +1241,7 @@ public void sendMessages(LivingEntity caster, String[] args) {
public void sendMessages(SpellData data, String... replacements) {
sendMessage(strCastSelf, data.caster(), data, replacements);
sendMessage(strCastTarget, data.target(), data, replacements);
sendMessageNear(strCastOthers, data, broadcastRange.get(data), replacements);
sendMessageNear(strCastOthers, data, replacements);
}

protected boolean preCastTimeCheck(LivingEntity livingEntity, String[] args) {
Expand Down Expand Up @@ -2296,8 +2301,7 @@ protected void sendMessage(String message, LivingEntity recipient, SpellData dat
*/
@Deprecated
protected void sendMessageNear(LivingEntity livingEntity, String message) {
SpellData data = new SpellData(livingEntity);
sendMessageNear(message, data, broadcastRange.get(data));
sendMessageNear(message, new SpellData(livingEntity));
}

/**
Expand Down Expand Up @@ -2325,6 +2329,17 @@ protected void sendMessageNear(LivingEntity livingEntity, Player ignore, String
sendMessageNear(message, new SpellData(livingEntity, ignore, 1f, args), range, replacements);
}

/**
* Sends a message to all players near the specified player, within the default broadcast range.
*
* @param message the message to send
* @param data the associated spell data
* @param replacements replacements to be done on message
*/
protected void sendMessageNear(String message, SpellData data, String... replacements) {
sendMessageNear(message, data, broadcastRange.get(data), replacements);
}

/**
* Sends a message to all players near the specified player, within the specified broadcast range.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.regex.Pattern;

import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.LivingEntity;
import org.bukkit.attribute.AttributeInstance;
Expand Down Expand Up @@ -48,10 +49,13 @@ public boolean initialize(@NotNull String var) {

@Override
public boolean check(LivingEntity caster) {
AttributeInstance instance = caster.getAttribute(attribute);
EntityType entityType = caster.getType();
if (!entityType.hasDefaultAttributes()) return false;

AttributeInstance instance = entityType.getDefaultAttributes().getAttribute(attribute);
if (instance == null) return false;

return compare(instance.getDefaultValue(), value);
return compare(instance.getBaseValue(), value);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.nisovin.magicspells.spelleffects.effecttypes;

import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.configuration.ConfigurationSection;

import com.nisovin.magicspells.util.Name;
import com.nisovin.magicspells.util.SpellData;
import com.nisovin.magicspells.util.config.ConfigData;
import com.nisovin.magicspells.spelleffects.SpellEffect;
import com.nisovin.magicspells.util.config.ConfigDataUtil;

@Name("experience")
public class ExperienceEffect extends SpellEffect {

private ConfigData<Integer> level;
private ConfigData<Integer> progress;

private ConfigData<Boolean> reset;

@Override
protected void loadFromConfig(ConfigurationSection config) {
level = ConfigDataUtil.getInteger(config, "level");
progress = ConfigDataUtil.getInteger(config, "progress");

reset = ConfigDataUtil.getBoolean(config, "reset", false);
}

@Override
protected Runnable playEffectEntity(Entity entity, SpellData data) {
if (!(entity instanceof Player player)) return null;

boolean reset = this.reset.get(data);

Integer l = this.level.get(data);
int level = l == null || reset ? player.getLevel() : l;

Integer p = this.progress.get(data);
float progress = p == null || reset ? player.getExp() : p / 100f;

try {
player.sendExperienceChange(progress, level);
} catch (IllegalArgumentException e) {
// debug
}

return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.bukkit.configuration.ConfigurationSection;

import com.nisovin.magicspells.util.Name;
import com.nisovin.magicspells.MagicSpells;
import com.nisovin.magicspells.util.SpellData;
import com.nisovin.magicspells.util.config.ConfigData;
import com.nisovin.magicspells.spelleffects.SpellEffect;
Expand All @@ -32,41 +33,46 @@ public class ParticlesEffect extends SpellEffect {

protected ConfigData<Particle> particle;

protected ConfigData<Color> rgbColor;
private ConfigData<Color> rgbColor;
protected ConfigData<Color> argbColor;

protected ConfigData<Material> material;
protected ConfigData<BlockData> blockData;
protected ConfigData<DustOptions> dustOptions;
protected ConfigData<Particle.Spell> spellOptions;
protected ConfigData<DustTransition> dustTransition;
private ConfigData<Material> material;
private ConfigData<BlockData> blockData;
private ConfigData<DustOptions> dustOptions;
private ConfigData<Particle.Spell> spellOptions;
private ConfigData<DustTransition> dustTransition;

protected ConfigData<Vector> vibrationOffset;
protected ConfigData<Vector> vibrationRelativeOffset;
protected ConfigData<ParticlePosition> vibrationOrigin;
protected ConfigData<ParticlePosition> vibrationDestination;
private ConfigData<Vector> vibrationOffset;
private ConfigData<Vector> vibrationRelativeOffset;
private ConfigData<ParticlePosition> vibrationOrigin;
private ConfigData<ParticlePosition> vibrationDestination;

protected ConfigData<Color> trailColor;
protected ConfigData<Integer> trailDuration;
protected ConfigData<Vector> trailTargetOffset;
protected ConfigData<ParticlePosition> trailOrigin;
protected ConfigData<ParticlePosition> trailTarget;
protected ConfigData<Vector> trailTargetRelativeOffset;
private ConfigData<Color> trailColor;
private ConfigData<Integer> trailDuration;
private ConfigData<Vector> trailTargetOffset;
private ConfigData<ParticlePosition> trailOrigin;
private ConfigData<ParticlePosition> trailTarget;
private ConfigData<Vector> trailTargetRelativeOffset;

private ConfigData<Integer> geyserWaterBlocks;
private ConfigData<Float> geyserBurstImpulse;

protected ConfigData<Integer> count;
protected ConfigData<Integer> radius;
protected ConfigData<Integer> arrivalTime;
protected ConfigData<Integer> shriekDelay;
private ConfigData<Integer> radius;
private ConfigData<Integer> arrivalTime;
private ConfigData<Integer> shriekDelay;

protected ConfigData<Float> speed;

protected ConfigData<Float> xSpread;
protected ConfigData<Float> ySpread;
protected ConfigData<Float> zSpread;
protected ConfigData<Float> dragonBreathPower;
protected ConfigData<Float> sculkChargeRotation;

private ConfigData<Float> dragonBreathPower;
private ConfigData<Float> sculkChargeRotation;

protected ConfigData<Boolean> force;
protected ConfigData<Boolean> staticDestination;
private ConfigData<Boolean> staticDestination;

@Override
public void loadFromConfig(ConfigurationSection config) {
Expand All @@ -93,6 +99,9 @@ public void loadFromConfig(ConfigurationSection config) {
trailTargetOffset = ConfigDataUtil.getVector(config, "trail.target-offset", new Vector());
trailTargetRelativeOffset = ConfigDataUtil.getVector(config, "trail.target-relative-offset", new Vector());

geyserWaterBlocks = ConfigDataUtil.getInteger(config, "geyser.water-blocks");
geyserBurstImpulse = ConfigDataUtil.getFloat(config, "geyser.burst-impulse");

count = ConfigDataUtil.getInteger(config, "count", 5);
radius = ConfigDataUtil.getInteger(config, "radius", 50);
arrivalTime = ConfigDataUtil.getInteger(config, "arrival-time", -1);
Expand Down Expand Up @@ -156,6 +165,13 @@ public Runnable playEffectLocation(Location location, SpellData data) {
}

protected Object getParticleData(@NotNull Particle particle, @Nullable Entity entity, @NotNull Location location, @NotNull SpellData data) {
Object nmsData = MagicSpells.getVolatileCodeHandler().getVolatileParticleData(
particle,
() -> geyserWaterBlocks.get(data),
() -> geyserBurstImpulse.get(data)
);
if (nmsData != null) return nmsData;

Class<?> type = particle.getDataType();

if (type == Color.class) {
Expand Down
Loading
Loading