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
5 changes: 4 additions & 1 deletion .github/workflows/pr_comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = `<!-- bot: ${label} -->`;
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});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -14,8 +15,8 @@
@Name("particlecloud")
public class ParticleCloudEffect extends ParticlesEffect {

private ConfigData<Integer> color;
private ConfigData<Integer> duration;
private ConfigData<Integer> waitTime;

private ConfigData<Float> radius;
private ConfigData<Float> yOffset;
Expand All @@ -25,21 +26,29 @@ public class ParticleCloudEffect extends ParticlesEffect {
public void loadFromConfig(ConfigurationSection config) {
super.loadFromConfig(config);

color = ConfigDataUtil.getInteger(config, "color", 0xFF0000);
ConfigData<Integer> 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);
yOffset = ConfigDataUtil.getFloat(config, "y-offset", 0);
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;

Expand All @@ -26,20 +25,21 @@
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 {

private final ConfigData<Vector> relativeOffset;

private final ConfigData<Component> customName;

protected ConfigData<ItemStack> item;
protected ConfigData<Particle> particle;
protected ConfigData<BlockData> blockData;
protected ConfigData<DustOptions> dustOptions;
private final ConfigData<Color> color;
private final ConfigData<ItemStack> item;
private final ConfigData<BlockData> blockData;
private final ConfigData<DustOptions> dustOptions;
private final ConfigData<DustTransition> dustTransition;

private final ConfigData<Particle> particle;

private final ConfigData<Integer> color;
private final ConfigData<Integer> waitTime;
private final ConfigData<Integer> ticksDuration;
private final ConfigData<Integer> durationOnUse;
Expand All @@ -53,7 +53,7 @@ public class ParticleCloudSpell extends TargetedSpell implements TargetedLocatio
private final ConfigData<Boolean> canTargetEntities;
private final ConfigData<Boolean> canTargetLocation;

private final Set<PotionEffect> potionEffects;
private final List<ConfigData<PotionEffect>> potionEffects;

public ParticleCloudSpell(MagicConfig config, String spellName) {
super(config, spellName);
Expand All @@ -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> 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> material = getConfigDataMaterial("material", null);
if (material.isConstant()) {
Expand All @@ -80,7 +88,10 @@ public ParticleCloudSpell(MagicConfig config, String spellName) {
};
}

color = getConfigDataInt("color", 0xFF0000);
ConfigData<Integer> 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);
Expand All @@ -94,28 +105,7 @@ public ParticleCloudSpell(MagicConfig config, String spellName) {
canTargetEntities = getConfigDataBoolean("can-target-entities", true);
canTargetLocation = getConfigDataBoolean("can-target-location", true);

List<String> 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
Expand All @@ -127,39 +117,30 @@ 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<Location> 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);
}

@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
Expand All @@ -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));
Expand All @@ -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<PotionEffect> 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) {
Expand All @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -42,6 +41,7 @@ public class ReplaceSpell extends TargetedSpell implements TargetedLocationSpell

private final ConfigData<Boolean> pointBlank;
private final ConfigData<Boolean> checkPlugins;
private final ConfigData<Boolean> applyPhysics;
private final ConfigData<Boolean> replaceRandom;
private final ConfigData<Boolean> powerAffectsRadius;
private final ConfigData<Boolean> resolveDurationPerBlock;
Expand All @@ -62,8 +62,9 @@ public ReplaceSpell(MagicConfig config, String spellName) {

pointBlank = getConfigDataBoolean("point-blank", false);
checkPlugins = getConfigDataBoolean("check-plugins", true);
ConfigData<Boolean> replaceRandom = getConfigDataBoolean("replace-random", true);
applyPhysics = getConfigDataBoolean("apply-physics", true);
powerAffectsRadius = getConfigDataBoolean("power-affects-radius", false);
ConfigData<Boolean> replaceRandom = getConfigDataBoolean("replace-random", true);
resolveDurationPerBlock = getConfigDataBoolean("resolve-duration-per-block", false);

boolean replaceAll = false;
Expand Down Expand Up @@ -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);

Expand All @@ -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();
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
Loading