private String damageStackDescription(AbilityFactory af, SpellAbility sa) {
        // when damageStackDescription is called, just build exactly what is happening
        StringBuilder sb = new StringBuilder();
        String name = af.getHostCard().toString();
        int dmg = getNumDamage(sa);

        ArrayList<Object> tgts;
        if (sa.getTarget() == null)
            tgts = AbilityFactory.getDefinedObjects(sa.getSourceCard(), af.getMapParams().get("Defined"), sa);
        else
            tgts = sa.getTarget().getTargets();

        if (!(sa instanceof Ability_Sub))
            sb.append(name).append(" -");
        sb.append(" ");

        String conditionDesc = af.getMapParams().get("ConditionDescription");
        if (conditionDesc != null)
            sb.append(conditionDesc).append(" ");

        ArrayList<Card> definedSources = AbilityFactory.getDefinedCards(sa.getSourceCard(), af.getMapParams().get("DamageSource"), sa);
        Card source = definedSources.get(0);

        if (source != sa.getSourceCard())
            sb.append(source.toString()).append(" deals");
        else
            sb.append("Deals");

        sb.append(" ").append(dmg).append(" damage to ");

        for (int i = 0; i < tgts.size(); i++) {
            if (i != 0)
                sb.append(" ");

            Object o = tgts.get(i);
            if (o instanceof Card || o instanceof Player)
                sb.append(o.toString());
        }

        sb.append(". ");

        if (sa.getSubAbility() != null) {
            sb.append(sa.getSubAbility().getStackDescription());
        }

        return sb.toString();
    }