foul-magics/Mage/src/main/java/mage/abilities/effects/Effects.java
2023-11-19 21:37:37 -05:00

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);
}
}
}