diff --git a/.github/workflows/pr_comment.yml b/.github/workflows/pr_comment.yml index 8eb3f9c7f..60e1661ad 100644 --- a/.github/workflows/pr_comment.yml +++ b/.github/workflows/pr_comment.yml @@ -44,7 +44,10 @@ jobs: // Create or update comment, linking the artifact. const artifact_url = `https://nightly.link/${owner}/${repo}/actions/artifacts/${artifact.id}.zip`; const marker = ``; - const body = `${marker}\nBuilt artifact: [\`${artifact.name}\`](${artifact_url})`; + + let body = `${marker}\nBuilt artifact: [\`${artifact.name}\`](${artifact_url})`; + const {behind_by} = await github.rest.repos.compareCommitsWithBasehead({owner: pr_owner, repo, basehead: `${pr_branch}...${owner}:main`}); + if (behind_by > 0) body += `\n\n[(Behind by \`${behind_by}\` commits)](https://github.com/${pr_owner}/${repo}/compare/${pr_branch}...${owner}:main)`; const issue_number = pull_request.number; const {data: comments} = await github.rest.issues.listComments({owner, repo, issue_number}); diff --git a/core/src/main/java/com/nisovin/magicspells/spelleffects/effecttypes/ParticleCloudEffect.java b/core/src/main/java/com/nisovin/magicspells/spelleffects/effecttypes/ParticleCloudEffect.java index 1e6742457..efcaa3c50 100644 --- a/core/src/main/java/com/nisovin/magicspells/spelleffects/effecttypes/ParticleCloudEffect.java +++ b/core/src/main/java/com/nisovin/magicspells/spelleffects/effecttypes/ParticleCloudEffect.java @@ -3,6 +3,7 @@ import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; +import org.bukkit.entity.Entity; import org.bukkit.entity.AreaEffectCloud; import org.bukkit.configuration.ConfigurationSection; @@ -14,8 +15,8 @@ @Name("particlecloud") public class ParticleCloudEffect extends ParticlesEffect { - private ConfigData color; private ConfigData duration; + private ConfigData waitTime; private ConfigData radius; private ConfigData yOffset; @@ -25,7 +26,10 @@ public class ParticleCloudEffect extends ParticlesEffect { public void loadFromConfig(ConfigurationSection config) { super.loadFromConfig(config); - color = ConfigDataUtil.getInteger(config, "color", 0xFF0000); + ConfigData color = ConfigDataUtil.getInteger(config, "color", 0xFF0000); + argbColor = argbColor.orDefault(data -> Color.fromRGB(color.get(data))); + + waitTime = ConfigDataUtil.getInteger(config, "wait-time", 0); duration = ConfigDataUtil.getInteger(config, "duration", 60); radius = ConfigDataUtil.getFloat(config, "radius", 5); @@ -33,13 +37,18 @@ public void loadFromConfig(ConfigurationSection config) { radiusPerTick = ConfigDataUtil.getFloat(config, "radius-per-tick", 0); } + @Override + protected Runnable playEffectEntity(Entity entity, SpellData data) { + return playEffectLocation(applyOffsets(entity.getLocation(), data), data); + } + @Override public Runnable playEffectLocation(Location location, SpellData data) { Particle particle = this.particle.get(data); if (particle == null) return null; location.getWorld().spawn(location.clone().add(0, yOffset.get(data), 0), AreaEffectCloud.class, cloud -> { - cloud.setColor(Color.fromRGB(color.get(data))); + cloud.setWaitTime(waitTime.get(data)); cloud.setRadius(radius.get(data)); cloud.setDuration(duration.get(data)); cloud.setRadiusPerTick(radiusPerTick.get(data)); diff --git a/core/src/main/java/com/nisovin/magicspells/spells/MenuSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/MenuSpell.java index a5cdf80b6..285ecdaa6 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/MenuSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/MenuSpell.java @@ -3,7 +3,6 @@ import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -281,7 +280,7 @@ private void applyOptionsToInventory(Player opener, MenuInventory menu) { if (event.isCancelled()) continue; } // Select and finalise item to display. - ItemStack item = option.item != null ? option.item : option.items.get(ThreadLocalRandom.current().nextInt(option.items.size())); + ItemStack item = option.item != null ? option.item : option.items.get(random.nextInt(option.items.size())); item.editMeta(meta -> meta.getPersistentDataContainer().set(OPTION_KEY, PersistentDataType.STRING, option.menuOptionName)); item = translateItem(opener, item, menu.data); diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ParticleCloudSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ParticleCloudSpell.java index 5e844aa36..cb4d6eb05 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ParticleCloudSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ParticleCloudSpell.java @@ -1,9 +1,6 @@ package com.nisovin.magicspells.spells.targeted; -import java.util.Set; import java.util.List; -import java.util.HashSet; -import java.util.ArrayList; import org.bukkit.Color; import org.bukkit.Material; @@ -16,7 +13,9 @@ import org.bukkit.Particle.DustOptions; import org.bukkit.block.data.BlockData; import org.bukkit.entity.AreaEffectCloud; -import org.bukkit.potion.PotionEffectType; +import org.bukkit.Particle.DustTransition; + +import org.jetbrains.annotations.NotNull; import net.kyori.adventure.text.Component; @@ -26,7 +25,6 @@ import com.nisovin.magicspells.spells.TargetedEntitySpell; import com.nisovin.magicspells.util.config.ConfigDataUtil; import com.nisovin.magicspells.spells.TargetedLocationSpell; -import com.nisovin.magicspells.handlers.PotionEffectHandler; public class ParticleCloudSpell extends TargetedSpell implements TargetedLocationSpell, TargetedEntitySpell { @@ -34,12 +32,14 @@ public class ParticleCloudSpell extends TargetedSpell implements TargetedLocatio private final ConfigData customName; - protected ConfigData item; - protected ConfigData particle; - protected ConfigData blockData; - protected ConfigData dustOptions; + private final ConfigData color; + private final ConfigData item; + private final ConfigData blockData; + private final ConfigData dustOptions; + private final ConfigData dustTransition; + + private final ConfigData particle; - private final ConfigData color; private final ConfigData waitTime; private final ConfigData ticksDuration; private final ConfigData durationOnUse; @@ -53,7 +53,7 @@ public class ParticleCloudSpell extends TargetedSpell implements TargetedLocatio private final ConfigData canTargetEntities; private final ConfigData canTargetLocation; - private final Set potionEffects; + private final List> potionEffects; public ParticleCloudSpell(MagicConfig config, String spellName) { super(config, spellName); @@ -62,10 +62,18 @@ public ParticleCloudSpell(MagicConfig config, String spellName) { customName = getConfigDataComponent("custom-name", null); - particle = ConfigDataUtil.getParticle(config.getMainConfig(), internalKey + "particle", Particle.POOF); + ConfigData particle = ConfigDataUtil.getParticle(config.getMainConfig(), internalKey + "particle", Particle.POOF); + this.particle = ConfigDataUtil.getParticle(config.getMainConfig(), internalKey + "particle-name", null).orDefault(particle); blockData = getConfigDataBlockData("material", null); dustOptions = ConfigDataUtil.getDustOptions(config.getMainConfig(), internalKey + "dust-color", internalKey + "size", new DustOptions(Color.RED, 1)); + dustTransition = ConfigDataUtil.getDustTransition( + config.getMainConfig(), + internalKey + "dust-transition.color", + internalKey + "dust-transition.to-color", + internalKey + "dust-transition.size", + new DustTransition(Color.RED, Color.BLACK, 1) + ); ConfigData material = getConfigDataMaterial("material", null); if (material.isConstant()) { @@ -80,7 +88,10 @@ public ParticleCloudSpell(MagicConfig config, String spellName) { }; } - color = getConfigDataInt("color", 0xFF0000); + ConfigData colorInt = getConfigDataInt("color", 0xFF0000); + color = ConfigDataUtil.getARGBColor(config.getMainConfig(), internalKey + "argb-color", null) + .orDefault(data -> Color.fromRGB(colorInt.get(data))); + waitTime = getConfigDataInt("wait-time-ticks", 10); ticksDuration = getConfigDataInt("duration-ticks", 3 * TimeUtil.TICKS_PER_SECOND); durationOnUse = getConfigDataInt("duration-ticks-on-use", 0); @@ -94,28 +105,7 @@ public ParticleCloudSpell(MagicConfig config, String spellName) { canTargetEntities = getConfigDataBoolean("can-target-entities", true); canTargetLocation = getConfigDataBoolean("can-target-location", true); - List potionEffectStrings = getConfigStringList("potion-effects", null); - if (potionEffectStrings == null) potionEffectStrings = new ArrayList<>(); - - potionEffects = new HashSet<>(); - - for (String effect : potionEffectStrings) { - potionEffects.add(getPotionEffectFromString(effect)); - } - } - - private static PotionEffect getPotionEffectFromString(String s) { - String[] splits = s.split(" "); - PotionEffectType type = PotionEffectHandler.getPotionEffectType(splits[0]); - - int durationTicks = Integer.parseInt(splits[1]); - int amplifier = Integer.parseInt(splits[2]); - - boolean ambient = Boolean.parseBoolean(splits[3]); - boolean particles = Boolean.parseBoolean(splits[4]); - boolean icon = Boolean.parseBoolean(splits[5]); - - return new PotionEffect(type, durationTicks, amplifier, ambient, particles, icon); + potionEffects = Util.getPotionEffects(getConfigList("potion-effects", null), internalName); } @Override @@ -127,20 +117,14 @@ public CastResult cast(SpellData data) { if (!info.noTarget()) { Location location = info.target().getLocation(); location.setDirection(data.caster().getLocation().getDirection()); - data = info.spellData().location(location); - - spawnCloud(data); - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + return spawnCloud(info.spellData().location(location)); } } if (canTargetLocation.get(data)) { TargetInfo info = getTargetedBlockLocation(data, 0.5, 1, 0.5, false); if (info.noTarget()) return noTarget(info); - data = info.spellData(); - - spawnCloud(data); - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + return spawnCloud(info.spellData()); } return noTarget(data); @@ -148,18 +132,15 @@ public CastResult cast(SpellData data) { @Override public CastResult castAtLocation(SpellData data) { - spawnCloud(data); - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + return spawnCloud(data); } @Override public CastResult castAtEntity(SpellData data) { - data = data.location(data.target().getLocation()); - spawnCloud(data); - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + return spawnCloud(data.location(data.target().getLocation())); } - private void spawnCloud(SpellData data) { + private CastResult spawnCloud(SpellData data) { Location location = data.location(); //apply relative offset @@ -171,16 +152,8 @@ private void spawnCloud(SpellData data) { SpellData finalData = data; location.getWorld().spawn(location, AreaEffectCloud.class, cloud -> { - Particle particle = this.particle.get(finalData); - - Class dataType = particle.getDataType(); - if (dataType == BlockData.class) cloud.setParticle(particle, blockData.get(finalData)); - else if (dataType == ItemStack.class) cloud.setParticle(particle, item.get(finalData)); - else if (dataType == DustOptions.class) cloud.setParticle(particle, dustOptions.get(finalData)); - else cloud.setParticle(particle); - cloud.setSource(finalData.caster()); - cloud.setColor(Color.fromRGB(color.get(finalData))); + cloud.setRadius(radius.get(finalData)); cloud.setGravity(useGravity.get(finalData)); cloud.setWaitTime(waitTime.get(finalData)); @@ -190,7 +163,12 @@ private void spawnCloud(SpellData data) { cloud.setRadiusPerTick(radiusPerTick.get(finalData)); cloud.setReapplicationDelay(reapplicationDelay.get(finalData)); - for (PotionEffect eff : potionEffects) cloud.addCustomEffect(eff, true); + if (potionEffects != null) + for (ConfigData eff : potionEffects) + cloud.addCustomEffect(eff.get(finalData), true); + + Particle particle = this.particle.get(finalData); + cloud.setParticle(particle, getParticleData(particle, finalData)); Component customName = this.customName.get(finalData); if (customName != null) { @@ -199,8 +177,20 @@ private void spawnCloud(SpellData data) { } }); - if (data.hasTarget()) playSpellEffects(data.caster(), data.target(), data); - else playSpellEffects(data.caster(), location, data); + playSpellEffects(data); + return new CastResult(PostCastAction.HANDLE_NORMALLY, data); + } + + private Object getParticleData(@NotNull Particle particle, @NotNull SpellData data) { + Class type = particle.getDataType(); + + if (type == Color.class) return color.get(data); + if (type == ItemStack.class) return item.get(data); + if (type == BlockData.class) return blockData.get(data); + if (type == DustOptions.class) return dustOptions.get(data); + if (type == DustTransition.class) return dustTransition.get(data); + + return null; } } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ReplaceSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ReplaceSpell.java index 41928e72b..0c1e97ca4 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ReplaceSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ReplaceSpell.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.HashMap; import java.util.ArrayList; -import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -42,6 +41,7 @@ public class ReplaceSpell extends TargetedSpell implements TargetedLocationSpell private final ConfigData pointBlank; private final ConfigData checkPlugins; + private final ConfigData applyPhysics; private final ConfigData replaceRandom; private final ConfigData powerAffectsRadius; private final ConfigData resolveDurationPerBlock; @@ -62,8 +62,9 @@ public ReplaceSpell(MagicConfig config, String spellName) { pointBlank = getConfigDataBoolean("point-blank", false); checkPlugins = getConfigDataBoolean("check-plugins", true); - ConfigData replaceRandom = getConfigDataBoolean("replace-random", true); + applyPhysics = getConfigDataBoolean("apply-physics", true); powerAffectsRadius = getConfigDataBoolean("power-affects-radius", false); + ConfigData replaceRandom = getConfigDataBoolean("replace-random", true); resolveDurationPerBlock = getConfigDataBoolean("resolve-duration-per-block", false); boolean replaceAll = false; @@ -160,6 +161,7 @@ public CastResult castAtLocation(SpellData data) { } boolean checkPlugins = this.checkPlugins.get(data); + boolean applyPhysics = this.applyPhysics.get(data); boolean replaceRandom = this.replaceRandom.get(data); boolean resolveDurationPerBlock = this.resolveDurationPerBlock.get(data); @@ -181,12 +183,11 @@ public CastResult castAtLocation(SpellData data) { if (replaceBlacklisted(blockData)) continue; - Block finalBlock = block; BlockState previousState = block.getState(); // Place block. - if (replaceRandom) block.setBlockData(replaceWith.get(ThreadLocalRandom.current().nextInt(replaceWith.size()))); - else block.setBlockData(replaceWith.get(i)); + BlockData newData = replaceWith.get(replaceRandom ? random.nextInt(replaceWith.size()) : i); + block.setBlockData(newData, applyPhysics); if (checkPlugins && data.caster() instanceof Player player) { Block against = target.clone().add(target.getDirection()).getBlock(); @@ -199,14 +200,15 @@ public CastResult castAtLocation(SpellData data) { } } - SpellData subData = data.location(finalBlock.getLocation()); - playSpellEffects(EffectPosition.SPECIAL, finalBlock.getLocation(), subData); + SpellData subData = data.location(block.getLocation()); + playSpellEffects(EffectPosition.SPECIAL, block.getLocation(), subData); // Break block. if (resolveDurationPerBlock) replaceDuration = this.replaceDuration.get(subData); if (replaceDuration > 0) { blocks.put(block, blockData); + Block finalBlock = block; MagicSpells.scheduleDelayedTask(() -> { BlockData previous = blocks.remove(finalBlock); if (previous == null) return; @@ -215,7 +217,7 @@ public CastResult castAtLocation(SpellData data) { EventUtil.call(event); if (event.isCancelled()) return; } - finalBlock.setBlockData(previous); + finalBlock.setBlockData(previous, applyPhysics); playSpellEffects(EffectPosition.BLOCK_DESTRUCTION, finalBlock.getLocation(), subData); }, replaceDuration); } @@ -228,7 +230,7 @@ public CastResult castAtLocation(SpellData data) { } playSpellEffects(data); - return new CastResult(replaced ?PostCastAction.HANDLE_NORMALLY : PostCastAction.ALREADY_HANDLED, data); + return new CastResult(replaced ? PostCastAction.HANDLE_NORMALLY : PostCastAction.ALREADY_HANDLED, data); } private boolean replaceBlacklisted(BlockData data) { diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/SpawnEntitySpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/SpawnEntitySpell.java index 9ef85c993..fb8587562 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/SpawnEntitySpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/SpawnEntitySpell.java @@ -224,7 +224,7 @@ public SpawnEntitySpell(MagicConfig config, String spellName) { ambient = split.length > 3 && split[3].equalsIgnoreCase("ambient"); potionEffects.add(new PotionEffect(type, duration, strength, ambient)); } catch (Exception e) { - MagicSpells.error("SpawnMonsterSpell '" + spellName + "' has an invalid potion effect defined: " + data); + MagicSpells.error("SpawnEntitySpell '" + spellName + "' has an invalid potion effect defined: " + data); } } } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/VolleySpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/VolleySpell.java index e94c98459..4c0ddf428 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/VolleySpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/VolleySpell.java @@ -91,7 +91,7 @@ public VolleySpell(MagicConfig config, String spellName) { color = getConfigDataColor("color", null); potionType = getConfigDataRegistryEntry("potion-type", Registry.POTION, null); - potionEffects = Util.getPotionEffects(getConfigList("potion-effects", null), internalName, false, false); + potionEffects = Util.getPotionEffects(getConfigList("potion-effects", null), internalName); } @Override diff --git a/core/src/main/java/com/nisovin/magicspells/util/EntityData.java b/core/src/main/java/com/nisovin/magicspells/util/EntityData.java index 6143c0bd4..9e67e4452 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/EntityData.java +++ b/core/src/main/java/com/nisovin/magicspells/util/EntityData.java @@ -27,6 +27,7 @@ import org.bukkit.attribute.Attribute; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Transformation; +import org.bukkit.potion.PotionEffect; import org.bukkit.block.data.BlockData; import org.bukkit.attribute.Attributable; import org.bukkit.inventory.EquipmentSlot; @@ -179,6 +180,16 @@ public EntityData(ConfigurationSection config, boolean forceOptional) { addOptEquipment(transformers, config, "equipment.boots", EquipmentSlot.FEET); addOptEquipment(transformers, config, "equipment.body", Mob.class, EquipmentSlot.BODY); + List potionEffectData = config.getList("potion-effects"); + if (potionEffectData != null && !potionEffectData.isEmpty()) { + List> effects = Util.getPotionEffects(potionEffectData, null); + if (effects != null) { + transformers.put(LivingEntity.class, (LivingEntity entity, SpellData data) -> { + effects.forEach(effect -> entity.addPotionEffect(effect.get(data))); + }); + } + } + // Mob addOptEquipmentDropChance(transformers, config, "equipment.main-hand-drop-chance", EquipmentSlot.HAND); addOptEquipmentDropChance(transformers, config, "equipment.off-hand-drop-chance", EquipmentSlot.OFF_HAND); @@ -375,7 +386,7 @@ public EntityData(ConfigurationSection config, boolean forceOptional) { ConfigData translation = getVector(config, "transformation.translation"); ConfigData scale = getVector(config, "transformation.scale"); ConfigData transformation = data -> null; - if (checkNull(leftRotation) && checkNull(rightRotation) && checkNull(translation) && checkNull(scale)) { + if (!leftRotation.isNull() && !rightRotation.isNull() && !translation.isNull() && !scale.isNull()) { if (leftRotation.isConstant() && rightRotation.isConstant() && translation.isConstant() && scale.isConstant()) { Quaternionf lr = leftRotation.get(); Quaternionf rr = rightRotation.get(); @@ -418,7 +429,7 @@ public EntityData(ConfigurationSection config, boolean forceOptional) { ConfigData blockLight = ConfigDataUtil.getInteger(config, "brightness.block"); ConfigData skyLight = ConfigDataUtil.getInteger(config, "brightness.sky"); ConfigData brightness = data -> null; - if (checkNull(blockLight) && checkNull(skyLight)) { + if (!blockLight.isNull() && !skyLight.isNull()) { if (blockLight.isConstant() && skyLight.isConstant()) { int bl = blockLight.get(); int sl = skyLight.get(); @@ -745,7 +756,7 @@ private ConfigData addOptRegistryEntry(Multimap private ConfigData fallback(Function> function, String... keys) { for (String key : keys) { ConfigData data = function.apply(key); - if (checkNull(data)) return data; + if (!data.isNull()) return data; } return data -> null; @@ -812,7 +823,7 @@ public ConfigData getVector(ConfigurationSection config, String path) return data -> null; } - if (!checkNull(x) || !checkNull(y) || !checkNull(z)) return data -> null; + if (x.isNull() || y.isNull() || z.isNull()) return data -> null; if (x.isConstant() && y.isConstant() && z.isConstant()) { Vector3f vector = new Vector3f(x.get(), y.get(), z.get()); @@ -862,7 +873,7 @@ private ConfigData getQuaternion(ConfigurationSection config, Strin ConfigData angle = ConfigDataUtil.getFloat(config, path + ".angle"); ConfigData axis = getVector(config, path + ".axis"); - if (checkNull(angle) && checkNull(axis)) { + if (!angle.isNull() && !axis.isNull()) { if (angle.isConstant() && axis.isConstant()) { Vector3f ax = axis.get(); float ang = angle.get(); @@ -949,7 +960,7 @@ public boolean isConstant() { return data -> null; } - if (!checkNull(x) || !checkNull(y) || !checkNull(z) || !checkNull(w)) return data -> null; + if (x.isNull() || y.isNull() || z.isNull() || w.isNull()) return data -> null; if (x.isConstant() && y.isConstant() && z.isConstant() && w.isConstant()) { Quaternionf rot = new Quaternionf(x.get(), y.get(), z.get(), w.get()); @@ -984,10 +995,6 @@ public boolean isConstant() { } - private boolean checkNull(ConfigData data) { - return !data.isConstant() || data.get() != null; - } - public ConfigData getEntityType() { return entityType; } diff --git a/core/src/main/java/com/nisovin/magicspells/util/Util.java b/core/src/main/java/com/nisovin/magicspells/util/Util.java index 123a4b707..758fc3238 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/Util.java +++ b/core/src/main/java/com/nisovin/magicspells/util/Util.java @@ -66,20 +66,20 @@ public static Material getMaterial(String name) { return Material.matchMaterial(name); } - // - (level) (duration) (ambient) + // - (amplifier) (duration) (ambient) (particles) (icon) public static PotionEffect buildPotionEffect(String effectString) { String[] data = effectString.split(" "); - PotionEffectType t = PotionEffectHandler.getPotionEffectType(data[0]); + PotionEffectType type = PotionEffectHandler.getPotionEffectType(data[0]); - if (t == null) { + if (type == null) { MagicSpells.error('\'' + data[0] + "' could not be connected to a potion effect type"); return null; } - int level = 0; + int amplifier = 0; if (data.length > 1) { try { - level = Integer.parseInt(data[1]); + amplifier = Integer.parseInt(data[1]); } catch (NumberFormatException ex) { DebugHandler.debugNumberFormat(ex); } @@ -100,7 +100,7 @@ public static PotionEffect buildPotionEffect(String effectString) { boolean icon = data.length > 5 && (BooleanUtils.isYes(data[5]) || data[5].equalsIgnoreCase("icon")); - return new PotionEffect(t, duration, level, ambient, particles, icon); + return new PotionEffect(type, duration, amplifier, ambient, particles, icon); } // - (duration) @@ -145,7 +145,13 @@ public static Color[] getColorsFromString(String str) { return c; } - public static List> getPotionEffects(@Nullable List potionEffectData, @NotNull String internalName, boolean spellPowerAffectsDuration, boolean spellPowerAffectsStrength) { + @Nullable + public static List> getPotionEffects(@Nullable List potionEffectData, @Nullable String internalName) { + return getPotionEffects(potionEffectData, internalName, false, false); + } + + @Nullable + public static List> getPotionEffects(@Nullable List potionEffectData, @Nullable String internalName, boolean spellPowerAffectsDuration, boolean spellPowerAffectsStrength) { if (potionEffectData == null || potionEffectData.isEmpty()) return null; List> potionEffects = new ArrayList<>(); @@ -156,7 +162,7 @@ public static List> getPotionEffects(@Nullable List PotionEffectType type = PotionEffectHandler.getPotionEffectType(data[0]); if (type == null) { - MagicSpells.error("Invalid potion effect string '" + potionEffectString + "' in spell '" + internalName + "'."); + MagicSpells.error("Invalid potion effect string '" + potionEffectString + "'" + (internalName == null ? "" : " in spell '" + internalName + "'.")); continue; } @@ -165,7 +171,7 @@ public static List> getPotionEffects(@Nullable List try { duration = Integer.parseInt(data[1]); } catch (NumberFormatException e) { - MagicSpells.error("Invalid duration '" + duration + "' in potion effect string '" + potionEffectString + "' in spell '" + internalName + "'."); + MagicSpells.error("Invalid duration '" + duration + "' in potion effect string '" + potionEffectString + "'" + (internalName == null ? "" : " in spell '" + internalName + "'.")); continue; } } @@ -175,17 +181,17 @@ public static List> getPotionEffects(@Nullable List try { strength = Integer.parseInt(data[2]); } catch (NumberFormatException e) { - MagicSpells.error("Invalid strength '" + strength + "' in potion effect string '" + potionEffectString + "' in spell '" + internalName + "'."); + MagicSpells.error("Invalid strength '" + strength + "' in potion effect string '" + potionEffectString + "'" + (internalName == null ? "" : " in spell '" + internalName + "'.")); continue; } } - boolean ambient = data.length >= 4 && Boolean.parseBoolean(data[4]); - boolean particles = data.length < 5 || !Boolean.parseBoolean(data[3]); + boolean particles = data.length < 4 || !Boolean.parseBoolean(data[3]); + boolean ambient = data.length >= 5 && Boolean.parseBoolean(data[4]); boolean icon = data.length < 6 || Boolean.parseBoolean(data[5]); if (data.length > 6) - MagicSpells.error("Trailing data found in potion effect string '" + potionEffectString + "' in spell '" + internalName + "'."); + MagicSpells.error("Trailing data found in potion effect string '" + potionEffectString + "'" + (internalName == null ? "" : " in spell '" + internalName + "'.")); if (spellPowerAffectsDuration || spellPowerAffectsStrength) { int finalDuration = duration; diff --git a/core/src/main/java/com/nisovin/magicspells/util/config/ConfigDataUtil.java b/core/src/main/java/com/nisovin/magicspells/util/config/ConfigDataUtil.java index fe32cb6ee..d219665fa 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/config/ConfigDataUtil.java +++ b/core/src/main/java/com/nisovin/magicspells/util/config/ConfigDataUtil.java @@ -606,7 +606,7 @@ public static ConfigData getParticle(@NotNull ConfigurationSection con if (value == null) return data -> def; Particle val = ParticleUtil.getParticle(value); - if (val != null) return ata -> val; + if (val != null) return data -> val; ConfigData supplier = getString(value); if (supplier.isConstant()) return data -> def;