Skip to content

Commit f147cef

Browse files
authored
Fix cheat shuffle (Card-Forge#10010)
* Fix cheat shuffle * Fix cheat shuffle --------- Co-authored-by: tool4EvEr <tool4EvEr@>
1 parent 1bb1a3d commit f147cef

File tree

14 files changed

+43
-74
lines changed

14 files changed

+43
-74
lines changed

forge-ai/src/main/java/forge/ai/AiController.java

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@
6767
import io.sentry.Breadcrumb;
6868
import io.sentry.Sentry;
6969

70-
import org.tinylog.Logger;
71-
7270
import java.util.*;
7371
import java.util.concurrent.FutureTask;
7472
import java.util.function.Function;
@@ -95,7 +93,6 @@ public class AiController {
9593
private final AiCardMemory memory;
9694
private Combat predictedCombat;
9795
private Combat predictedCombatNextTurn;
98-
private boolean cheatShuffle;
9996
private boolean useSimulation;
10097
private SpellAbilityPicker simPicker;
10198
private int lastAttackAggression;
@@ -110,14 +107,6 @@ public AiController(final Player computerPlayer, final Game game0) {
110107
simPicker = new SpellAbilityPicker(game, player);
111108
}
112109

113-
public boolean canCheatShuffle() {
114-
return cheatShuffle;
115-
}
116-
117-
public void allowCheatShuffle(boolean canCheatShuffle) {
118-
this.cheatShuffle = canCheatShuffle;
119-
}
120-
121110
public boolean usesSimulation() {
122111
return this.useSimulation;
123112
}
@@ -1340,11 +1329,6 @@ public void declareAttackers(Player attacker, Combat combat) {
13401329
aiAtk.declareAttackers(combat);
13411330
}
13421331
}
1343-
1344-
for (final Card element : combat.getAttackers()) {
1345-
// tapping of attackers happens after Propaganda is paid for
1346-
Logger.debug("Computer just assigned " + element.getName() + " as an attacker.");
1347-
}
13481332
}
13491333

13501334
private void removeUnpayableAttackers(Combat combat) {
@@ -1399,7 +1383,6 @@ public List<SpellAbility> chooseSpellAbilityToPlay() {
13991383
CardCollection landsWannaPlay = ComputerUtilAbility.getAvailableLandsToPlay(game, player);
14001384
if (landsWannaPlay != null) {
14011385
landsWannaPlay = filterLandsToPlay(landsWannaPlay);
1402-
Logger.debug("Computer " + game.getPhaseHandler().getPhase().nameForUi);
14031386
if (landsWannaPlay != null && !landsWannaPlay.isEmpty()) {
14041387
// TODO search for other land it might want to play?
14051388
Card land = chooseBestLandToPlay(landsWannaPlay);
@@ -2119,7 +2102,7 @@ public Map<DeckSection, List<? extends PaperCard>> complainCardsCantPlayWell(Dec
21192102
* @return an array of {@link forge.game.card.Card} objects.
21202103
*/
21212104
public CardCollectionView cheatShuffle(CardCollectionView in) {
2122-
if (in.size() < 20 || !canCheatShuffle()) {
2105+
if (in.size() < 20 || !getBoolProperty(AiProps.CHEAT_WITH_MANA_ON_SHUFFLE) || !getGame().getRules().isAllowCheatShuffle()) {
21232106
return in;
21242107
}
21252108

forge-ai/src/main/java/forge/ai/LobbyPlayerAi.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
import forge.game.player.IGameEntitiesFactory;
88
import forge.game.player.Player;
99
import forge.game.player.PlayerController;
10+
import org.tinylog.Logger;
1011

1112
public class LobbyPlayerAi extends LobbyPlayer implements IGameEntitiesFactory {
1213

1314
private String aiProfile = "";
1415
private boolean rotateProfileEachGame;
15-
private boolean allowCheatShuffle;
1616
private boolean useSimulation;
1717

1818
public LobbyPlayerAi(String name, Set<AIOption> options) {
@@ -22,14 +22,8 @@ public LobbyPlayerAi(String name, Set<AIOption> options) {
2222
}
2323
}
2424

25-
public boolean isAllowCheatShuffle() {
26-
return allowCheatShuffle;
27-
}
28-
public void setAllowCheatShuffle(boolean allowCheatShuffle) {
29-
this.allowCheatShuffle = allowCheatShuffle;
30-
}
31-
3225
public void setAiProfile(String profileName) {
26+
Logger.debug("[AI Preferences] " + name + " using profile " + profileName);
3327
aiProfile = profileName;
3428
}
3529
public String getAiProfile() {
@@ -43,7 +37,6 @@ public void setRotateProfileEachGame(boolean rotateProfileEachGame) {
4337
private PlayerControllerAi createControllerFor(Player ai) {
4438
PlayerControllerAi result = new PlayerControllerAi(ai.getGame(), ai, this);
4539
result.setUseSimulation(useSimulation);
46-
result.allowCheatShuffle(allowCheatShuffle);
4740
return result;
4841
}
4942

@@ -59,7 +52,6 @@ public Player createIngamePlayer(Game game, final int id) {
5952

6053
if (rotateProfileEachGame) {
6154
setAiProfile(AiProfileUtil.getRandomProfile());
62-
/*System.out.println(String.format("AI profile %s was chosen for the lobby player %s.", getAiProfile(), getName()));*/
6355
}
6456
return ai;
6557
}

forge-ai/src/main/java/forge/ai/PlayerControllerAi.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ public void setupAutoProfile(Deck deck) {
7676
pilotsNonAggroDeck = deck.getName().contains("Control") || Deck.getAverageCMC(deck) > 3;
7777
}
7878

79-
public void allowCheatShuffle(boolean value) {
80-
brains.allowCheatShuffle(value);
81-
}
82-
8379
public void setUseSimulation(boolean value) {
8480
brains.setUseSimulation(value);
8581
}
@@ -103,8 +99,7 @@ public boolean isAI() {
10399

104100
@Override
105101
public List<PaperCard> sideboard(Deck deck, GameType gameType, String message) {
106-
if (!brains.getGame().getRules().getAISideboardingEnabled()
107-
|| !deck.has(DeckSection.Sideboard)) {
102+
if (!brains.getGame().getRules().getAISideboardingEnabled() || !deck.has(DeckSection.Sideboard)) {
108103
return null;
109104
}
110105

@@ -1402,7 +1397,7 @@ public Map<DeckSection, List<? extends PaperCard>> complainCardsCantPlayWell(Dec
14021397

14031398
@Override
14041399
public CardCollectionView cheatShuffle(CardCollectionView list) {
1405-
return brains.getBoolProperty(AiProps.CHEAT_WITH_MANA_ON_SHUFFLE) ? brains.cheatShuffle(list) : list;
1400+
return brains.cheatShuffle(list);
14061401
}
14071402

14081403
@Override

forge-game/src/main/java/forge/game/GameAction.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -938,11 +938,8 @@ public final Card exileEffect(final Card effect) {
938938
}
939939

940940
public final void moveToCommand(final Card effect, final SpellAbility sa) {
941-
moveToCommand(effect, sa, AbilityKey.newMap());
942-
}
943-
public final void moveToCommand(final Card effect, final SpellAbility sa, Map<AbilityKey, Object> params) {
944941
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
945-
moveTo(ZoneType.Command, effect, sa, params);
942+
moveTo(ZoneType.Command, effect, sa, null);
946943
effect.updateStateForView();
947944
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
948945
}

forge-game/src/main/java/forge/game/GameRules.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class GameRules {
1414
private boolean matchAnteRarity = false;
1515
private boolean AISideboardingEnabled = false;
1616
private boolean sideboardForAI = false;
17+
private boolean allowCheatShuffle = false;
1718
private final Set<GameType> appliedVariants = EnumSet.noneOf(GameType.class);
1819
private int simTimeout = 120;
1920

@@ -88,6 +89,13 @@ public void setAISideboardingEnabled(final boolean aiSideboarding) {
8889
AISideboardingEnabled = aiSideboarding;
8990
}
9091

92+
public boolean isAllowCheatShuffle() {
93+
return allowCheatShuffle;
94+
}
95+
public void setAllowCheatShuffle(boolean allowCheatShuffle) {
96+
this.allowCheatShuffle = allowCheatShuffle;
97+
}
98+
9199
public int getGamesToWinMatch() {
92100
return gamesToWinMatch;
93101
}

forge-game/src/main/java/forge/game/ability/effects/VentureEffect.java

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
public class VentureEffect extends SpellAbilityEffect {
3535

36-
private Card getDungeonCard(SpellAbility sa, Player player, Map<AbilityKey, Object> moveParams) {
36+
private Card getDungeonCard(SpellAbility sa, Player player) {
3737
final Game game = player.getGame();
3838

3939
CardCollectionView commandCards = player.getCardsIn(ZoneType.Command);
@@ -73,7 +73,7 @@ private Card getDungeonCard(SpellAbility sa, Player player, Map<AbilityKey, Obje
7373
final Card dungeon = CardFactory.getCard(StaticData.instance().getAllTokens().getToken(script, edition), player, game);
7474
dungeon.setGamePieceType(GamePieceType.DUNGEON);
7575

76-
game.getAction().moveToCommand(dungeon, sa, moveParams);
76+
game.getAction().moveToCommand(dungeon, sa);
7777

7878
return dungeon;
7979
}
@@ -88,32 +88,32 @@ private String chooseNextRoom(SpellAbility sa, Player player, Card dungeon, Stri
8888
}
8989
}
9090
String [] nextRoomNames = nextRoomParam.split(",");
91-
if (nextRoomNames.length > 1) {
92-
List<SpellAbility> candidates = new ArrayList<>();
93-
for (String nextRoomName : nextRoomNames) {
94-
for (final Trigger t : dungeon.getTriggers()) {
95-
SpellAbility roomSA = t.getOverridingAbility();
96-
if (roomSA.getParam("RoomName").equals(nextRoomName)) {
97-
candidates.add(new WrappedAbility(t, roomSA, player));
98-
break;
99-
}
91+
if (nextRoomNames.length == 1) {
92+
return nextRoomNames[0];
93+
}
94+
95+
List<SpellAbility> candidates = new ArrayList<>();
96+
for (String nextRoomName : nextRoomNames) {
97+
for (final Trigger t : dungeon.getTriggers()) {
98+
SpellAbility roomSA = t.getOverridingAbility();
99+
if (roomSA.getParam("RoomName").equals(nextRoomName)) {
100+
candidates.add(new WrappedAbility(t, roomSA, player));
101+
break;
100102
}
101103
}
102-
final String title = Localizer.getInstance().getMessage("lblChooseRoom");
103-
SpellAbility chosen = player.getController().chooseSingleSpellForEffect(candidates, sa, title, null);
104-
return chosen.getParam("RoomName");
105-
} else {
106-
return nextRoomNames[0];
107104
}
105+
final String title = Localizer.getInstance().getMessage("lblChooseRoom");
106+
SpellAbility chosen = player.getController().chooseSingleSpellForEffect(candidates, sa, title, null);
107+
return chosen.getParam("RoomName");
108108
}
109109

110-
private void ventureIntoDungeon(SpellAbility sa, Player player, Map<AbilityKey, Object> moveParams) {
110+
private void ventureIntoDungeon(SpellAbility sa, Player player) {
111111
if (StaticAbilityCantVenture.cantVenture(player)) {
112112
return;
113113
}
114114

115115
final Game game = player.getGame();
116-
Card dungeon = getDungeonCard(sa, player, moveParams);
116+
Card dungeon = getDungeonCard(sa, player);
117117
String room = dungeon.getCurrentRoom();
118118

119119
String nextRoom;
@@ -138,15 +138,11 @@ private void ventureIntoDungeon(SpellAbility sa, Player player, Map<AbilityKey,
138138

139139
@Override
140140
public void resolve(SpellAbility sa) {
141-
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
142-
moveParams.put(AbilityKey.LastStateBattlefield, sa.getLastStateBattlefield());
143-
moveParams.put(AbilityKey.LastStateGraveyard, sa.getLastStateGraveyard());
144-
145141
for (final Player p : getTargetPlayers(sa)) {
146142
if (!p.isInGame()) {
147143
continue;
148144
}
149-
ventureIntoDungeon(sa, p, moveParams);
145+
ventureIntoDungeon(sa, p);
150146
}
151147
}
152148

forge-game/src/main/java/forge/game/card/Card.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6139,11 +6139,11 @@ public final void addAssignedDamage(int assignedDamage0, final Card sourceCard)
61396139
if (assignedDamage0 <= 0) {
61406140
return;
61416141
}
6142-
Logger.debug(this + " - was assigned " + assignedDamage0 + " damage, by " + sourceCard);
6143-
if (!assignedDamageMap.containsKey(sourceCard)) {
6144-
assignedDamageMap.put(sourceCard, assignedDamage0);
6145-
} else {
6142+
Logger.debug("{} was assigned {} damage by {}", this, assignedDamage0, sourceCard);
6143+
if (assignedDamageMap.containsKey(sourceCard)) {
61466144
assignedDamageMap.put(sourceCard, assignedDamageMap.get(sourceCard) + assignedDamage0);
6145+
} else {
6146+
assignedDamageMap.put(sourceCard, assignedDamage0);
61476147
}
61486148
view.updateAssignedDamage(this);
61496149
}

forge-gui-desktop/src/main/java/forge/toolbox/CardFaceSymbols.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public static void drawOther(final Graphics g, final String s, int x, final int
239239
final String symbol = tok.nextToken();
240240
final SkinImage image = MANA_IMAGES.get(symbol);
241241
if (image == null) {
242-
Logger.info("Symbol not recognized \"" + symbol + "\" in string: " + s);
242+
Logger.warn("Symbol not recognized \"" + symbol + "\" in string: " + s);
243243
continue;
244244
}
245245
FSkin.drawImage(g, image, x, y, w, h);

forge-gui/res/cardsfolder/d/doom_reigns_supreme.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ ManaCost:1 B
33
Types:Enchantment Plan
44
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Villain.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever a Villain you control enters, each opponent loses 1 life and you gain 1 life. Put a plan counter on this enchantment.
55
SVar:TrigLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife
6-
SVar:DBgGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 | SubAbility$ DBPutCounter
6+
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 | SubAbility$ DBPutCounter
77
SVar:DBPutCounter:DB$ PutCounter | CounterType$ PLAN | CounterNum$ 1
88
T:Mode$ CounterAdded | ValidCard$ Card.Self | TriggerZones$ Battlefield | CounterType$ PLAN | CounterAmount$ EQ5 | Execute$ TrigSac | TriggerDescription$ When the fifth plan counter is put on this enchantment, sacrifice it. When you do, target opponent exiles the top five cards of their library. You may cast up to two spells from among the exiled cards without paying their mana costs.
99
SVar:TrigSac:DB$ Sacrifice | Defined$ Self | RememberSacrificed$ True | SubAbility$ DBImmediateTrigger

forge-gui/res/cardsfolder/s/scion_of_halaster.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Types:Legendary Enchantment Background
44
S:Mode$ Continuous | Affected$ Creature.IsCommander+YouOwn | AddReplacementEffect$ Draw | Description$ Commander creatures you own have "The first time you would draw a card each turn, instead look at the top two cards of your library. Put one of them into your graveyard and the other back on top of your library. Then draw a card."
55
SVar:Draw:Event$ Draw | ValidPlayer$ You | ReplaceWith$ DBDig | CheckSVar$ X | SVarCompare$ EQ0 | Description$ The first time you would draw a card each turn, instead look at the top two cards of your library. Put one of them into your graveyard and the other back on top of your library. Then draw a card.
66
SVar:DBDig:DB$ Dig | DigNum$ 2 | DestinationZone$ Graveyard | NoReveal$ True | LibraryPosition2$ 0 | SubAbility$ DBDraw
7-
SVar:DBDraw:DB$ Draw | SubAbility$ Reset
7+
SVar:DBDraw:DB$ Draw
88
SVar:X:Count$YouDrewThisTurn
99
AI:RemoveDeck:NonCommander
1010
DeckHas:Ability$Graveyard

0 commit comments

Comments
 (0)