From a78c648e775d75da2ff253145da59876f6b68caa Mon Sep 17 00:00:00 2001 From: tool4ever Date: Thu, 24 Jul 2025 16:33:51 +0200 Subject: [PATCH] Fix Offering being an AltCost (#8190) --- .../src/main/java/forge/game/GameActionUtil.java | 11 ++++++++--- .../game/ability/effects/PermanentEffect.java | 10 +++++----- .../java/forge/game/card/CardFactoryUtil.java | 16 ---------------- .../forge/game/spellability/AlternativeCost.java | 1 - .../forge/game/spellability/OptionalCost.java | 1 + .../forge/game/spellability/SpellAbility.java | 4 ++-- 6 files changed, 16 insertions(+), 27 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 6126e03bfb8..73b4651689c 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -495,9 +495,11 @@ public final class GameActionUtil { String[] k = keyword.split(":"); final Cost cost = new Cost(k[1], false); costs.add(new OptionalCostValue(OptionalCost.Flash, cost)); + } else if (keyword.endsWith(" offering")) { + final String type = keyword.split(" ")[0]; + final Cost cost = new Cost("Sac<1/" + type + ">", false); + costs.add(new OptionalCostValue(OptionalCost.Offering, cost)); } - - // Surge while having OptionalCost is none of them } // reset static abilities @@ -524,7 +526,9 @@ public final class GameActionUtil { result.putParam("RaiseCost", sa.getParam("RaiseCost")); } for (OptionalCostValue v : list) { - result.getPayCosts().add(v.getCost()); + if (v.getType() != OptionalCost.Offering) { + result.getPayCosts().add(v.getCost()); + } result.addOptionalCost(v.getType()); // add some extra logic, try to move it to other parts @@ -534,6 +538,7 @@ public final class GameActionUtil { result.getRestrictions().setZone(ZoneType.Graveyard); break; case Flash: + case Offering: result.getRestrictions().setInstantSpeed(true); break; default: diff --git a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java index a84981cb4a0..14ce438c8ea 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java @@ -31,20 +31,20 @@ public class PermanentEffect extends SpellAbilityEffect { final Card c = game.getAction().moveToPlay(host, sa, moveParams); sa.setHostCard(c); + // CR 608.3g if (sa.isIntrinsic() || c.wasCast()) { - // some extra for Dashing if (sa.isDash() && c.isInPlay()) { - c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Dash"), c.getGame().getNextTimestamp(), 0); registerDelayedTrigger(sa, "Hand", Lists.newArrayList(c)); + // add AI hint + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Dash"), c.getGame().getNextTimestamp(), 0); } - // similar for Blitz keyword if (sa.isBlitz() && c.isInPlay()) { - c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Blitz"), c.getGame().getNextTimestamp(), 0); registerDelayedTrigger(sa, "Sacrifice", Lists.newArrayList(c)); + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Blitz"), c.getGame().getNextTimestamp(), 0); } if (sa.isWarp() && c.isInPlay()) { - c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Warp"), c.getGame().getNextTimestamp(), 0); registerDelayedTrigger(sa, "Exile", Lists.newArrayList(c)); + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Warp"), c.getGame().getNextTimestamp(), 0); } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 1a4b9a935e2..eaf2913ae88 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3810,22 +3810,6 @@ public class CardFactoryUtil { newSA.setAlternativeCost(AlternativeCost.Warp); newSA.setIntrinsic(intrinsic); inst.addSpellAbility(newSA); - } else if (keyword.endsWith(" offering")) { - final String offeringType = keyword.split(" ")[0]; - final SpellAbility sa = card.getFirstSpellAbility(); - - final SpellAbility newSA = sa.copy(); - - SpellAbilityRestriction sar = newSA.getRestrictions(); - sar.setIsPresent(offeringType + ".YouCtrl+CanBeSacrificedBy"); - sar.setInstantSpeed(true); - - newSA.putParam("Secondary", "True"); - newSA.setAlternativeCost(AlternativeCost.Offering); - newSA.setPayCosts(sa.getPayCosts()); - newSA.setDescription(sa.getDescription() + " (" + offeringType + " offering)"); - newSA.setIntrinsic(intrinsic); - inst.addSpellAbility(newSA); } else if (keyword.startsWith("Crew")) { final String[] k = keyword.split(":"); final String power = k[1]; diff --git a/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java b/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java index e88c409b0f1..471451a0ca6 100644 --- a/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java +++ b/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java @@ -17,7 +17,6 @@ public enum AlternativeCost { Madness, MTMtE, // More Than Meets the Eye (Transformers Universes Beyond) Mutate, - Offering, Overload, Prowl, Plotted, diff --git a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java index 086a4ed5545..9a36518a3c8 100644 --- a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java +++ b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java @@ -13,6 +13,7 @@ public enum OptionalCost { PromiseGift("Promise Gift", ""), Retrace("Retrace", ""), Jumpstart("Jump-start", ""), + Offering("Offering", ""), ReduceW("(to reduce white mana)", "W"), ReduceU("(to reduce blue mana)", "U"), ReduceB("(to reduce black mana)", "B"), diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 95a75446d57..70e9da92c9f 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -1609,10 +1609,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public boolean isOffering() { - return isAlternativeCost(AlternativeCost.Offering); + return isOptionalCostPaid(OptionalCost.Offering); } - public Card getSacrificedAsOffering() { //for Patron offering + public Card getSacrificedAsOffering() { return sacrificedAsOffering; } public void setSacrificedAsOffering(final Card c) {