package com.nisovin.magicspells.spells;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.nisovin.magicspells.MagicSpells;
import com.nisovin.magicspells.Spell;
import com.nisovin.magicspells.Subspell;
import com.nisovin.magicspells.spelleffects.EffectPosition;
import com.nisovin.magicspells.util.MagicConfig;
public final class MultiSpell extends InstantSpell {
private boolean castWithItem;
private boolean castByCommand;
private boolean checkIndividualCooldowns;
private boolean castRandomSpellInstead;
private List<String> spellList;
private ArrayList<Action> actions;
private Random random = new Random();
public MultiSpell(MagicConfig config, String spellName) {
super(config, spellName);
castWithItem = getConfigBoolean("can-cast-with-item", true);
castByCommand = getConfigBoolean("can-cast-by-command", true);
checkIndividualCooldowns = getConfigBoolean("check-individual-cooldowns", false);
castRandomSpellInstead = getConfigBoolean("cast-random-spell-instead", false);
actions = new ArrayList<Action>();
spellList = getConfigStringList("spells", null);
}
@Override
public void initialize() {
super.initialize();
if (spellList != null) {
for (String s : spellList) {
if (s.matches("DELAY [0-9]+")) {
int delay = Integer.parseInt(s.split(" ")[1]);
actions.add(new Action(delay));
} else {
Subspell spell = new Subspell(s);
if (spell.process()) {
actions.add(new Action(spell));
} else {
MagicSpells.error("No such spell '" + s + "' for multi-spell '" + internalName + "'");
}
}
}
}
spellList = null;
}
@Override
public PostCastAction castSpell(Player player, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
if (!castRandomSpellInstead) {
// check cooldowns
if (checkIndividualCooldowns) {
for (Action action : actions) {
if (action.isSpell()) {
if (action.getSpell().getSpell().onCooldown(player)) {
// a spell is on cooldown
sendMessage(player, strOnCooldown);
return PostCastAction.ALREADY_HANDLED;
}
}
}
}
// cast/schedule spells
int delay = 0;
Subspell spell;
for (Action action : actions) {
if (action.isDelay()) {
delay += action.getDelay();
} else if (action.isSpell()) {
spell = action.getSpell();
if (delay == 0) {
spell.cast(player, power);
} else {
Bukkit.getScheduler().scheduleSyncDelayedTask(MagicSpells.plugin, new DelayedSpell(spell, player, power), delay);
}
}
}
} else {
// random spell
List<Action> list;
if (checkIndividualCooldowns) {
list = new ArrayList<Action>();
for (Action a : actions) {
if (a.isSpell() && !a.getSpell().getSpell().onCooldown(player)) {
list.add(a);
}
}
} else {
list = actions;
}
if (list.size() > 0) {
Action action = list.get(random.nextInt(list.size()));
if (action.isSpell()) {
action.getSpell().cast(player, power);
}
} else {
return PostCastAction.ALREADY_HANDLED;
}
}
playSpellEffects(EffectPosition.CASTER, player);
}
return PostCastAction.HANDLE_NORMALLY;
}
@Override
public boolean castFromConsole(final CommandSender sender, final String[] args) {
if (!castRandomSpellInstead) {
int delay = 0;
for (Action action : actions) {
if (action.isSpell()) {
if (delay == 0) {
action.getSpell().getSpell().castFromConsole(sender, args);
} else {
final Spell spell = action.getSpell().getSpell();
MagicSpells.scheduleDelayedTask(new Runnable() {
public void run() {
spell.castFromConsole(sender, args);
}
}, delay);
}
} else if (action.isDelay()) {
delay += action.getDelay();
}
}
} else {
Action action = actions.get(random.nextInt(actions.size()));
if (action.isSpell()) {
action.getSpell().getSpell().castFromConsole(sender, args);
}
}
return true;
}
@Override
public boolean canCastWithItem() {
return castWithItem;
}
@Override
public boolean canCastByCommand() {
return castByCommand;
}
private class Action {
private Subspell spell;
private int delay;
public Action(Subspell spell) {
this.spell = spell;
this.delay = 0;
}
public Action(int delay) {
this.delay = delay;
this.spell = null;
}
public boolean isSpell() {
return spell != null;
}
public Subspell getSpell() {
return spell;
}
public boolean isDelay() {
return delay > 0;
}
public int getDelay() {
return delay;
}
}
private class DelayedSpell implements Runnable {
private Subspell spell;
private String playerName;
private float power;
public DelayedSpell(Subspell spell, Player player, float power) {
this.spell = spell;
this.playerName = player.getName();
this.power = power;
}
@Override
public void run() {
Player player = Bukkit.getPlayerExact(playerName);
if (player != null && player.isValid()) {
spell.cast(player, power);
}
}
}
}