Refactor Damage Prevention - Step 2

This commit is contained in:
Alumi
2021-05-08 13:57:03 +00:00
committed by Michael Kamensky
parent c40a132811
commit fe95ad2e11
40 changed files with 104 additions and 262 deletions

View File

@@ -48,7 +48,7 @@ public class ReplaceDamageEffect extends SpellAbilityEffect {
if (card.getType().hasStringType("Effect") && prevent <= 0) {
game.getAction().exile(card, null);
} else if (!StringUtils.isNumeric(varValue)) {
} else if (!StringUtils.isNumeric(varValue) && card.getSVar(varValue).startsWith("Number$")) {
card.setSVar(varValue, "Number$" + prevent);
}
// Set PreventedDamage SVar for PreventionSubAbility

View File

@@ -5222,12 +5222,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return 0;
}
// Prevent Damage static abilities
for (final Card ca : getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat, isTest);
}
}
return restDamage > 0 ? restDamage : 0;
}

View File

@@ -3422,7 +3422,24 @@ public class CardFactoryUtil {
Card host = card.getCard();
String keyword = inst.getOriginal();
if (keyword.equals("Aftermath") && card.getStateName().equals(CardStateName.RightSplit)) {
if (keyword.startsWith("Absorb")) {
final String[] k = keyword.split(":");
final String n = k[1];
StringBuilder sb = new StringBuilder();
sb.append("Event$ DamageDone | ActiveZones$ Battlefield | ValidTarget$ Card.Self");
sb.append(" | PreventionEffect$ True | Secondary$ True | Description$ Absorb ").append(n);
sb.append(" (").append(inst.getReminderText()).append(")");
String repeffstr = sb.toString();
String abString = "DB$ ReplaceDamage | Amount$ " + n;
SpellAbility replaceDamage = AbilityFactory.getAbility(abString, card);
replaceDamage.setIntrinsic(intrinsic);
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
re.setOverridingAbility(replaceDamage);
inst.addReplacement(re);
} else if (keyword.equals("Aftermath") && card.getStateName().equals(CardStateName.RightSplit)) {
StringBuilder sb = new StringBuilder();
sb.append("Event$ Moved | ValidCard$ Card.Self | Origin$ Stack | ExcludeDestination$ Exile ");
sb.append("| ValidStackSa$ Spell.Aftermath | Description$ Aftermath");
@@ -4748,16 +4765,7 @@ public class CardFactoryUtil {
String effect = null;
Map<String, String> svars = Maps.newHashMap();
if (keyword.startsWith("Absorb")) {
final String[] k = keyword.split(":");
final String n = k[1];
StringBuilder sb = new StringBuilder();
sb.append("Mode$ PreventDamage | Target$ Card.Self | Amount$ ");
sb.append(n).append("| Secondary$ True | Description$ Absorb ").append(n);
sb.append(" (").append(inst.getReminderText()).append(")");
effect = sb.toString();
} else if (keyword.startsWith("Affinity")) {
if (keyword.startsWith("Affinity")) {
final String[] k = keyword.split(":");
final String t = k[1];

View File

@@ -729,13 +729,6 @@ public class Player extends GameEntity implements Comparable<Player> {
int restDamage = damage;
// Prevent Damage static abilities
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat, isTest);
}
}
if (restDamage > 0) {
return restDamage;
}

View File

@@ -180,7 +180,7 @@ public abstract class PlayerController {
}
public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ListMultimap<Object, Player> votes, Player forPlayer);
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, GameEntity affected, String question);
public abstract CardCollectionView getCardsToMulligan(Player firstPlayer);
public abstract boolean mulliganKeepHand(Player player, int cardsToReturn);

View File

@@ -342,7 +342,8 @@ public class ReplacementHandler {
final String question = replacementEffect instanceof ReplaceDiscard
? Localizer.getInstance().getMessage("lblApplyCardReplacementEffectToCardConfirm", CardTranslation.getTranslatedName(cardForUi.getName()), runParams.get(AbilityKey.Card).toString(), effectDesc)
: Localizer.getInstance().getMessage("lblApplyReplacementEffectOfCardConfirm", CardTranslation.getTranslatedName(cardForUi.getName()), effectDesc);
boolean confirmed = optDecider.getController().confirmReplacementEffect(replacementEffect, effectSA, question);
GameEntity affected = (GameEntity) runParams.get(AbilityKey.Affected);
boolean confirmed = optDecider.getController().confirmReplacementEffect(replacementEffect, effectSA, affected, question);
if (!confirmed) {
return ReplacementResult.NotReplaced;
}

View File

@@ -287,41 +287,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
return getParam("Mode").equals("Continuous") && layers.contains(layer) && !isSuppressed() && checkConditions() && (previousRun || getHostCard().getStaticAbilities().contains(this));
}
// apply the ability if it has the right mode
/**
* Apply ability.
*
* @param mode
* the mode
* @param source
* the source
* @param target
* the target
* @param in
* the in
* @param isCombat
* the b
* @return the int
*/
public final int applyAbility(final String mode, final Card source, final GameEntity target, final int in,
final boolean isCombat, final boolean isTest) {
// don't apply the ability if it hasn't got the right mode
if (!getParam("Mode").equals(mode)) {
return in;
}
if (this.isSuppressed() || !this.checkConditions()) {
return in;
}
if (mode.equals("PreventDamage")) {
return StaticAbilityPreventDamage.applyPreventDamageAbility(this, source, target, in, isCombat, isTest);
}
return in;
}
/**
* Apply ability.
*

View File

@@ -1,120 +0,0 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.game.staticability;
import java.util.Map;
import forge.game.GameEntity;
import forge.game.card.Card;
import forge.game.card.CardFactoryUtil;
/**
* The Class StaticAbility_PreventDamage.
*/
public class StaticAbilityPreventDamage {
/**
* TODO Write javadoc for this method.
*
* @param stAb
* a StaticAbility
* @param source
* the source
* @param target
* the target
* @param damage
* the damage
* @param isCombat
* the is combat
* @return the int
*/
public static int applyPreventDamageAbility(final StaticAbility stAb, final Card source, final GameEntity target,
final int damage, final boolean isCombat, final boolean isTest) {
final Map<String, String> params = stAb.getMapParams();
final Card hostCard = stAb.getHostCard();
int restDamage = damage;
if (params.containsKey("Source") && !stAb.matchesValid(source, params.get("Source").split(","))) {
return restDamage;
}
if (params.containsKey("Target") && !stAb.matchesValid(target, params.get("Target").split(","))) {
return restDamage;
}
if (params.containsKey("CombatDamage") && params.get("CombatDamage").equals("True") && !isCombat) {
return restDamage;
}
if (params.containsKey("CombatDamage") && params.get("CombatDamage").equals("False") && isCombat) {
return restDamage;
}
if (params.containsKey("MaxDamage") && (Integer.parseInt(params.get("MaxDamage")) < damage)) {
return restDamage;
}
if (params.containsKey("SourceSharesColorWithTarget")) {
if (!(target instanceof Card) || source.equals(target)) {
return restDamage;
}
Card targetCard = (Card) target;
if (!source.sharesColorWith(targetCard)) {
return restDamage;
}
}
if (params.containsKey("Optional")) { //Assume if param is present it should be optional
if (!isTest) {
final String logic = params.containsKey("AILogic") ? params.get("AILogic") : "";
final String message = "Apply the effect of " + hostCard + "? (Affected: " + target + ")";
boolean confirmed = hostCard.getController().getController().confirmStaticApplication(hostCard, target, logic, message);
if (!confirmed) {
return restDamage;
}
} else { //test
if (!hostCard.getController().equals(target)) {
return restDamage;
}
}
}
// no amount means all
if (!params.containsKey("Amount") || params.get("Amount").equals("All")) {
return 0;
}
if (params.get("Amount").matches("[0-9][0-9]?")) {
restDamage = restDamage - Integer.parseInt(params.get("Amount"));
} else if (params.get("Amount").matches("HalfUp")) {
restDamage = restDamage - (int) (Math.ceil(restDamage / 2.0));
} else if (params.get("Amount").matches("HalfDown")) {
restDamage = restDamage - (int) (Math.floor(restDamage / 2.0));
} else {
restDamage = restDamage - CardFactoryUtil.xCount(hostCard, hostCard.getSVar(params.get("Amount")));
}
if (restDamage < 0) {
return 0;
}
return restDamage;
}
}