use of org.bukkit.configuration.MemoryConfiguration in project MagicPlugin by elBukkit.
the class MagicPlugin method cast.
@Override
public boolean cast(String spellName, String[] parameters, CommandSender sender, Entity entity) {
ConfigurationSection config = null;
if (parameters != null && parameters.length > 0) {
config = new MemoryConfiguration();
ConfigurationUtils.addParameters(parameters, config);
}
return controller.cast(null, spellName, config, sender, entity);
}
use of org.bukkit.configuration.MemoryConfiguration in project MagicPlugin by elBukkit.
the class MagicConfigurableExecutor method onConfigure.
public boolean onConfigure(String command, MagicConfigurable target, CommandSender sender, Player player, String[] parameters, boolean safe) {
if (parameters.length < 1 || (safe && parameters.length < 2)) {
sender.sendMessage("Use: /" + command + " configure <property> [value]");
sender.sendMessage("Properties: " + StringUtils.join(BaseMagicConfigurable.PROPERTY_KEYS, ", "));
return true;
}
Mage mage = controller.getMage(player);
String value = "";
for (int i = 1; i < parameters.length; i++) {
if (i != 1)
value = value + " ";
value = value + parameters[i];
}
if (value.isEmpty()) {
value = null;
} else if (value.equals("\"\"")) {
value = "";
}
if (value != null) {
value = value.replace("\\n", "\n");
}
boolean modified = false;
if (value == null) {
if (target.removeProperty(parameters[0])) {
modified = true;
mage.sendMessage(api.getMessages().get(command + ".removed_property").replace("$name", parameters[0]));
} else {
mage.sendMessage(api.getMessages().get(command + ".no_property").replace("$name", parameters[0]));
}
} else {
ConfigurationSection node = new MemoryConfiguration();
double transformed = Double.NaN;
try {
transformed = Double.parseDouble(value);
} catch (Exception ex) {
EquationTransform transform = EquationStore.getInstance().getTransform(value);
if (transform.getException() == null) {
double property = target.getProperty(parameters[0], Double.NaN);
if (!Double.isNaN(property)) {
transform.setVariable("x", property);
transformed = transform.get();
}
}
}
if (!Double.isNaN(transformed)) {
node.set(parameters[0], transformed);
} else {
node.set(parameters[0], value);
}
if (safe) {
modified = target.upgrade(node);
} else {
target.configure(node);
modified = true;
}
if (modified) {
mage.sendMessage(api.getMessages().get(command + ".reconfigured"));
} else {
mage.sendMessage(api.getMessages().get(command + ".not_reconfigured"));
}
}
if (sender != player) {
if (modified) {
sender.sendMessage(api.getMessages().getParameterized(command + ".player_reconfigured", "$name", player.getName()));
} else {
sender.sendMessage(api.getMessages().getParameterized(command + ".player_not_reconfigured", "$name", player.getName()));
}
}
return true;
}
use of org.bukkit.configuration.MemoryConfiguration in project MagicPlugin by elBukkit.
the class HeroesSpellSkill method use.
@Override
public SkillResult use(Hero hero, String[] strings) {
Mage mage = controller.getMage(hero.getPlayer());
boolean success = false;
{
String spellKey = spellTemplate.getKey();
int targetLevel = SkillConfigManager.getUseSetting(hero, this, "tier", spellLevel, true);
if (targetLevel != 1) {
SpellKey key = new SpellKey(spellTemplate.getSpellKey().getBaseKey(), targetLevel);
spellKey = key.getKey();
}
Spell spell = mage.getSpell(spellKey);
if (spell == null) {
if (targetLevel > 1) {
controller.getLogger().warning("Invalid tier for spell in skills config: " + spellKey + " (tier " + spellLevel + ")");
} else {
controller.getLogger().warning("Invalid spell in skills config: " + spellKey);
}
return SkillResult.FAIL;
}
Set<String> parameterKeys = parameters.getKeys(false);
ConfigurationSection spellParameters = spellTemplate.getSpellParameters();
ConfigurationSection heroParameters = new MemoryConfiguration();
for (String parameterKey : parameterKeys) {
String value = parameters.getString(parameterKey);
String magicKey = heroesToMagic(parameterKey);
Double doubleValue = null;
try {
doubleValue = Double.parseDouble(value);
} catch (NumberFormatException ignored) {
}
Object magicValue = spellParameters.getString(magicKey);
if (doubleValue != null) {
doubleValue = SkillConfigManager.getUseSetting(hero, this, parameterKey, doubleValue, true);
Double doubleMagicValue = null;
try {
if (magicValue != null) {
doubleMagicValue = Double.parseDouble(magicValue.toString());
}
} catch (NumberFormatException ignored) {
}
if (doubleMagicValue != null && doubleValue.equals(doubleMagicValue))
continue;
} else {
value = SkillConfigManager.getUseSetting(hero, this, parameterKey, value);
if (magicValue != null && value != null && value.equals(magicValue))
continue;
}
if (doubleValue != null) {
heroParameters.set(magicKey, doubleValue);
} else {
heroParameters.set(magicKey, value);
}
}
// Don't let Magic get in the way of using the skill
heroParameters.set("cost_reduction", 2);
heroParameters.set("cooldown_reduction", 2);
success = spell.cast(heroParameters);
}
if (success) {
this.broadcastExecuteText(hero);
}
return success ? SkillResult.NORMAL : SkillResult.FAIL;
}
use of org.bukkit.configuration.MemoryConfiguration in project MagicPlugin by elBukkit.
the class Wand method loadProperties.
@Override
public void loadProperties() {
super.loadProperties();
locked = getBoolean("locked", locked);
lockedAllowUpgrades = getBoolean("locked_allow_upgrades", false);
consumeReduction = getFloat("consume_reduction");
cooldownReduction = getFloat("cooldown_reduction");
costReduction = getFloat("cost_reduction");
power = getFloat("power");
ConfigurationSection protectionConfig = getConfigurationSection("protection");
if (protectionConfig == null && hasProperty("protection")) {
migrateProtection("protection", "overall");
migrateProtection("protection_physical", "physical");
migrateProtection("protection_projectiles", "projectile");
migrateProtection("protection_falling", "fall");
migrateProtection("protection_fire", "fire");
migrateProtection("protection_explosions", "explosion");
protectionConfig = getConfigurationSection("protection");
}
if (protectionConfig != null) {
protection = new HashMap<>();
for (String protectionKey : protectionConfig.getKeys(false)) {
protection.put(protectionKey, protectionConfig.getDouble(protectionKey));
}
}
hasId = getBoolean("unique", false);
blockChance = getFloat("block_chance");
blockReflectChance = getFloat("block_reflect_chance");
blockFOV = getFloat("block_fov");
blockMageCooldown = getInt("block_mage_cooldown");
blockCooldown = getInt("block_cooldown");
manaPerDamage = getFloat("mana_per_damage");
spMultiplier = getFloat("sp_multiplier", 1);
String singleClass = getString("class");
if (singleClass != null && !singleClass.isEmpty()) {
mageClassKeys = new ArrayList<>();
mageClassKeys.add(singleClass);
} else {
mageClassKeys = getStringList("classes");
}
// Check for single-use wands
uses = getInt("uses");
hasUses = uses > 0;
// Convert some legacy properties to potion effects
float healthRegeneration = getFloat("health_regeneration", 0);
float hungerRegeneration = getFloat("hunger_regeneration", 0);
float speedIncrease = getFloat("haste", 0);
if (speedIncrease > 0) {
potionEffects.put(PotionEffectType.SPEED, 1);
}
if (healthRegeneration > 0) {
potionEffects.put(PotionEffectType.REGENERATION, 1);
}
if (hungerRegeneration > 0) {
potionEffects.put(PotionEffectType.SATURATION, 1);
}
// This overrides the value loaded in CasterProperties
if (!regenWhileInactive) {
setProperty("mana_timestamp", System.currentTimeMillis());
}
if (hasProperty("effect_color")) {
setEffectColor(getString("effect_color"));
}
id = getString("id");
isUpgrade = getBoolean("upgrade");
quietLevel = getInt("quiet");
effectBubbles = getBoolean("effect_bubbles");
keep = getBoolean("keep");
passive = getBoolean("passive");
indestructible = getBoolean("indestructible");
superPowered = getBoolean("powered");
superProtected = getBoolean("protected");
glow = getBoolean("glow");
undroppable = getBoolean("undroppable");
isHeroes = getBoolean("heroes");
bound = getBoolean("bound");
forceUpgrade = getBoolean("force");
autoOrganize = getBoolean("organize");
autoAlphabetize = getBoolean("alphabetize");
autoFill = getBoolean("fill");
rename = getBoolean("rename");
renameDescription = getBoolean("rename_description");
enchantCount = getInt("enchant_count");
maxEnchantCount = getInt("max_enchant_count");
inventoryRows = getInt("inventory_rows", 5);
if (inventoryRows <= 0)
inventoryRows = 1;
if (hasProperty("effect_particle")) {
effectParticle = ConfigurationUtils.toParticleEffect(getString("effect_particle"));
effectParticleData = 0;
} else {
effectParticle = null;
}
if (hasProperty("effect_sound")) {
effectSound = ConfigurationUtils.toSoundEffect(getString("effect_sound"));
} else {
effectSound = null;
}
activeEffectsOnly = getBoolean("active_effects");
effectParticleData = getFloat("effect_particle_data");
effectParticleCount = getInt("effect_particle_count");
effectParticleRadius = getDouble("effect_particle_radius");
effectParticleOffset = getDouble("effect_particle_offset");
effectParticleInterval = getInt("effect_particle_interval");
effectParticleMinVelocity = getDouble("effect_particle_min_velocity");
effectSoundInterval = getInt("effect_sound_interval");
castLocation = getVector("cast_location");
castInterval = getInt("cast_interval");
castMinVelocity = getDouble("cast_min_velocity");
castVelocityDirection = getVector("cast_velocity_direction");
castSpell = getString("cast_spell");
String castParameterString = getString("cast_parameters", null);
if (castParameterString != null && !castParameterString.isEmpty()) {
castParameters = new MemoryConfiguration();
ConfigurationUtils.addParameters(StringUtils.split(castParameterString, ' '), castParameters);
} else {
castParameters = null;
}
WandMode newMode = parseWandMode(getString("mode"), controller.getDefaultWandMode());
if (newMode != mode) {
if (isInventoryOpen()) {
closeInventory();
}
mode = newMode;
}
brushMode = parseWandMode(getString("brush_mode"), controller.getDefaultBrushMode());
// Backwards compatibility
if (getBoolean("mode_drop", false)) {
dropAction = WandAction.TOGGLE;
swapAction = WandAction.CYCLE_HOTBAR;
rightClickAction = WandAction.NONE;
quickCast = true;
// This is to turn the redundant spell lore off
quickCastDisabled = true;
manualQuickCastDisabled = false;
} else if (mode == WandMode.CAST) {
leftClickAction = WandAction.CAST;
rightClickAction = WandAction.CAST;
swapAction = WandAction.NONE;
dropAction = WandAction.NONE;
} else if (mode == WandMode.CYCLE) {
leftClickAction = WandAction.CAST;
rightClickAction = WandAction.NONE;
swapAction = WandAction.NONE;
dropAction = WandAction.CYCLE;
} else {
leftClickAction = WandAction.NONE;
rightClickAction = WandAction.NONE;
dropAction = WandAction.NONE;
swapAction = WandAction.NONE;
quickCast = false;
quickCastDisabled = false;
manualQuickCastDisabled = false;
}
String quickCastType = getString("quick_cast", getString("mode_cast"));
if (quickCastType != null) {
if (quickCastType.equalsIgnoreCase("true")) {
quickCast = true;
// This is to turn the redundant spell lore off
quickCastDisabled = true;
manualQuickCastDisabled = false;
} else if (quickCastType.equalsIgnoreCase("manual")) {
quickCast = false;
quickCastDisabled = true;
manualQuickCastDisabled = false;
} else if (quickCastType.equalsIgnoreCase("disable")) {
quickCast = false;
quickCastDisabled = true;
manualQuickCastDisabled = true;
} else {
quickCast = false;
quickCastDisabled = false;
manualQuickCastDisabled = false;
}
}
leftClickAction = parseWandAction(getString("left_click"), leftClickAction);
rightClickAction = parseWandAction(getString("right_click"), rightClickAction);
dropAction = parseWandAction(getString("drop"), dropAction);
swapAction = parseWandAction(getString("swap"), swapAction);
owner = getString("owner");
ownerId = getString("owner_id");
template = getString("template");
upgradeTemplate = getString("upgrade_template");
path = getString("path");
activeSpell = getString("active_spell");
if (activeSpell != null && activeSpell.contains("|")) {
SpellKey activeKey = new SpellKey(activeSpell);
activeSpell = activeKey.getBaseKey();
setProperty("active_spell", activeSpell);
}
alternateSpell = getString("alternate_spell");
alternateSpell2 = getString("alternate_spell2");
activeBrush = getString("active_brush", getString("active_material"));
if (hasProperty("hotbar")) {
currentHotbar = getInt("hotbar");
}
if (hasProperty("page")) {
int page = getInt("page");
if (page != openInventoryPage) {
openInventoryPage = page;
}
}
// Default to template names, override with localizations and finally with wand data
wandName = controller.getMessages().get("wand.default_name");
description = "";
// Check for migration information in the template config
ConfigurationSection templateConfig = null;
if (template != null && !template.isEmpty()) {
templateConfig = controller.getWandTemplateConfiguration(template);
if (templateConfig != null) {
wandName = templateConfig.getString("name", wandName);
description = templateConfig.getString("description", description);
int templateUses = templateConfig.getInt("uses");
isSingleUse = templateUses == 1;
hasUses = hasUses || templateUses > 0;
}
wandName = controller.getMessages().get("wands." + template + ".name", wandName);
description = controller.getMessages().get("wands." + template + ".description", description);
}
wandName = getString("name", wandName);
description = getString("description", description);
WandTemplate wandTemplate = getTemplate();
// Add vanilla attributes
InventoryUtils.applyAttributes(item, getConfigurationSection("item_attributes"), getString("item_attribute_slot", getString("attribute_slot")));
// Add unstashable and unmoveable tags
if (getBoolean("unstashable") || (undroppable && Unstashable)) {
InventoryUtils.setMetaBoolean(item, "unstashable", true);
} else {
InventoryUtils.removeMeta(item, "unstashable");
}
if (getBoolean("unmoveable")) {
InventoryUtils.setMetaBoolean(item, "unmoveable", true);
} else {
InventoryUtils.removeMeta(item, "unmoveable");
}
if (undroppable) {
InventoryUtils.setMetaBoolean(item, "undroppable", true);
} else {
InventoryUtils.removeMeta(item, "undroppable");
}
if (keep) {
InventoryUtils.setMetaBoolean(item, "keep", true);
} else {
InventoryUtils.removeMeta(item, "keep");
}
// Add vanilla enchantments
ConfigurationSection enchantments = getConfigurationSection("enchantments");
InventoryUtils.applyEnchantments(item, enchantments);
// Add enchantment glow
if (enchantments == null || enchantments.getKeys(false).isEmpty()) {
if (glow) {
CompatibilityUtils.addGlow(item);
} else {
CompatibilityUtils.removeGlow(item);
}
}
if (hasProperty("icon_inactive")) {
String iconKey = getString("icon_inactive");
if (wandTemplate != null) {
iconKey = wandTemplate.migrateIcon(iconKey);
}
if (iconKey != null) {
inactiveIcon = new MaterialAndData(iconKey);
}
} else {
inactiveIcon = null;
}
if (inactiveIcon != null && (inactiveIcon.getMaterial() == null || inactiveIcon.getMaterial() == Material.AIR)) {
inactiveIcon = null;
}
inactiveIconDelay = getInt("icon_inactive_delay");
randomizeOnActivate = randomizeOnActivate && hasProperty("randomize_icon");
if (randomizeOnActivate) {
String randomizeIcon = getString("randomize_icon");
setIcon(new MaterialAndData(randomizeIcon));
if (item == null) {
controller.getLogger().warning("Invalid randomize_icon in wand '" + template + "' config: " + randomizeIcon);
}
} else if (hasProperty("icon")) {
String iconKey = getString("icon");
if (wandTemplate != null) {
iconKey = wandTemplate.migrateIcon(iconKey);
}
if (iconKey.contains(",")) {
Random r = new Random();
String[] keys = StringUtils.split(iconKey, ',');
iconKey = keys[r.nextInt(keys.length)];
}
// Port old custom wand icons
if (templateConfig != null && iconKey.contains("i.imgur.com")) {
iconKey = templateConfig.getString("icon");
}
setIcon(new MaterialAndData(iconKey));
if (item == null) {
controller.getLogger().warning("Invalid icon in wand '" + template + "' config: " + iconKey);
}
updateIcon();
} else if (isUpgrade) {
setIcon(new MaterialAndData(DefaultUpgradeMaterial));
} else {
setIcon(new MaterialAndData(DefaultWandMaterial));
}
if (hasProperty("upgrade_icon")) {
upgradeIcon = new MaterialAndData(getString("upgrade_icon"));
}
// Check for path-based migration, may update icons
com.elmakers.mine.bukkit.api.wand.WandUpgradePath upgradePath = getPath();
if (upgradePath != null) {
hasSpellProgression = upgradePath.getSpells().size() > 0 || upgradePath.getExtraSpells().size() > 0 || upgradePath.getRequiredSpells().size() > 0;
upgradePath.checkMigration(this);
} else {
hasSpellProgression = false;
}
if (isHeroes) {
hasSpellProgression = true;
}
brushInventory.clear();
spellInventory.clear();
limitSpellsToPath = getBoolean("limit_spells_to_path");
limitBrushesToPath = getBoolean("limit_brushes_to_path");
loadSpells();
// Load spell levels
Object spellLevelsRaw = getObject("spell_levels");
if (spellLevelsRaw != null) {
// Not sure this will ever appear as a Map, but just in case
if (spellLevelsRaw instanceof Map) {
@SuppressWarnings("unchecked") Map<String, Integer> spellLevels = (Map<String, Integer>) spellLevelsRaw;
loadSpellLevels(spellLevels);
} else if (spellLevelsRaw instanceof ConfigurationSection) {
loadSpellLevels(NMSUtils.getMap((ConfigurationSection) spellLevelsRaw));
}
}
checkActiveSpell();
loadBrushes();
Object brushInventoryRaw = getObject("brush_inventory");
if (brushInventoryRaw != null) {
// Not sure this will ever appear as a Map, but just in case
if (brushInventoryRaw instanceof Map) {
@SuppressWarnings("unchecked") Map<String, Integer> brushInventory = (Map<String, Integer>) brushInventoryRaw;
loadBrushInventory(brushInventory);
} else if (brushInventoryRaw instanceof ConfigurationSection) {
loadBrushInventory(NMSUtils.getMap((ConfigurationSection) brushInventoryRaw));
}
}
Object spellInventoryRaw = getObject("spell_inventory");
if (spellInventoryRaw != null) {
// Not sure this will ever appear as a Map, but just in case
if (spellInventoryRaw instanceof Map) {
@SuppressWarnings("unchecked") Map<String, Integer> spellInventory = (Map<String, Integer>) spellInventoryRaw;
loadSpellInventory(spellInventory);
} else if (spellInventoryRaw instanceof ConfigurationSection) {
loadSpellInventory(NMSUtils.getMap((ConfigurationSection) spellInventoryRaw));
}
} else {
// Spells may have contained an inventory from migration or templates with a spell@slot format.
updateSpellInventory();
}
castOverrides = null;
if (hasProperty("overrides")) {
castOverrides = null;
Object overridesGeneric = getObject("overrides");
if (overridesGeneric != null) {
castOverrides = new HashMap<>();
if (overridesGeneric instanceof String) {
String overrides = (String) overridesGeneric;
if (!overrides.isEmpty()) {
// Support YML-List-As-String format
// May not really need this anymore.
overrides = overrides.replaceAll("[\\]\\[]", "");
String[] pairs = StringUtils.split(overrides, ',');
for (String override : pairs) {
parseOverride(override);
}
}
} else if (overridesGeneric instanceof List) {
@SuppressWarnings("unchecked") List<String> overrideList = (List<String>) overridesGeneric;
for (String override : overrideList) {
parseOverride(override);
}
} else if (overridesGeneric instanceof ConfigurationSection) {
ConfigurationSection overridesSection = (ConfigurationSection) overridesGeneric;
Set<String> keys = overridesSection.getKeys(true);
for (String key : keys) {
Object leaf = overridesSection.get(key);
if (!(leaf instanceof ConfigurationSection) && !(leaf instanceof Map)) {
castOverrides.put(key, leaf.toString());
}
}
}
}
}
potionEffects.clear();
if (hasProperty("potion_effects")) {
addPotionEffects(potionEffects, getString("potion_effects", null));
}
// so try to keep defaults as 0/0.0/false.
if (effectSound == null) {
effectSoundInterval = 0;
} else {
effectSoundInterval = (effectSoundInterval == 0) ? 5 : effectSoundInterval;
}
if (effectParticle == null) {
effectParticleInterval = 0;
}
checkActiveMaterial();
}
use of org.bukkit.configuration.MemoryConfiguration in project MagicPlugin by elBukkit.
the class Wand method updateEffects.
public void updateEffects(Mage mage) {
if (mage == null)
return;
Player player = mage.getPlayer();
if (player == null)
return;
// Update Bubble effects effects
if (effectBubbles && effectColor != null) {
Location potionEffectLocation = player.getLocation();
potionEffectLocation.setX(potionEffectLocation.getX() + random.nextDouble() - 0.5);
potionEffectLocation.setY(potionEffectLocation.getY() + random.nextDouble() * player.getEyeHeight());
potionEffectLocation.setZ(potionEffectLocation.getZ() + random.nextDouble() - 0.5);
ParticleEffect.SPELL_MOB.display(potionEffectLocation, effectColor.getColor(), 24);
}
Location location = mage.getLocation();
long now = System.currentTimeMillis();
boolean playEffects = !activeEffectsOnly || inventoryIsOpen || isInOffhand;
if (playEffects && effectParticle != null && effectParticleInterval > 0 && effectParticleCount > 0) {
boolean velocityCheck = true;
if (effectParticleMinVelocity > 0) {
double velocitySquared = effectParticleMinVelocity * effectParticleMinVelocity;
Vector velocity = mage.getVelocity().clone();
velocity.setY(0);
double speedSquared = velocity.lengthSquared();
velocityCheck = (speedSquared > velocitySquared);
}
if (velocityCheck && (lastParticleEffect == 0 || now > lastParticleEffect + effectParticleInterval)) {
lastParticleEffect = now;
Location effectLocation = player.getLocation();
Location eyeLocation = player.getEyeLocation();
effectLocation.setY(eyeLocation.getY() + effectParticleOffset);
if (effectPlayer == null) {
effectPlayer = new EffectRing(controller.getPlugin());
effectPlayer.setParticleCount(1);
effectPlayer.setIterations(1);
effectPlayer.setParticleOffset(0, 0, 0);
}
effectPlayer.setMaterial(location.getBlock().getRelative(BlockFace.DOWN));
if (effectParticleData == 0) {
effectPlayer.setColor(getEffectColor());
} else {
effectPlayer.setColor(null);
}
effectPlayer.setParticleType(effectParticle);
effectPlayer.setParticleData(effectParticleData);
effectPlayer.setSize(effectParticleCount);
effectPlayer.setRadius((float) effectParticleRadius);
effectPlayer.start(effectLocation, null);
}
}
if (castSpell != null && castInterval > 0) {
if (lastSpellCast == 0 || now > lastSpellCast + castInterval) {
boolean velocityCheck = true;
if (castMinVelocity > 0) {
double velocitySquared = castMinVelocity * castMinVelocity;
Vector velocity = mage.getVelocity();
if (castVelocityDirection != null) {
velocity = velocity.clone().multiply(castVelocityDirection);
// This is kind of a hack to make jump-detection work.
if (castVelocityDirection.getY() < 0) {
velocityCheck = velocity.getY() < 0;
} else {
velocityCheck = velocity.getY() > 0;
}
}
if (velocityCheck) {
double speedSquared = velocity.lengthSquared();
velocityCheck = (speedSquared > velocitySquared);
}
}
if (velocityCheck) {
lastSpellCast = now;
Spell spell = mage.getSpell(castSpell);
if (spell != null) {
if (castParameters == null) {
castParameters = new MemoryConfiguration();
}
castParameters.set("passive", true);
mage.setCostFree(true);
mage.setQuiet(true);
try {
spell.cast(castParameters);
} catch (Exception ex) {
controller.getLogger().log(Level.WARNING, "Error casting aura spell " + spell.getKey(), ex);
}
mage.setCostFree(false);
mage.setQuiet(false);
}
}
}
}
if (playEffects && effectSound != null && controller.soundsEnabled() && effectSoundInterval > 0) {
if (lastSoundEffect == 0 || now > lastSoundEffect + effectSoundInterval) {
lastSoundEffect = now;
effectSound.play(controller.getPlugin(), mage.getPlayer());
}
}
}
Aggregations