mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Merge branch '1580-znr-iridescent-hornbeetle-wants-to-count-counters-added-to-creatures' into 'master'
Resolve "ZNR: Iridescent Hornbeetle wants to count counters added to CREATURES" Closes #1580 See merge request core-developers/forge!3196
This commit is contained in:
@@ -20,9 +20,12 @@ package forge.game;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardStateName;
|
||||
@@ -53,6 +56,8 @@ import forge.util.Visitor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
/**
|
||||
* Represents the state of a <i>single game</i>, a new instance is created for each game.
|
||||
*/
|
||||
@@ -86,6 +91,8 @@ public class Game {
|
||||
private Map<Player, PlayerCollection> attackedThisTurn = Maps.newHashMap();
|
||||
private Map<Player, PlayerCollection> attackedLastTurn = Maps.newHashMap();
|
||||
|
||||
private Table<CounterType, Player, List<Pair<Card, Integer>>> countersAddedThisTurn = HashBasedTable.create();
|
||||
|
||||
private Player monarch = null;
|
||||
private Player monarchBeginTurn = null;
|
||||
|
||||
@@ -939,4 +946,46 @@ public class Game {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void onCleanupPhase() {
|
||||
clearCounterAddedThisTurn();
|
||||
for (Player player : getPlayers()) {
|
||||
player.onCleanupPhase();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCounterAddedThisTurn(Player putter, CounterType cType, Card card, Integer value) {
|
||||
if (putter == null || card == null || value <= 0) {
|
||||
return;
|
||||
}
|
||||
List<Pair<Card, Integer>> result = countersAddedThisTurn.get(cType, putter);
|
||||
if (result == null) {
|
||||
result = Lists.newArrayList();
|
||||
}
|
||||
result.add(Pair.of(CardUtil.getLKICopy(card), value));
|
||||
if (!countersAddedThisTurn.contains(cType, putter)) {
|
||||
countersAddedThisTurn.put(cType, putter, result);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCounterAddedThisTurn(CounterType cType, String validPlayer, String validCard, Card source, Player sourceController, SpellAbility spellAbility) {
|
||||
int result = 0;
|
||||
if (!countersAddedThisTurn.containsRow(cType)) {
|
||||
return result;
|
||||
}
|
||||
for (Map.Entry<Player, List<Pair<Card, Integer>>> e : countersAddedThisTurn.row(cType).entrySet()) {
|
||||
if (e.getKey().isValid(validPlayer.split(","), sourceController, source, spellAbility)) {
|
||||
for (Pair<Card, Integer> p : e.getValue()) {
|
||||
if (p.getKey().isValid(validCard.split(","), sourceController, source, spellAbility)) {
|
||||
result += p.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clearCounterAddedThisTurn() {
|
||||
countersAddedThisTurn.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1593,6 +1593,8 @@ public class AbilityUtils {
|
||||
final String[] sq;
|
||||
sq = l[0].split("\\.");
|
||||
|
||||
final Game game = c.getGame();
|
||||
|
||||
if (ctb != null) {
|
||||
// Count$Compare <int comparator value>.<True>.<False>
|
||||
if (sq[0].startsWith("Compare")) {
|
||||
@@ -1776,6 +1778,13 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l[0].startsWith("CountersAddedThisTurn")) {
|
||||
final String[] parts = l[0].split(" ");
|
||||
CounterType cType = CounterType.getType(parts[1]);
|
||||
|
||||
return CardFactoryUtil.doXMath(game.getCounterAddedThisTurn(cType, parts[2], parts[3], c, sa.getActivatingPlayer(), sa), expr, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CardFactoryUtil.xCount(c, s2);
|
||||
|
||||
@@ -1239,7 +1239,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
final int loyaltyBefore = getCurrentLoyalty();
|
||||
|
||||
setCounters(counterType, newValue);
|
||||
getController().addCounterToPermThisTurn(counterType, addAmount);
|
||||
getGame().addCounterAddedThisTurn(source, counterType, this, addAmount);
|
||||
view.updateCounters(this);
|
||||
|
||||
//fire card stats changed event if p/t bonuses or loyalty changed from added counters
|
||||
@@ -1267,7 +1267,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
}
|
||||
} else {
|
||||
setCounters(counterType, newValue);
|
||||
getController().addCounterToPermThisTurn(counterType, addAmount);
|
||||
|
||||
getGame().addCounterAddedThisTurn(source, counterType, this, addAmount);
|
||||
view.updateCounters(this);
|
||||
}
|
||||
if (newValue <= 0) {
|
||||
|
||||
@@ -841,14 +841,6 @@ public class CardFactoryUtil {
|
||||
return doXMath(maxNum, m, c);
|
||||
}
|
||||
|
||||
// Count$CountersAddedToPermYouCtrl <CounterType>
|
||||
if (l[0].startsWith("CountersAddedToPermYouCtrl")) {
|
||||
final String[] components = l[0].split(" ", 2);
|
||||
final CounterType counterType = CounterType.getType(components[1]);
|
||||
int n = cc.getCounterToPermThisTurn(counterType);
|
||||
return doXMath(n, m, c);
|
||||
}
|
||||
|
||||
if (l[0].startsWith("CommanderCastFromCommandZone")) {
|
||||
// only used by Opal Palace, and it does add the trigger to the card
|
||||
return doXMath(cc.getCommanderCast(c), m, c);
|
||||
|
||||
@@ -501,9 +501,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
bPreventCombatDamageThisTurn = false;
|
||||
if (!bRepeatCleanup) {
|
||||
// only call onCleanupPhase when Cleanup is not repeated
|
||||
for (Player player : game.getPlayers()) {
|
||||
player.onCleanupPhase();
|
||||
}
|
||||
game.onCleanupPhase();
|
||||
setPlayerTurn(handleNextTurn());
|
||||
// "Trigger" for begin turn to get around a phase skipping
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
|
||||
@@ -114,8 +114,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
|
||||
private CardCollection sacrificedThisTurn = new CardCollection();
|
||||
|
||||
private Map<CounterType, Integer> countersAddedtoPermThisTurn = Maps.newHashMap();
|
||||
|
||||
/** A list of tokens not in play, but on their way.
|
||||
* This list is kept in order to not break ETB-replacement
|
||||
* on tokens. */
|
||||
@@ -2289,20 +2287,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
sacrificedThisTurn.clear();
|
||||
}
|
||||
|
||||
public final void addCounterToPermThisTurn(final CounterType type, final int x) {
|
||||
countersAddedtoPermThisTurn.put(type, getCounterToPermThisTurn(type) + x);
|
||||
}
|
||||
|
||||
public final Integer getCounterToPermThisTurn(final CounterType type) {
|
||||
if (countersAddedtoPermThisTurn.containsKey(type))
|
||||
return countersAddedtoPermThisTurn.get(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public final void resetCounterToPermThisTurn() {
|
||||
countersAddedtoPermThisTurn.clear();
|
||||
}
|
||||
|
||||
public final int getSpellsCastThisTurn() {
|
||||
return spellsCastThisTurn;
|
||||
}
|
||||
@@ -2521,7 +2505,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
resetSurveilThisTurn();
|
||||
resetCycledThisTurn();
|
||||
resetSacrificedThisTurn();
|
||||
resetCounterToPermThisTurn();
|
||||
clearAssignedDamage();
|
||||
resetAttackersDeclaredThisTurn();
|
||||
resetAttackedOpponentsThisTurn();
|
||||
|
||||
@@ -5,6 +5,6 @@ PT:2/2
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | CheckSVar$ X | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of each end step, if a +1/+1 counter was put on a permanent under your control this turn, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHints:Ability$Counters
|
||||
SVar:X:Count$CountersAddedToPermYouCtrl P1P1
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/fairgrounds_trumpeter.jpg
|
||||
DeckHas:Ability$Counters
|
||||
SVar:X:Count$CountersAddedThisTurn P1P1 Player Permanent.YouCtrl
|
||||
Oracle:At the beginning of each end step, if a +1/+1 counter was put on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter.
|
||||
|
||||
11
forge-gui/res/cardsfolder/i/iridescent_hornbeetle.txt
Normal file
11
forge-gui/res/cardsfolder/i/iridescent_hornbeetle.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Iridescent Hornbeetle
|
||||
ManaCost:4 G
|
||||
Types:Creature Insect
|
||||
PT:3/4
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, create a 1/1 green Insect creature token for each +1/+1 counter you've put on creatures under your control this turn.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ X | References$ X | TokenOwner$ You | TokenScript$ g_1_1_insect
|
||||
SVar:X:Count$CountersAddedThisTurn P1P1 You Creature.YouCtrl
|
||||
DeckNeeds:Ability$Counters
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:At the beginning of your end step, create a 1/1 green Insect creature token for each +1/+1 counter you've put on creatures under your control this turn.
|
||||
|
||||
Reference in New Issue
Block a user