mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Some fixes (#6575)
This commit is contained in:
@@ -2456,7 +2456,7 @@ public class GameAction {
|
|||||||
game.getAction().reveal(milledPlayer, destination, p, false, message, addSuffix);
|
game.getAction().reveal(milledPlayer, destination, p, false, message, addSuffix);
|
||||||
}
|
}
|
||||||
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, p + " milled " +
|
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, p + " milled " +
|
||||||
Lang.joinHomogenous(milled) + toZoneStr + ".");
|
Lang.joinHomogenous(milledPlayer) + toZoneStr + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1640,9 +1640,15 @@ public class AbilityUtils {
|
|||||||
return doXMath(calculateAmount(c, sq[v ? 1 : 2], ctb), expr, c, ctb);
|
return doXMath(calculateAmount(c, sq[v ? 1 : 2], ctb), expr, c, ctb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpellAbility sa = null;
|
||||||
if (ctb instanceof SpellAbility) {
|
if (ctb instanceof SpellAbility) {
|
||||||
final SpellAbility sa = (SpellAbility) ctb;
|
sa = (SpellAbility) ctb;
|
||||||
|
} else if (sq[0].contains("xPaid") && ctb instanceof TriggerReplacementBase) {
|
||||||
|
// try avoid fallback
|
||||||
|
sa = ((TriggerReplacementBase) ctb).getOverridingAbility();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa != null) {
|
||||||
// special logic for xPaid in SpellAbility
|
// special logic for xPaid in SpellAbility
|
||||||
if (sq[0].contains("xPaid")) {
|
if (sq[0].contains("xPaid")) {
|
||||||
SpellAbility root = sa.getRootAbility();
|
SpellAbility root = sa.getRootAbility();
|
||||||
@@ -1672,7 +1678,8 @@ public class AbilityUtils {
|
|||||||
// and the spell that became that object as it resolved had a value of X chosen for any of its costs,
|
// and the spell that became that object as it resolved had a value of X chosen for any of its costs,
|
||||||
// the value of X for that ability is the same as the value of X for that spell, although the value of X for that permanent is 0.
|
// the value of X for that ability is the same as the value of X for that spell, although the value of X for that permanent is 0.
|
||||||
if (TriggerType.ChangesZone.equals(t.getMode()) && ZoneType.Battlefield.name().equals(t.getParam("Destination"))) {
|
if (TriggerType.ChangesZone.equals(t.getMode()) && ZoneType.Battlefield.name().equals(t.getParam("Destination"))) {
|
||||||
return doXMath(c.getXManaCostPaid(), expr, c, ctb);
|
int x = isUnlinkedFromCastSA(ctb, c) ? 0 : c.getXManaCostPaid();
|
||||||
|
return doXMath(x, expr, c, ctb);
|
||||||
} else if (TriggerType.SpellCast.equals(t.getMode())) {
|
} else if (TriggerType.SpellCast.equals(t.getMode())) {
|
||||||
// Cast Trigger like Hydroid Krasis
|
// Cast Trigger like Hydroid Krasis
|
||||||
SpellAbilityStackInstance castSI = (SpellAbilityStackInstance) root.getTriggeringObject(AbilityKey.StackInstance);
|
SpellAbilityStackInstance castSI = (SpellAbilityStackInstance) root.getTriggeringObject(AbilityKey.StackInstance);
|
||||||
@@ -1696,7 +1703,8 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (root.isReplacementAbility() && sa.hasParam("ETB")) {
|
if (root.isReplacementAbility() && sa.hasParam("ETB")) {
|
||||||
return doXMath(c.getXManaCostPaid(), expr, c, ctb);
|
int x = isUnlinkedFromCastSA(ctb, c) ? 0 : c.getXManaCostPaid();
|
||||||
|
return doXMath(x, expr, c, ctb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return doXMath(0, expr, c, ctb);
|
return doXMath(0, expr, c, ctb);
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ public interface ICostVisitor<T> {
|
|||||||
public T visit(CostFlipCoin cost) {
|
public T visit(CostFlipCoin cost) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T visit(CostForage cost) {
|
public T visit(CostForage cost) {
|
||||||
return null;
|
return null;
|
||||||
@@ -146,7 +147,9 @@ public interface ICostVisitor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T visit(CostPromiseGift cost) { return null; }
|
public T visit(CostPromiseGift cost) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T visit(CostPutCardToLib cost) {
|
public T visit(CostPutCardToLib cost) {
|
||||||
|
|||||||
@@ -665,6 +665,7 @@ public class ReplacementHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<ReplacementEffect> possibleReplacers = new ArrayList<>(replaceCandidateMap.keySet());
|
List<ReplacementEffect> possibleReplacers = new ArrayList<>(replaceCandidateMap.keySet());
|
||||||
|
// TODO should be able to choose different order for each entity
|
||||||
ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect(possibleReplacers);
|
ReplacementEffect chosenRE = decider.getController().chooseSingleReplacementEffect(possibleReplacers);
|
||||||
List<Map<AbilityKey, Object>> runParamList = replaceCandidateMap.get(chosenRE);
|
List<Map<AbilityKey, Object>> runParamList = replaceCandidateMap.get(chosenRE);
|
||||||
|
|
||||||
|
|||||||
@@ -78,9 +78,8 @@ public class CCombat implements ICDoc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
display.append("\n");
|
display.append("\n");
|
||||||
PlayerView controller = null;
|
|
||||||
if (defender instanceof CardView) {
|
if (defender instanceof CardView) {
|
||||||
controller = ((CardView) defender).getController();
|
PlayerView controller = ((CardView) defender).getController();
|
||||||
if (controller == null)
|
if (controller == null)
|
||||||
//shouldn't be null but display card's + controller ie Black Knight's controller
|
//shouldn't be null but display card's + controller ie Black Knight's controller
|
||||||
display.append(Lang.getInstance().getPossesive(defender.getName())).append(" controller");
|
display.append(Lang.getInstance().getPossesive(defender.getName())).append(" controller");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Infernal Vessel
|
|||||||
ManaCost:2 B
|
ManaCost:2 B
|
||||||
Types:Creature Human Cleric
|
Types:Creature Human Cleric
|
||||||
PT:2/1
|
PT:2/1
|
||||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+notDemon | Execute$ TrigReturn | TriggerDescription$ When this creature dies, if it wasn't a Demon, return it to the battlefield under its owner's control with two +1/+1 counters on it. It's a Demon in addition to its other types.
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+nonDemon | Execute$ TrigReturn | TriggerDescription$ When this creature dies, if it wasn't a Demon, return it to the battlefield under its owner's control with two +1/+1 counters on it. It's a Demon in addition to its other types.
|
||||||
SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredNewCardLKICopy | WithCountersType$ P1P1 | WithCountersAmount$ 2 | AnimateSubAbility$ DBAnimate
|
SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredNewCardLKICopy | WithCountersType$ P1P1 | WithCountersAmount$ 2 | AnimateSubAbility$ DBAnimate
|
||||||
SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Demon | Duration$ Permanent
|
SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Demon | Duration$ Permanent
|
||||||
Oracle:When this creature dies, if it wasn't a Demon, return it to the battlefield under its owner's control with two +1/+1 counters on it. It's a Demon in addition to its other types.
|
Oracle:When this creature dies, if it wasn't a Demon, return it to the battlefield under its owner's control with two +1/+1 counters on it. It's a Demon in addition to its other types.
|
||||||
@@ -3,7 +3,7 @@ ManaCost:2 W B
|
|||||||
Types:Legendary Creature Spirit Noble
|
Types:Legendary Creature Spirit Noble
|
||||||
PT:3/3
|
PT:3/3
|
||||||
K:Flying
|
K:Flying
|
||||||
T:Mode$ BecomesTarget | ValidTarget$ Card.Self,Spirit.YouCtrl+Other | ValidSource$ Spell | TriggerZones$ Battlefield | Execute$ TrigPhaseOut | TriggerDescription$ Whenever CARDNAME or another Spirit you control becomes the target of a spell, it phases out. (Treat it and anything attached to it as though they don't exist until your next turn.)
|
T:Mode$ BecomesTarget | ValidTarget$ Card.Self,Spirit.YouCtrl+Other+inZoneBattlefield | ValidSource$ Spell | TriggerZones$ Battlefield | Execute$ TrigPhaseOut | TriggerDescription$ Whenever CARDNAME or another Spirit you control becomes the target of a spell, it phases out. (Treat it and anything attached to it as though they don't exist until your next turn.)
|
||||||
SVar:TrigPhaseOut:DB$ Phases | Defined$ TriggeredTargetLKICopy
|
SVar:TrigPhaseOut:DB$ Phases | Defined$ TriggeredTargetLKICopy
|
||||||
T:Mode$ PhaseIn | ValidCard$ Card.Self,Spirit.YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME or another Spirit you control phases in, create a tapped 1/1 white Spirit creature token with flying.
|
T:Mode$ PhaseIn | ValidCard$ Card.Self,Spirit.YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME or another Spirit you control phases in, create a tapped 1/1 white Spirit creature token with flying.
|
||||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You | TokenTapped$ True
|
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You | TokenTapped$ True
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Needletooth Pack
|
|||||||
ManaCost:3 G G
|
ManaCost:3 G G
|
||||||
Types:Creature Dinosaur
|
Types:Creature Dinosaur
|
||||||
PT:4/5
|
PT:4/5
|
||||||
T:Mode$ Phase | Phase$ End of Turn | CheckSVar$ Morbid | SVarCompare$ GE1 | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Morbid — At the beginning of your end step, if a creature died this turn, put two +1/+1 counters on target creature you control.
|
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ Morbid | SVarCompare$ GE1 | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Morbid — At the beginning of your end step, if a creature died this turn, put two +1/+1 counters on target creature you control.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 2
|
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | CounterType$ P1P1 | CounterNum$ 2
|
||||||
SVar:Morbid:Count$Morbid.1.0
|
SVar:Morbid:Count$Morbid.1.0
|
||||||
Oracle:Morbid — At the beginning of your end step, if a creature died this turn, put two +1/+1 counters on target creature you control.
|
Oracle:Morbid — At the beginning of your end step, if a creature died this turn, put two +1/+1 counters on target creature you control.
|
||||||
@@ -3,7 +3,7 @@ ManaCost:U U U
|
|||||||
Types:Legendary Enchantment Creature Nightmare
|
Types:Legendary Enchantment Creature Nightmare
|
||||||
PT:10/1
|
PT:10/1
|
||||||
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't be blocked.
|
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't be blocked.
|
||||||
R:Event$ DamageDone | ActiveZones$ Battlefield | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | ReplaceWith$ Mill | PreventionEffect$ True | ExecuteMode$ PerTarget | Description$ If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.
|
R:Event$ DamageDone | ActiveZones$ Battlefield | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | ReplaceWith$ Mill | PreventionEffect$ True | ExecuteMode$ PerSource | Description$ If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.
|
||||||
SVar:Mill:DB$ Mill | Defined$ Opponent | NumCards$ X
|
SVar:Mill:DB$ Mill | Defined$ Opponent | NumCards$ X
|
||||||
SVar:X:ReplaceCount$DamageAmount
|
SVar:X:ReplaceCount$DamageAmount
|
||||||
Oracle:The Mindskinner can't be blocked.\nIf a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.
|
Oracle:The Mindskinner can't be blocked.\nIf a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.
|
||||||
|
|||||||
@@ -443,17 +443,13 @@ public abstract class GameLobby implements IHasGameType {
|
|||||||
Deck deck = slot.getDeck();
|
Deck deck = slot.getDeck();
|
||||||
RegisteredPlayer rp = new RegisteredPlayer(deck);
|
RegisteredPlayer rp = new RegisteredPlayer(deck);
|
||||||
|
|
||||||
if (variantTypes.isEmpty()) {
|
if (!variantTypes.isEmpty()) {
|
||||||
rp.setTeamNumber(team);
|
|
||||||
players.add(rp.setPlayer(lobbyPlayer));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isCommanderMatch) {
|
if (isCommanderMatch) {
|
||||||
final GameType commanderGameType =
|
final GameType commanderGameType =
|
||||||
isOathbreakerMatch ? GameType.Oathbreaker :
|
isOathbreakerMatch ? GameType.Oathbreaker :
|
||||||
isTinyLeadersMatch ? GameType.TinyLeaders :
|
isTinyLeadersMatch ? GameType.TinyLeaders :
|
||||||
isBrawlMatch ? GameType.Brawl :
|
isBrawlMatch ? GameType.Brawl :
|
||||||
GameType.Commander;
|
GameType.Commander;
|
||||||
if (checkLegality) {
|
if (checkLegality) {
|
||||||
final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
|
final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
|
||||||
if (errMsg != null) {
|
if (errMsg != null) {
|
||||||
@@ -481,7 +477,6 @@ public abstract class GameLobby implements IHasGameType {
|
|||||||
Iterable<PaperCard> schemes = null;
|
Iterable<PaperCard> schemes = null;
|
||||||
Iterable<PaperCard> planes = null;
|
Iterable<PaperCard> planes = null;
|
||||||
|
|
||||||
//Archenemy
|
|
||||||
if (variantTypes.contains(GameType.ArchenemyRumble)
|
if (variantTypes.contains(GameType.ArchenemyRumble)
|
||||||
|| (variantTypes.contains(GameType.Archenemy) && isArchenemy)) {
|
|| (variantTypes.contains(GameType.Archenemy) && isArchenemy)) {
|
||||||
final CardPool schemePool = deck.get(DeckSection.Schemes);
|
final CardPool schemePool = deck.get(DeckSection.Schemes);
|
||||||
@@ -495,7 +490,6 @@ public abstract class GameLobby implements IHasGameType {
|
|||||||
schemes = schemePool == null ? Collections.emptyList() : schemePool.toFlatList();
|
schemes = schemePool == null ? Collections.emptyList() : schemePool.toFlatList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Planechase
|
|
||||||
if (variantTypes.contains(GameType.Planechase)) {
|
if (variantTypes.contains(GameType.Planechase)) {
|
||||||
final CardPool planePool = deck.get(DeckSection.Planes);
|
final CardPool planePool = deck.get(DeckSection.Planes);
|
||||||
if (checkLegality) {
|
if (checkLegality) {
|
||||||
@@ -508,7 +502,6 @@ public abstract class GameLobby implements IHasGameType {
|
|||||||
planes = planePool == null ? Collections.emptyList() : planePool.toFlatList();
|
planes = planePool == null ? Collections.emptyList() : planePool.toFlatList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Vanguard
|
|
||||||
if (variantTypes.contains(GameType.Vanguard)) {
|
if (variantTypes.contains(GameType.Vanguard)) {
|
||||||
if (avatarPool == null || avatarPool.countAll() == 0) { //ERROR! null if avatar deselected on list
|
if (avatarPool == null || avatarPool.countAll() == 0) { //ERROR! null if avatar deselected on list
|
||||||
SOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblNoSelectedVanguardAvatarForPlayer", name));
|
SOptionPane.showMessageDialog(Localizer.getInstance().getMessage("lblNoSelectedVanguardAvatarForPlayer", name));
|
||||||
@@ -517,10 +510,11 @@ public abstract class GameLobby implements IHasGameType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rp = RegisteredPlayer.forVariants(activeSlots.size(), variantTypes, deck, schemes, isArchenemy, planes, avatarPool);
|
rp = RegisteredPlayer.forVariants(activeSlots.size(), variantTypes, deck, schemes, isArchenemy, planes, avatarPool);
|
||||||
rp.setTeamNumber(team);
|
|
||||||
players.add(rp.setPlayer(lobbyPlayer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rp.setTeamNumber(team);
|
||||||
|
players.add(rp.setPlayer(lobbyPlayer));
|
||||||
|
|
||||||
if (!isAI) {
|
if (!isAI) {
|
||||||
guis.put(rp, gui);
|
guis.put(rp, gui);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user