mirror of
https://github.com/correl/mage.git
synced 2024-12-01 11:09:56 +00:00
Fixes to casting calculations (#9049)
This commit is contained in:
parent
4f0e0a2ec6
commit
484e6c20f1
2 changed files with 54 additions and 3 deletions
|
@ -277,4 +277,8 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter
|
||||||
return alterCosts;
|
return alterCosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DynamicCost getDynamicCost() {
|
||||||
|
return dynamicCost;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3513,8 +3513,16 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a boolean indicating if the minimum mana cost of a given ability can be paid.
|
||||||
|
*
|
||||||
|
* @param ability The ability to pay for.
|
||||||
|
* @param availableMana The available mana.
|
||||||
|
* @param game The game to calculate this for.
|
||||||
|
* @return Boolean. True if the minimum can be paid, false otherwise.
|
||||||
|
*/
|
||||||
protected boolean canPayMinimumManaCost(ActivatedAbility ability, ManaOptions availableMana, Game game) {
|
protected boolean canPayMinimumManaCost(ActivatedAbility ability, ManaOptions availableMana, Game game) {
|
||||||
ManaOptions abilityOptions = ability.getMinimumCostToActivate(playerId, game);
|
ManaOptions abilityOptions = ability.getMinimumCostToActivate(playerId, game); // All possible combinations of mana costs
|
||||||
if (abilityOptions.isEmpty()) {
|
if (abilityOptions.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3526,22 +3534,30 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
addPhyrexianLikePayOptions(abilityOptions, availableMana, game);
|
addPhyrexianLikePayOptions(abilityOptions, availableMana, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the ability, if any, which allows for spending many as if it were another color.
|
||||||
|
// TODO: This needs to be improved to handle multiple approving objects.
|
||||||
|
// See https://github.com/magefree/mage/issues/8584
|
||||||
ApprovingObject approvingObject = game.getContinuousEffects().asThough(ability.getSourceId(),
|
ApprovingObject approvingObject = game.getContinuousEffects().asThough(ability.getSourceId(),
|
||||||
AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
|
AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game);
|
||||||
for (Mana mana : abilityOptions) {
|
for (Mana mana : abilityOptions) {
|
||||||
if (mana.count() == 0) {
|
if (mana.count() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Iterate through combinations of available mana
|
||||||
for (Mana avail : availableMana) {
|
for (Mana avail : availableMana) {
|
||||||
// TODO: SPEND_OTHER_MANA effects with getAsThoughManaType can change mana type to pay,
|
// TODO: SPEND_OTHER_MANA effects with getAsThoughManaType can change mana type to pay,
|
||||||
// but that code processing it as any color, need to test and fix another use cases
|
// but that code processing it as any color, need to test and fix another use cases
|
||||||
// (example: Sunglasses of Urza - may spend white mana as though it were red mana)
|
// (example: Sunglasses of Urza - may spend white mana as though it were red mana)
|
||||||
|
|
||||||
//
|
// TODO: add tests for non any color like Sunglasses of Urza
|
||||||
// add tests for non any color like Sunglasses of Urza
|
// TODO: Describe this
|
||||||
|
// Abilities that let us spend mana as if it were any (or other colors/types) must be handled seperately
|
||||||
|
// and can't be incorporated into calculating availableMana since the number of combinations would explode.
|
||||||
if (approvingObject != null && mana.count() <= avail.count()) {
|
if (approvingObject != null && mana.count() <= avail.count()) {
|
||||||
|
// TODO: I think this is wrong for spell that require colorless
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// TODO: Why is this second? Shouldn't conditional mana be checked before the above line?
|
||||||
if (avail instanceof ConditionalMana && !((ConditionalMana) avail).apply(ability, game, getId(), ability.getManaCosts())) {
|
if (avail instanceof ConditionalMana && !((ConditionalMana) avail).apply(ability, game, getId(), ability.getManaCosts())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3597,7 +3613,17 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
return availableLifeMana;
|
return availableLifeMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a boolean inidicating if any of the alternative mana costs for the given card can be afforded.
|
||||||
|
*
|
||||||
|
* @param sourceObject The card
|
||||||
|
* @param availableMana The mana available for payments.
|
||||||
|
* @param ability The ability to play it by.
|
||||||
|
* @param game The game to check for.
|
||||||
|
* @return Boolean, true if the card can be played by *any* of the available alternative costs, false otherwise.
|
||||||
|
*/
|
||||||
protected boolean canPlayCardByAlternateCost(Card sourceObject, ManaOptions availableMana, Ability ability, Game game) {
|
protected boolean canPlayCardByAlternateCost(Card sourceObject, ManaOptions availableMana, Ability ability, Game game) {
|
||||||
|
// TODO: Why is the "sourceObject instanceof Permanent" in there?
|
||||||
if (sourceObject != null && !(sourceObject instanceof Permanent)) {
|
if (sourceObject != null && !(sourceObject instanceof Permanent)) {
|
||||||
Ability copyAbility; // for alternative cost and reduce tries
|
Ability copyAbility; // for alternative cost and reduce tries
|
||||||
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
||||||
|
@ -3668,9 +3694,26 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a copy of the dynamic cost for this ability if there is one.
|
||||||
|
// E.g. from Kentaro, the Smiling Cat
|
||||||
|
if (alternateSourceCosts instanceof AlternativeCostSourceAbility) {
|
||||||
|
DynamicCost dynamicCost = ((AlternativeCostSourceAbility) alternateSourceCosts).getDynamicCost();
|
||||||
|
if (dynamicCost != null) {
|
||||||
|
Cost cost = dynamicCost.getCost(ability, game);
|
||||||
|
// TODO: I don't know if this first if-check is needed, I don't think any of the dynamics values are alternative costs.
|
||||||
|
if (cost instanceof AlternativeCost) {
|
||||||
|
cost = ((AlternativeCost) cost).getCost();
|
||||||
|
}
|
||||||
|
if (cost instanceof ManaCost) {
|
||||||
|
manaCosts.add((ManaCost) cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (manaCosts.isEmpty()) {
|
if (manaCosts.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: Why is it returning true if availableMana == null, one would think it should return false
|
||||||
if (availableMana == null) {
|
if (availableMana == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3678,6 +3721,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
// alternative cost reduce
|
// alternative cost reduce
|
||||||
copyAbility = ability.copy();
|
copyAbility = ability.copy();
|
||||||
copyAbility.getManaCostsToPay().clear();
|
copyAbility.getManaCostsToPay().clear();
|
||||||
|
// TODO: IDE warning:
|
||||||
|
// Unchecked assignment: 'mage.abilities.costs.mana.ManaCosts' to
|
||||||
|
// 'java.util.Collection<? extends mage.abilities.costs.mana.ManaCost>'.
|
||||||
|
// Reason: 'manaCosts' has raw type, so result of copy is erased
|
||||||
copyAbility.getManaCostsToPay().addAll(manaCosts.copy());
|
copyAbility.getManaCostsToPay().addAll(manaCosts.copy());
|
||||||
copyAbility.adjustCosts(game);
|
copyAbility.adjustCosts(game);
|
||||||
game.getContinuousEffects().costModification(copyAbility, game);
|
game.getContinuousEffects().costModification(copyAbility, game);
|
||||||
|
|
Loading…
Reference in a new issue