/** Causes all combat spells to expire */
  public void expireCombatSpells() {
    // Expire the spells, one at a time
    for (SpellWrapper spell : getSpells(COMBAT_SPELLS)) {
      spell.expireSpell();
    }

    // Clear the combat spell list
    setBoolean(COMBAT_SPELLS, false);
  }
  /** Causes all day spells to expire */
  public void expireDaySpells() {
    // Expire the spells, one at a time
    for (SpellWrapper spell : getSpells(DAY_SPELLS)) {
      spell.expireSpell();
    }

    // Clear the day spell list
    setBoolean(DAY_SPELLS, false);
  }
 public void removeSpell(SpellWrapper spell) {
   String duration = spell.getGameObject().getThisAttribute("duration");
   ArrayList list = getList(duration);
   if (list != null && list.contains(spell.getGameObject().getStringId())) {
     list = new ArrayList(list);
     list.remove(spell.getGameObject().getStringId());
     setList(duration, list);
   }
 }
 /**
  * @param target The target to test
  * @return List of SpellWrapper objects that are currently bewitching the target
  */
 public ArrayList<SpellWrapper> getAffectingSpells(GameObject target) {
   ArrayList<SpellWrapper> ret = new ArrayList<SpellWrapper>();
   for (SpellWrapper spell : getSpells(null)) {
     if (spell.targetsGameObject(target)) {
       ret.add(spell);
     }
   }
   return ret;
 }
 public void restoreBewitchingNullifiedSpells(GameObject target, SpellWrapper exclude) {
   for (SpellWrapper spell : getAffectingSpells(target)) {
     if (exclude == null || !exclude.getGameObject().equals(spell.getGameObject())) {
       if (spell.isNullified()) {
         spell.restoreSpell();
         // System.err.println(spell.getGameObject().getName()+" is restored after nullification");
       }
     }
   }
 }
  /**
   * Causes all phase spells to expire
   *
   * @return true when spells were expired
   */
  public boolean expirePhaseSpells() {
    boolean ret = false;
    // Expire the spells, one at a time
    for (SpellWrapper spell : getSpells(PHASE_SPELLS)) {
      spell.expireSpell();
      ret = true;
    }

    // Clear the phase spell list
    setBoolean(PHASE_SPELLS, false);
    return ret;
  }
  public void expireAllSpells() {
    // Expire the spells, one at a time
    for (SpellWrapper spell : getSpells(null)) {
      spell.expireSpell();
    }

    // Clear all spell lists
    setBoolean(DAY_SPELLS, false);
    setBoolean(COMBAT_SPELLS, false);
    setBoolean(PERMANENT_SPELLS, false);
    setBoolean(PHASE_SPELLS, false);
    setBoolean(MOVE_SPELLS, false);
  }
  private boolean spellCanEnergize(
      GameWrapper game, TileLocation loc, SpellWrapper spell, boolean includeCalendar) {
    RealmCalendar cal = RealmCalendar.getCalendar(game.getGameObject().getGameData());
    ArrayList infiniteSources = new ArrayList();
    if (loc.isInClearing()) {
      infiniteSources.addAll(loc.clearing.getAllSourcesOfColor(true));
    } else if (loc.isBetweenClearings()) {
      infiniteSources.addAll(loc.clearing.getAllSourcesOfColor(true));
      infiniteSources.addAll(loc.getOther().clearing.getAllSourcesOfColor(true));
    } else if (loc.isTileOnly()) {
      infiniteSources.addAll(loc.tile.getAllSourcesOfColor());
    } else if (loc.isBetweenTiles()) {
      infiniteSources.addAll(loc.tile.getAllSourcesOfColor());
      infiniteSources.addAll(loc.getOther().tile.getAllSourcesOfColor());
    }

    if (includeCalendar) {
      // 7th day color magic!
      infiniteSources.addAll(cal.getColorMagic(game.getMonth(), game.getDay()));
    }

    if (infiniteSources.size() > 0) {
      ColorMagic spellColor = spell.getRequiredColorMagic();
      if (spellColor == null || infiniteSources.contains(spellColor)) {
        // We got it!
        return true;
        //				spell.affectTargets(frame,game,false);
      }
    }
    return false;
  }
  public void deenergizePermanentSpells() {
    // Make each permanent spell "inert", one at a time
    boolean didDeenergize = false;
    for (SpellWrapper spell : getSpells(PERMANENT_SPELLS)) {
      if (!spell.isInert()) { // If spell is already inert, then don't deenergize it!
        // Don't deenergize spells that have an automatic supply of color magic
        if (spellCanEnergize(
            GameWrapper.findGame(spell.getGameData()), spell.getCurrentLocation(), spell, false)) {
          continue;
        }

        if (!spell.isAlwaysActive()) {
          spell.unaffectTargets();
          spell.makeInert();
          didDeenergize = true;
        }
      }
    }
    if (didDeenergize) {
      // Yes, this is a dangerous recursion, but necessary I think.  If you Absorb Essence, and then
      // activate a Transform
      // spell, you end up two layers deep in spell wizardry, and this is the only way to guarantee
      // that both are deenergized.
      deenergizePermanentSpells();
    }
  }
 /**
  * @param location The location to search
  * @param needForCancel If true, excludes noCancel spells
  * @return A list of ALL breakable spells (currently Combat,Day,Permanent) that are in the
  *     clearing.
  */
 public ArrayList getAllSpellsInClearing(TileLocation location, boolean needForCancel) {
   ArrayList ret = new ArrayList();
   for (Iterator i = getSpells(null).iterator(); i.hasNext(); ) {
     SpellWrapper spell = (SpellWrapper) i.next();
     if (!needForCancel || !spell.isNoCancelSpell()) {
       TileLocation test = spell.getCurrentLocation();
       if (test
           != null) { // test might be null if the spell is targeting a treasure that hasn't yet
                      // been seen
         if (test.equals(location)) {
           ret.add(spell);
         } else if (test.isTileOnly()) {
           ret.add(spell);
         }
       }
     }
   }
   return ret;
 }
 /**
  * Adds a spell to the master list. Organizes into three bins: permanent, day, combat. All other
  * spell duration types (instant,attack,phase,move) are ignored here.
  */
 public void addSpell(SpellWrapper spell) {
   String duration = spell.getGameObject().getThisAttribute("duration");
   if (PERMANENT_SPELLS.equals(duration)) {
     addPermanentSpell(spell);
   } else if (DAY_SPELLS.equals(duration)) {
     addDaySpell(spell);
   } else if (COMBAT_SPELLS.equals(duration)) {
     addCombatSpell(spell);
   } else if (PHASE_SPELLS.equals(duration)) {
     addPhaseSpell(spell);
   } else if (MOVE_SPELLS.equals(duration)) {
     addMoveSpell(spell);
   }
 }
 private void expireBewitchingSpells(GameObject target, SpellWrapper exclude, boolean nullify) {
   for (SpellWrapper spell : getAffectingSpells(target)) {
     if (exclude != null && exclude.getGameObject().equals(spell.getGameObject())) continue;
     if (!nullify) {
       spell.removeTarget(target);
       if (spell.getTargetCount() == 0) {
         spell.expireSpell();
         // System.err.println(spell.getGameObject().getName()+" is expired");
       }
     } else {
       spell.nullifySpell();
       // System.err.println(spell.getGameObject().getName()+" is nullified");
     }
   }
 }
 private void addPermanentSpell(SpellWrapper spell) {
   addListItem(PERMANENT_SPELLS, spell.getGameObject().getStringId());
 }
  /** Calculates spell locations, and figures out the colors (infinite sources only here) */
  public void energizePermanentSpells(JFrame frame, GameWrapper game) {
    HashLists conflicts = new HashLists();
    for (SpellWrapper spell : getSpells(PERMANENT_SPELLS)) {
      if (spell.isInert()) { // no point energizing non-inert spells!
        TileLocation loc = spell.getCurrentLocation();
        if (loc == null) {
          // This means the spell was lost somehow
          spell.expireSpell();
        } else {
          if (spellCanEnergize(game, loc, spell, true)) {
            if (spell.canConflict()) {
              // Before we can add this, need to make sure that the affected target isn't already
              // afflicted with a STRONGER spell
              boolean addSpell = true;

              int str = spell.getConflictStrength();
              GameObject at = spell.getAffectedTarget().getGameObject();
              ArrayList<SpellWrapper> affSpells = getAffectingSpells(at);
              for (SpellWrapper affSpell : affSpells) {
                if (!affSpell.isInert() && affSpell.canConflict() && !affSpell.equals(spell)) {
                  int aStr = affSpell.getConflictStrength();
                  if (aStr >= str) {
                    // The active spell gets priority because it is equal to or greater in strength
                    // than this spell
                    addSpell = false;
                    break;
                  }
                }
              }

              if (addSpell) {
                conflicts.put(at, spell);
              }
            } else {
              spell.affectTargets(frame, game, false);
            }
          }
        }
      }
    }

    // Resolve conflicts per target (if any)
    for (Iterator i = conflicts.keySet().iterator(); i.hasNext(); ) {
      GameObject target = (GameObject) i.next();
      SpellWrapper strongest = null;
      ArrayList list = conflicts.getList(target);
      if (list.size() == 1) {
        // No conflict!
        strongest = (SpellWrapper) list.get(0);
      } else {
        // Multiple spells affecting target - find the strongest one
        ArrayList<SpellWrapper> strongGroup = new ArrayList<SpellWrapper>();
        int bestStrength = 0;
        for (Iterator n = list.iterator(); n.hasNext(); ) {
          SpellWrapper spell = (SpellWrapper) n.next();
          int strength = spell.getConflictStrength();
          if (strength > bestStrength) {
            strongGroup.clear();
            bestStrength = strength;
          }
          if (strength == bestStrength) {
            strongGroup.add(spell);
          }
        }
        if (strongGroup.size() == 1) {
          // Found the strongest spell
          strongest = strongGroup.get(0);
        } else {
          // uh-oh, this means there are two spells with equal strength affecting the same target
          // In this case, it is up to the spellcaster to decide which spell goes into effect

          // Make sure its all the same caster
          CharacterWrapper commonCaster = null;
          for (SpellWrapper spell : strongGroup) {
            CharacterWrapper caster = spell.getCaster();
            if (commonCaster == null) {
              commonCaster = caster;
            }
            if (!commonCaster.equals(caster)) {
              commonCaster = null;
              break;
            }
          }
          if (commonCaster != null) {
            // Found a common caster
            commonCaster.setSpellConflicts(strongGroup);
          } else {
            // No common caster?  No choice here, but to pick one at random!
            int r = RandomNumber.getRandom(strongGroup.size());
            strongest = strongGroup.get(r);
          }
        }
      }
      if (strongest != null) {
        strongest.affectTargets(frame, game, false);
      }
    }
  }
 public void expireIncantationSpell(GameObject incantation) {
   SpellWrapper spell = getIncantedSpell(incantation);
   if (spell != null) {
     spell.expireSpell();
   }
 }
 private void addPhaseSpell(SpellWrapper spell) {
   // only add a phase spell that has been activated (has a chit)
   if (spell.hasPhaseChit()) {
     addListItem(PHASE_SPELLS, spell.getGameObject().getStringId());
   }
 }
 private void addMoveSpell(SpellWrapper spell) {
   addListItem(MOVE_SPELLS, spell.getGameObject().getStringId());
 }
 private void addCombatSpell(SpellWrapper spell) {
   addListItem(COMBAT_SPELLS, spell.getGameObject().getStringId());
 }
 private void addDaySpell(SpellWrapper spell) {
   addListItem(DAY_SPELLS, spell.getGameObject().getStringId());
 }
 public void breakAllIncantations(boolean markIncantationChitsAsUsed) {
   for (SpellWrapper spell : getSpells(null)) {
     spell.breakIncantation(markIncantationChitsAsUsed);
   }
 }