forked from External/mage
202 lines
6.6 KiB
Java
202 lines
6.6 KiB
Java
package mage.abilities.effects;
|
|
|
|
import mage.abilities.Ability;
|
|
import mage.abilities.Mode;
|
|
import mage.constants.Outcome;
|
|
import mage.target.targetpointer.TargetPointer;
|
|
import mage.util.CardUtil;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* @author BetaSteward_at_googlemail.com
|
|
*/
|
|
public class Effects extends ArrayList<Effect> {
|
|
|
|
public Effects(Effect... effects) {
|
|
this.addAll(Arrays.asList(effects));
|
|
}
|
|
|
|
protected Effects(final Effects effects) {
|
|
for (Effect effect : effects) {
|
|
this.add(effect.copy());
|
|
}
|
|
}
|
|
|
|
public Effects copy() {
|
|
return new Effects(this);
|
|
}
|
|
|
|
public String getTextStartingUpperCase(Mode mode) {
|
|
String text = getText(mode);
|
|
if (text.length() > 3) {
|
|
return CardUtil.getTextWithFirstCharUpperCase(text);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
public String getText(Mode mode) {
|
|
StringBuilder sbText = new StringBuilder();
|
|
String lastRule = null;
|
|
int effectNum = 0;
|
|
for (Effect effect : this) {
|
|
String endString = "";
|
|
String nextRule = effect.getText(mode);
|
|
|
|
// ignore empty rules
|
|
if (nextRule == null || nextRule.isEmpty()) {
|
|
continue;
|
|
}
|
|
effectNum++;
|
|
|
|
// concat effects (default: each effect with a new sentence)
|
|
String concatPrefix = effect.getConcatPrefix();
|
|
|
|
if (effectNum > 1 && !concatPrefix.isEmpty() && !concatPrefix.equals(".")) {
|
|
if (concatPrefix.contains("<br>")) {
|
|
nextRule = concatPrefix + CardUtil.getTextWithFirstCharUpperCase(nextRule);
|
|
} else {
|
|
nextRule = concatPrefix + " " + nextRule;
|
|
}
|
|
}
|
|
|
|
//check if nextRule is a new sentence or not.
|
|
if (nextRule.startsWith("and ")
|
|
|| nextRule.startsWith("with ")
|
|
|| nextRule.startsWith("then ")
|
|
|| nextRule.startsWith("or ")) {
|
|
endString = " ";
|
|
} else if (nextRule.startsWith(",") || nextRule.startsWith(" ")) {
|
|
endString = "";
|
|
// nextRule determined to be a new sentence, now check ending of lastRule
|
|
} else if (lastRule != null && lastRule.length() > 3) {
|
|
//check if lastRule already has appropriate punctuation, if so, add a space.
|
|
if (lastRule.endsWith(".\"")
|
|
|| lastRule.endsWith(".]")
|
|
|| lastRule.endsWith(".)")
|
|
|| lastRule.endsWith(".)</i>")
|
|
|| lastRule.endsWith(".")) {
|
|
endString = " ";
|
|
// if lastRule does not have appropriate punctuation, add the default ". "
|
|
} else if (!lastRule.endsWith(".") && !lastRule.endsWith("<br>")) {
|
|
endString = ". ";
|
|
}
|
|
if (nextRule.length() > 3) {
|
|
nextRule = Character.toUpperCase(nextRule.charAt(0)) + nextRule.substring(1);
|
|
}
|
|
}
|
|
|
|
String currentRule = endString + nextRule;
|
|
// fix dot in the combined effect like IfDoCost
|
|
if (sbText.length() > 0 && currentRule.length() > 0) {
|
|
boolean prevTextEndsWithDot = sbText.charAt(sbText.length() - 1) == '.';
|
|
boolean currentTextStartsWithDot = currentRule.startsWith(",") || currentRule.startsWith(".");
|
|
if (prevTextEndsWithDot && currentTextStartsWithDot) {
|
|
sbText.delete(sbText.length() - 1, sbText.length());
|
|
}
|
|
}
|
|
|
|
sbText.append(currentRule);
|
|
|
|
lastRule = nextRule;
|
|
}
|
|
|
|
// add punctuation to very last rule.
|
|
if (lastRule != null && lastRule.length() > 3
|
|
&& !lastRule.endsWith(".")
|
|
&& !lastRule.endsWith("!")
|
|
&& !lastRule.endsWith("\"")
|
|
&& !lastRule.endsWith(".]")
|
|
&& !lastRule.startsWith("<b>LEVEL ")
|
|
&& !lastRule.endsWith(".)")
|
|
&& !lastRule.endsWith("<br>")
|
|
&& !lastRule.endsWith("</i>")) {
|
|
sbText.append('.');
|
|
}
|
|
|
|
// flavor word
|
|
if (mode.getFlavorWord() != null) {
|
|
return CardUtil.italicizeWithEmDash(mode.getFlavorWord())
|
|
+ CardUtil.getTextWithFirstCharUpperCase(sbText.toString());
|
|
}
|
|
|
|
return sbText.toString();
|
|
}
|
|
|
|
public boolean hasOutcome(Ability source, Outcome outcome) {
|
|
Outcome realOutcome = (source == null ? null : source.getCustomOutcome());
|
|
if (realOutcome != null) {
|
|
return realOutcome == outcome;
|
|
}
|
|
for (Effect effect : this) {
|
|
if (effect.getOutcome() == outcome) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param source source ability for effects
|
|
* @return real outcome of ability
|
|
*/
|
|
public Outcome getOutcome(Ability source) {
|
|
return getOutcome(source, Outcome.Detriment);
|
|
}
|
|
|
|
public Outcome getOutcome(Ability source, Outcome defaultOutcome) {
|
|
Outcome realOutcome = (source == null ? null : source.getCustomOutcome());
|
|
if (realOutcome != null) {
|
|
return realOutcome;
|
|
}
|
|
|
|
if (!this.isEmpty()) {
|
|
return this.get(0).getOutcome();
|
|
}
|
|
|
|
return defaultOutcome;
|
|
}
|
|
|
|
/**
|
|
* @param source source ability for effects
|
|
* @return total score of outcome effects (plus/minus)
|
|
*/
|
|
public int getOutcomeScore(Ability source) {
|
|
int total = 0;
|
|
for (Effect effect : this) {
|
|
// custom ability outcome must "rewrite" effect's outcome (it uses for AI desisions and card score... hmm, getOutcomeTotal used on 28.01.2020)
|
|
Outcome realOutcome = (source == null ? null : source.getCustomOutcome());
|
|
if (realOutcome == null) {
|
|
realOutcome = effect.getOutcome();
|
|
}
|
|
if (realOutcome.isGood()) {
|
|
total++;
|
|
} else {
|
|
total--;
|
|
}
|
|
}
|
|
return total;
|
|
}
|
|
|
|
public void newId() {
|
|
for (Effect effect : this) {
|
|
effect.newId();
|
|
}
|
|
}
|
|
|
|
public void setTargetPointer(TargetPointer targetPointer) {
|
|
if (targetPointer == null) {
|
|
return;
|
|
}
|
|
for (Effect effect : this) {
|
|
effect.setTargetPointer(targetPointer.copy());
|
|
}
|
|
}
|
|
|
|
public void setValue(String key, Object value) {
|
|
for (Effect effect : this) {
|
|
effect.setValue(key, value);
|
|
}
|
|
}
|
|
}
|