Skip to content
Permalink
Browse files

Add support for particles that require additional data in Area Effect…

… Clouds.

Make particle data creation more forgiving.
  • Loading branch information
PseudoKnight committed Nov 17, 2019
1 parent 01e37d4 commit e614b254f3bb48a981e3ebbbbbcb48ed213f75a0
@@ -18,6 +18,8 @@

boolean isBlock();

boolean isItem();

boolean isBurnable();

boolean isEdible();
@@ -63,6 +63,7 @@
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.exceptions.CRE.CREFormatException;
import org.bukkit.Chunk;
import org.bukkit.Color;
import org.bukkit.Effect;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
@@ -126,6 +127,7 @@
import org.bukkit.entity.Zombie;
import org.bukkit.entity.ZombieHorse;
import org.bukkit.entity.ZombieVillager;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.util.Consumer;

@@ -339,18 +341,38 @@ public void playEffect(MCLocation l, MCEffect mCEffect, int data, int radius) {
public void spawnParticle(MCLocation l, MCParticle pa, int count, double offsetX, double offsetY, double offsetZ, double velocity, Object data) {
Particle type = (Particle) pa.getConcrete();
Location loc = (Location) l.getHandle();
if(data != null) {
if(data instanceof MCItemStack) {
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, ((MCItemStack) data).getHandle());
} else if(data instanceof MCBlockData) {
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, ((MCBlockData) data).getHandle());
} else if(data instanceof MCColor) {
Particle.DustOptions color = new Particle.DustOptions(BukkitMCColor.GetColor((MCColor) data), 1.0F);
switch(type) {
case BLOCK_DUST:
case BLOCK_CRACK:
case FALLING_DUST:
BlockData bd;
if(data instanceof MCBlockData) {
bd = (BlockData) ((MCBlockData) data).getHandle();
} else {
bd = Material.STONE.createBlockData();
}
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, bd);
return;
case ITEM_CRACK:
ItemStack is;
if(data instanceof MCItemStack) {
is = (ItemStack) ((MCItemStack) data).getHandle();
} else {
is = new ItemStack(Material.STONE, 1);
}
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, is);
return;
case REDSTONE:
Particle.DustOptions color;
if(data instanceof MCColor) {
color = new Particle.DustOptions(BukkitMCColor.GetColor((MCColor) data), 1.0F);
} else {
color = new Particle.DustOptions(Color.RED, 1.0F);
}
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, color);
}
} else {
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity);
return;
}
w.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity);
}

@Override
@@ -47,6 +47,11 @@ public boolean isBlock() {
return m.isBlock();
}

@Override
public boolean isItem() {
return m.isItem();
}

@Override
public boolean isBurnable() {
return m.isBurnable();
@@ -1,9 +1,11 @@
package com.laytonsmith.abstraction.bukkit.entities;

import com.laytonsmith.abstraction.MCColor;
import com.laytonsmith.abstraction.MCItemStack;
import com.laytonsmith.abstraction.MCLivingEntity;
import com.laytonsmith.abstraction.MCPotionData;
import com.laytonsmith.abstraction.MCProjectileSource;
import com.laytonsmith.abstraction.blocks.MCBlockData;
import com.laytonsmith.abstraction.blocks.MCBlockProjectileSource;
import com.laytonsmith.abstraction.bukkit.BukkitConvertor;
import com.laytonsmith.abstraction.bukkit.BukkitMCColor;
@@ -13,8 +15,12 @@
import com.laytonsmith.abstraction.enums.MCParticle;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCParticle;
import com.laytonsmith.abstraction.enums.bukkit.BukkitMCPotionEffectType;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@@ -136,8 +142,35 @@ public void setDurationOnUse(int ticks) {
}

@Override
public void setParticle(MCParticle particle) {
aec.setParticle(((BukkitMCParticle) particle).getConcrete());
public void setParticle(MCParticle particle, Object data) {
Particle type = ((BukkitMCParticle) particle).getConcrete();
switch(type) {
case BLOCK_DUST:
case BLOCK_CRACK:
case FALLING_DUST:
if(data instanceof MCBlockData) {
aec.setParticle(type, ((MCBlockData) data).getHandle());
} else {
aec.setParticle(type, Material.STONE.createBlockData());
}
return;
case ITEM_CRACK:
if(data instanceof MCItemStack) {
aec.setParticle(type, ((MCItemStack) data).getHandle());
} else {
aec.setParticle(type, new ItemStack(Material.STONE, 1));
}
return;
case REDSTONE:
if(data instanceof MCColor) {
Particle.DustOptions color = new Particle.DustOptions(BukkitMCColor.GetColor((MCColor) data), 1.0F);
aec.setParticle(type, color);
} else {
aec.setParticle(type, new Particle.DustOptions(Color.RED, 1.0F));
}
return;
}
aec.setParticle(type);
}

@Override
@@ -36,6 +36,7 @@
import com.laytonsmith.commandhelper.CommandHelperPlugin;
import com.laytonsmith.core.Static;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Note;
@@ -555,18 +556,38 @@ public void stopSound(String sound, MCSoundCategory category) {
public void spawnParticle(MCLocation l, MCParticle pa, int count, double offsetX, double offsetY, double offsetZ, double velocity, Object data) {
Particle type = (Particle) pa.getConcrete();
Location loc = (Location) l.getHandle();
if(data != null) {
if(data instanceof MCItemStack) {
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, ((MCItemStack) data).getHandle());
} else if(data instanceof MCBlockData) {
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, ((MCBlockData) data).getHandle());
} else if(data instanceof MCColor) {
Particle.DustOptions color = new Particle.DustOptions(BukkitMCColor.GetColor((MCColor) data), 1.0F);
switch(type) {
case BLOCK_DUST:
case BLOCK_CRACK:
case FALLING_DUST:
BlockData bd;
if(data instanceof MCBlockData) {
bd = (BlockData) ((MCBlockData) data).getHandle();
} else {
bd = Material.STONE.createBlockData();
}
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, bd);
return;
case ITEM_CRACK:
ItemStack is;
if(data instanceof MCItemStack) {
is = (ItemStack) ((MCItemStack) data).getHandle();
} else {
is = new ItemStack(Material.STONE, 1);
}
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, is);
return;
case REDSTONE:
Particle.DustOptions color;
if(data instanceof MCColor) {
color = new Particle.DustOptions(BukkitMCColor.GetColor((MCColor) data), 1.0F);
} else {
color = new Particle.DustOptions(Color.RED, 1.0F);
}
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity, color);
}
} else {
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity);
return;
}
p.spawnParticle(type, loc, count, offsetX, offsetY, offsetZ, velocity);
}

@Override
@@ -47,7 +47,7 @@

void setDurationOnUse(int ticks);

void setParticle(MCParticle particle);
void setParticle(MCParticle particle, Object data);

void setRadius(float radius);

@@ -2222,11 +2222,67 @@ public Mixed exec(Target t, Environment environment, Mixed... args) throws Confi
cloud.setDurationOnUse(ArgumentValidation.getInt32(specArray.get(index, t), t));
break;
case entity_spec.KEY_AREAEFFECTCLOUD_PARTICLE:
String particleName = specArray.get(index, t).val();
try {
cloud.setParticle(MCParticle.valueOf(particleName));
} catch (IllegalArgumentException ex) {
throw new CREFormatException("Invalid particle type: " + particleName, t);
if(specArray.get(index, t).isInstanceOf(CArray.TYPE)) {
Object data = null;
CArray pa = (CArray) specArray.get(index, t);
MCParticle p;
try {
p = MCParticle.valueOf(pa.get("particle", t).val().toUpperCase());
} catch (IllegalArgumentException ex) {
throw new CREIllegalArgumentException("Particle name '"
+ pa.get("particle", t).val() + "' is invalid.", t);
}
if(pa.containsKey("block")) {
// BLOCK_DUST, BLOCK_CRACK, FALLING_DUST
String value = pa.get("block", t).val();
MCMaterial mat = StaticLayer.GetMaterial(value);
if(mat != null) {
try {
data = mat.createBlockData();
} catch (IllegalArgumentException ex) {
throw new CREIllegalArgumentException(value + " is not a block.", t);
}
} else {
throw new CREIllegalArgumentException("Could not find material from " + value, t);
}
} else if(pa.containsKey("item")) {
// ITEM_CRACK
Mixed value = pa.get("item", t);
if(value.isInstanceOf(CArray.TYPE)) {
data = ObjectGenerator.GetGenerator().item(pa.get("item", t), t);
} else {
MCMaterial mat = StaticLayer.GetMaterial(value.val());
if(mat != null) {
if(mat.isItem()) {
data = StaticLayer.GetItemStack(mat, 1);
} else {
throw new CREIllegalArgumentException(value + " is not an item type.", t);
}
} else {
throw new CREIllegalArgumentException("Could not find material from " + value, t);
}
}
} else if(pa.containsKey("color")) {
// REDSTONE
Mixed c = pa.get("color", t);
if(c.isInstanceOf(CArray.TYPE)) {
data = ObjectGenerator.GetGenerator().color((CArray) c, t);
} else {
data = StaticLayer.GetConvertor().GetColor(c.val(), t);
}
}
try {
cloud.setParticle(p, data);
} catch (IllegalArgumentException ex) {
throw new CREFormatException("Invalid particle data for " + p.name(), t);
}
} else {
String particleName = specArray.get(index, t).val();
try {
cloud.setParticle(MCParticle.valueOf(particleName), null);
} catch (IllegalArgumentException ex) {
throw new CREFormatException("Invalid particle data: " + particleName, t);
}
}
break;
case entity_spec.KEY_AREAEFFECTCLOUD_POTIONMETA:
@@ -1394,19 +1394,17 @@ public String docs() {
+ " parameter can be one player or an array of players. If none is given, all players within 32"
+ " meters will see the particle. The particle parameter can be a particle name or an associative"
+ " array defining the characteristics of the particle to be spawned. The array requires the"
+ " particle name under the key \"particle\"."
+ " ---- Possible particles: " + StringUtils.Join(MCParticle.types(), ", ", ", or ", " or ")
+ " \n\nSome particles have more specific keys and/or special behavior, but the common keys for the"
+ " particle name under the key \"particle\". ----"
+ " Possible particle types: " + StringUtils.Join(MCParticle.types(), ", ", ", or ", " or ") + ".\n"
+ " Some particles have more specific keys and/or special behavior, but the common keys for the"
+ " particle array are \"count\" (usually the number of particles to be spawned), \"speed\""
+ " (usually the velocity of the particle), \"xoffset\", \"yoffset\", and \"zoffset\""
+ " (usually the ranges from center within which the particle may be offset on that axis)."
+ " The BLOCK_DUST, BLOCK_CRACK and FALLING_DUST particles can take a block type name parameter"
+ " under the key \"block\".\n\n"
+ " The ITEM_CRACK particle can take an item array under the key \"item\".\n\n"
+ " The REDSTONE particle can take a color array (or name)"
+ " under the key \"color\"."
+ " If a block, item or color is provided for a particle type that doesn't support it,"
+ " an IllegalArgumentException will be thrown.";
+ " (usually the ranges from center within which the particle may be offset on that axis).\n"
+ " BLOCK_DUST, BLOCK_CRACK and FALLING_DUST particles can take a block type name parameter"
+ " under the key \"block\" (default: STONE).\n"
+ " ITEM_CRACK particles can take an item array or name under the key \"item\" (default: STONE).\n"
+ " REDSTONE particles take an RGB color array (each 0 - 255) or name under the key \"color\""
+ " (default: RED).";
}

@Override
@@ -1475,7 +1473,21 @@ public Mixed exec(Target t, com.laytonsmith.core.environments.Environment enviro
}

} else if(pa.containsKey("item")) {
data = ObjectGenerator.GetGenerator().item(pa.get("item", t), t);
Mixed value = pa.get("item", t);
if(value.isInstanceOf(CArray.TYPE)) {
data = ObjectGenerator.GetGenerator().item(pa.get("item", t), t);
} else {
MCMaterial mat = StaticLayer.GetMaterial(value.val());
if(mat != null) {
if(mat.isItem()) {
data = StaticLayer.GetItemStack(mat, 1);
} else {
throw new CREIllegalArgumentException(value + " is not an item type.", t);
}
} else {
throw new CREIllegalArgumentException("Could not find material from " + value, t);
}
}

} else if(pa.containsKey("color")) {
Mixed c = pa.get("color", t);
@@ -7,10 +7,12 @@ array {entityID} Returns an associative array containing all the data of the giv
|-
| AREA_EFFECT_CLOUD
|
* %KEY_AREAEFFECTCLOUD_COLOR%: The color array of the particle.
* %KEY_AREAEFFECTCLOUD_COLOR%: The color array of the particle, if applicable (eg. SPELL_MOB particle type).
* %KEY_AREAEFFECTCLOUD_DURATION%: The duration of the cloud in ticks.
* %KEY_AREAEFFECTCLOUD_DURATIONONUSE%: The amount the duration will change when the effects are applied.
* %KEY_AREAEFFECTCLOUD_PARTICLE%: The particle which comprises the cloud (can be %PARTICLE%).
* %KEY_AREAEFFECTCLOUD_PARTICLE%: The particle type which comprises the cloud (can be %PARTICLE%).
Can accept a particle array for setting index data required for specific particle types.
This particle array must contain a "particle" key, and supports the keys "block", "item", or "color" when applicable.
* %KEY_AREAEFFECTCLOUD_POTIONMETA%: An array of potion effect arrays for the cloud.
* %KEY_AREAEFFECTCLOUD_RADIUS%: The radius of the cloud.
* %KEY_AREAEFFECTCLOUD_RADIUSONUSE%: The distance the radius will change when the effects are applied.

0 comments on commit e614b25

Please sign in to comment.
You can’t perform that action at this time.