package net.demilich.metastone.game.spells; import java.util.List; import net.demilich.metastone.game.Environment; import net.demilich.metastone.game.GameContext; import net.demilich.metastone.game.Player; import net.demilich.metastone.game.entities.Entity; import net.demilich.metastone.game.spells.desc.SpellArg; import net.demilich.metastone.game.spells.desc.SpellDesc; import net.demilich.metastone.game.spells.desc.filter.EntityFilter; public abstract class Spell { public void cast(GameContext context, Player player, SpellDesc desc, Entity source, List<Entity> targets) { // no target specified, cast the spell once with target NULL if (targets == null) { castForPlayer(context, player, desc, source, null); return; } EntityFilter targetFilter = desc.getEntityFilter(); List<Entity> validTargets = SpellUtils.getValidTargets(context, player, targets, targetFilter); // there is at least one valid target and the RANDOM_TARGET flag is set, // pick one randomly if (validTargets.size() > 0 && desc.getBool(SpellArg.RANDOM_TARGET)) { Entity target = SpellUtils.getRandomTarget(validTargets); castForPlayer(context, player, desc, source, target); } else { // there is at least one target and RANDOM_TARGET flag is not set, // cast in on all targets for (Entity target : validTargets) { context.getEnvironment().put(Environment.SPELL_TARGET, target.getReference()); castForPlayer(context, player, desc, source, target); context.getEnvironment().remove(Environment.SPELL_TARGET); } } } private void castForPlayer(GameContext context, Player player, SpellDesc desc, Entity source, Entity target) { TargetPlayer targetPlayer = desc.getTargetPlayer(); if (targetPlayer == null) { targetPlayer = TargetPlayer.SELF; } Player opponent = context.getOpponent(player); switch (targetPlayer) { case BOTH: onCast(context, player, desc, source, target); onCast(context, opponent, desc, source, target); break; case OPPONENT: onCast(context, opponent, desc, source, target); break; case SELF: onCast(context, player, desc, source, target); break; case OWNER: onCast(context, context.getPlayer(target.getOwner()), desc, source, target); break; case ACTIVE: onCast(context, context.getActivePlayer(), desc, source, target); break; case INACTIVE: onCast(context, context.getOpponent(context.getActivePlayer()), desc, source, target); break; default: break; } } protected abstract void onCast(GameContext context, Player player, SpellDesc desc, Entity source, Entity target); @Override public String toString() { return "[SPELL " + getClass().getSimpleName() + "]"; } }