Pull ManaConversion out to be reused for SpellAbilityStackInstance

This commit is contained in:
Chris H
2018-10-07 22:07:53 -04:00
committed by Agetian
parent e4fddafc10
commit 210896b64e
6 changed files with 66 additions and 55 deletions

View File

@@ -29,6 +29,7 @@ import forge.game.ability.effects.AttachEffect;
import forge.game.card.*; import forge.game.card.*;
import forge.game.event.*; import forge.game.event.*;
import forge.game.keyword.KeywordInterface; import forge.game.keyword.KeywordInterface;
import forge.game.mana.ManaConversionService;
import forge.game.player.GameLossReason; import forge.game.player.GameLossReason;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
@@ -786,7 +787,7 @@ public class GameAction {
game.getReplacementHandler().cleanUpTemporaryReplacements(); game.getReplacementHandler().cleanUpTemporaryReplacements();
for (final Player p : game.getPlayers()) { for (final Player p : game.getPlayers()) {
p.getManaPool().restoreColorReplacements(); new ManaConversionService(p.getManaPool()).restoreColorReplacements();
p.clearStaticAbilities(); p.clearStaticAbilities();
} }

View File

@@ -18,6 +18,7 @@ import forge.game.ability.AbilityFactory.AbilityRecordType;
import forge.game.card.*; import forge.game.card.*;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.keyword.KeywordInterface; import forge.game.keyword.KeywordInterface;
import forge.game.mana.ManaConversionService;
import forge.game.mana.ManaCostBeingPaid; import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerCollection; import forge.game.player.PlayerCollection;
@@ -1663,7 +1664,7 @@ public class AbilityUtils {
} }
} }
// AdjustColorReplacement has two different matrices handling final mana conversion under the covers // AdjustColorReplacement has two different matrices handling final mana conversion under the covers
p.getManaPool().adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); new ManaConversionService(p.getManaPool()).adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive);
} }
} }
} }

View File

@@ -0,0 +1,11 @@
package forge.game.mana;
import forge.card.mana.ManaAtom;
public interface IManaConversionMatrix {
// Conversion matrix ORs byte values to make mana more payable
// Restrictive matrix ANDs byte values to make mana less payable
byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length];
byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length];
}

View File

@@ -0,0 +1,36 @@
package forge.game.mana;
import forge.card.mana.ManaAtom;
public class ManaConversionService {
static byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS };
IManaConversionMatrix matrix;
public ManaConversionService(IManaConversionMatrix mtrx) {
matrix = mtrx;
}
public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) {
// Fix the index without hardcodes
int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor);
rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx;
if (additive) {
matrix.colorConversionMatrix[rowIdx] |= replacementColor;
}
else {
matrix.colorRestrictionMatrix[rowIdx] &= replacementColor;
}
}
public void restoreColorReplacements() {
// By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C}
for (int i = 0; i < matrix.colorConversionMatrix.length; i++) {
matrix.colorConversionMatrix[i] = identityMatrix[i];
}
// By default all mana types are unrestricted
for (int i = 0; i < matrix.colorRestrictionMatrix.length; i++) {
matrix.colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES;
}
}
}

View File

@@ -20,7 +20,6 @@ package forge.game.mana;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import forge.GameCommand; import forge.GameCommand;
import forge.card.MagicColor; import forge.card.MagicColor;
import forge.card.mana.ManaAtom; import forge.card.mana.ManaAtom;
@@ -36,14 +35,9 @@ import forge.game.player.Player;
import forge.game.spellability.AbilityManaPart; import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/** /**
* <p> * <p>
@@ -53,13 +47,13 @@ import java.util.List;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class ManaPool implements Iterable<Mana> { public class ManaPool implements Iterable<Mana>, IManaConversionMatrix {
private final Player owner; private final Player owner;
private final Multimap<Byte, Mana> floatingMana = ArrayListMultimap.create(); private final Multimap<Byte, Mana> floatingMana = ArrayListMultimap.create();
public ManaPool(final Player player) { public ManaPool(final Player player) {
owner = player; owner = player;
restoreColorReplacements(); new ManaConversionService(this).restoreColorReplacements();
} }
public final int getAmountOfColor(final byte color) { public final int getAmountOfColor(final byte color) {
@@ -354,40 +348,11 @@ public class ManaPool implements Iterable<Mana> {
Player p = sa.getActivatingPlayer(); Player p = sa.getActivatingPlayer();
p.getGame().fireEvent(new GameEventZone(ZoneType.Battlefield, p, EventValueChangeType.ComplexUpdate, null)); p.getGame().fireEvent(new GameEventZone(ZoneType.Battlefield, p, EventValueChangeType.ComplexUpdate, null));
} }
// Conversion matrix ORs byte values to make mana more payable
// Restrictive matrix ANDs byte values to make mana less payable
private final byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length];
private final byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length];
private static final byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS };
public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) {
// Fix the index without hardcodes
int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor);
rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx;
if (additive) {
colorConversionMatrix[rowIdx] |= replacementColor;
}
else {
colorRestrictionMatrix[rowIdx] &= replacementColor;
}
}
public void restoreColorReplacements() {
// By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C}
for (int i = 0; i < colorConversionMatrix.length; i++) {
colorConversionMatrix[i] = identityMatrix[i];
}
// By default all mana types are unrestricted
for (int i = 0; i < colorRestrictionMatrix.length; i++) {
colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES;
}
}
public byte getPossibleColorUses(byte color) { public byte getPossibleColorUses(byte color) {
// Take the current conversion value, AND with restrictions to get mana usage // Take the current conversion value, AND with restrictions to get mana usage
int rowIdx = ManaAtom.getIndexOfFirstManaType(color); int rowIdx = ManaAtom.getIndexOfFirstManaType(color);
int matrixIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; int matrixIdx = rowIdx < 0 ? ManaConversionService.identityMatrix.length - 1 : rowIdx;
byte colorUse = colorConversionMatrix[matrixIdx]; byte colorUse = colorConversionMatrix[matrixIdx];
colorUse &= colorRestrictionMatrix[matrixIdx]; colorUse &= colorRestrictionMatrix[matrixIdx];

View File

@@ -17,14 +17,8 @@
*/ */
package forge.player; package forge.player;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.card.CardType; import forge.card.CardType;
import forge.card.MagicColor; import forge.card.MagicColor;
@@ -38,16 +32,17 @@ import forge.game.cost.CostPart;
import forge.game.cost.CostPartMana; import forge.game.cost.CostPartMana;
import forge.game.cost.CostPayment; import forge.game.cost.CostPayment;
import forge.game.keyword.KeywordInterface; import forge.game.keyword.KeywordInterface;
import forge.game.mana.ManaConversionService;
import forge.game.mana.ManaPool; import forge.game.mana.ManaPool;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerController; import forge.game.player.PlayerController;
import forge.game.spellability.AbilityActivated; import forge.game.spellability.*;
import forge.game.spellability.AbilitySub;
import forge.game.spellability.Spell;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.util.collect.FCollection; import forge.util.collect.FCollection;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.Map;
/** /**
* <p> * <p>
@@ -81,6 +76,7 @@ public class HumanPlaySpellAbility {
final Card c = ability.getHostCard(); final Card c = ability.getHostCard();
final CardPlayOption option = c.mayPlay(ability.getMayPlay()); final CardPlayOption option = c.mayPlay(ability.getMayPlay());
ManaConversionService service = new ManaConversionService(manapool);
boolean manaTypeConversion = false; boolean manaTypeConversion = false;
boolean manaColorConversion = false; boolean manaColorConversion = false;
@@ -169,11 +165,12 @@ public class HumanPlaySpellAbility {
ability.getHostCard().unanimateBestow(); ability.getHostCard().unanimateBestow();
} }
} }
if (manaTypeConversion || manaColorConversion || keywordColor) { if (manaTypeConversion || manaColorConversion || keywordColor) {
manapool.restoreColorReplacements(); service.restoreColorReplacements();
} }
if (playerManaConversion) { if (playerManaConversion) {
manapool.restoreColorReplacements(); service.restoreColorReplacements();
human.decNumManaConversion(); human.decNumManaConversion();
} }
return false; return false;
@@ -196,7 +193,7 @@ public class HumanPlaySpellAbility {
clearTargets(ability); clearTargets(ability);
} }
if (manaTypeConversion || manaColorConversion || keywordColor) { if (manaTypeConversion || manaColorConversion || keywordColor) {
manapool.restoreColorReplacements(); service.restoreColorReplacements();
} }
} }
return true; return true;