mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 12:31:59 -08:00
Merge branch 'master' of https://github.com/magefree/mage
This commit is contained in:
commit
32b800d99e
17 changed files with 190 additions and 224 deletions
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
|
|
@ -16,8 +15,9 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ public class PutCardFromHandOnTopOfLibraryCost extends CostImpl {
|
|||
if (targetCardInHand.canChoose(controllerId, game)
|
||||
&& controller.choose(Outcome.PreventDamage, targetCardInHand, sourceId, game)) {
|
||||
card = game.getCard(targetCardInHand.getFirstTarget());
|
||||
paid = controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.HAND, true, true);
|
||||
paid = card != null && controller.moveCardToLibraryWithInfo(card, sourceId, game, Zone.HAND, true, true);
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
|
|
@ -19,18 +17,19 @@ import mage.target.Target;
|
|||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* 702.46. Offering # 702.46a Offering is a static ability of a card that
|
||||
* functions in any zone from which the card can be cast. "[Subtype] offering"
|
||||
* means "You may cast this card any time you could cast an instant by
|
||||
* sacrificing a [subtype] permanent. If you do, the total cost to cast this
|
||||
* card is reduced by the sacrificed permanent's mana cost." #
|
||||
*
|
||||
* <p>
|
||||
* 702.46b The permanent is sacrificed at the same time the spell is announced
|
||||
* (see rule 601.2a). The total cost of the spell is reduced by the sacrificed
|
||||
* permanent's mana cost (see rule 601.2e). #
|
||||
*
|
||||
* <p>
|
||||
* 702.46c Generic mana in the sacrificed permanent's mana cost reduces generic
|
||||
* mana in the total cost to cast the card with offering. Colored mana in the
|
||||
* sacrificed permanent's mana cost reduces mana of the same color in the total
|
||||
|
|
@ -39,7 +38,6 @@ import mage.util.CardUtil;
|
|||
* cost of the card with offering, or is in excess of the card's colored mana
|
||||
* cost, reduces that much generic mana in the total cost. #
|
||||
*
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class OfferingAbility extends StaticAbility {
|
||||
|
|
@ -47,7 +45,6 @@ public class OfferingAbility extends StaticAbility {
|
|||
private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param subtype name of the subtype that can be offered
|
||||
*/
|
||||
public OfferingAbility(SubType subtype) {
|
||||
|
|
@ -107,7 +104,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
|
|||
public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
|
||||
if (sourceId.equals(source.getSourceId())) {
|
||||
Card card = game.getCard(sourceId);
|
||||
if (!card.isOwnedBy(source.getControllerId())) {
|
||||
if (card == null || !card.isOwnedBy(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
// because can activate is always called twice, result from first call will be used
|
||||
|
|
@ -129,6 +126,9 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
|
|||
}
|
||||
FilterControlledCreaturePermanent filter = ((OfferingAbility) source).getFilter();
|
||||
Card spellToCast = game.getCard(source.getSourceId());
|
||||
if (spellToCast == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null && !CardUtil.isCheckPlayableMode(affectedAbility)
|
||||
&& player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) {
|
||||
|
|
@ -146,7 +146,6 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
|
|||
game.getState().setValue("offering_ok_" + card.getId(), true);
|
||||
game.getState().setValue("offering_Id_" + card.getId(), activationId);
|
||||
return true;
|
||||
|
||||
}
|
||||
} else {
|
||||
game.getState().setValue("offering_" + card.getId(), true);
|
||||
|
|
@ -201,7 +200,7 @@ class OfferingCostReductionEffect extends CostModificationEffectImpl {
|
|||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
Object object = game.getState().getValue("offering_Id_" + card.getId());
|
||||
if (object != null && ((UUID) object).equals(this.activationId) && offeredPermanent.getPermanent(game) != null) {
|
||||
if (object != null && object.equals(this.activationId) && offeredPermanent.getPermanent(game) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -619,9 +619,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (hasProtectionFrom(source, game)) {
|
||||
return false;
|
||||
}
|
||||
return !hasProtectionFrom(source, game);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1122,6 +1120,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
@Override
|
||||
public boolean playLand(Card card, Game game, boolean ignoreTiming) {
|
||||
// Check for alternate casting possibilities: e.g. land with Morph
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
ActivatedAbility playLandAbility = null;
|
||||
boolean found = false;
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
|
|
@ -1342,7 +1343,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
switch (((SpellAbility) ability).getSpellAbilityType()) {
|
||||
case SPLIT_FUSED:
|
||||
if (zone == Zone.HAND) {
|
||||
if (((SpellAbility) ability).canChooseTarget(game)) {
|
||||
if (ability.canChooseTarget(game)) {
|
||||
useable.put(ability.getId(), (SpellAbility) ability);
|
||||
}
|
||||
}
|
||||
|
|
@ -1456,37 +1457,39 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
for (ActivatedAbility ability : otherAbilities) {
|
||||
if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
|
||||
Card card = game.getCard(ability.getSourceId());
|
||||
if (card.isSplitCard() && ability instanceof FlashbackAbility) {
|
||||
FlashbackAbility flashbackAbility;
|
||||
// Left Half
|
||||
if (card.isInstant()) {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.INSTANT);
|
||||
} else {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.SORCERY);
|
||||
}
|
||||
flashbackAbility.setSourceId(card.getId());
|
||||
flashbackAbility.setControllerId(card.getOwnerId());
|
||||
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_LEFT);
|
||||
flashbackAbility.setAbilityName(((SplitCard) card).getLeftHalfCard().getName());
|
||||
if (flashbackAbility.canActivate(playerId, game).canActivate()) {
|
||||
useable.put(flashbackAbility.getId(), flashbackAbility);
|
||||
}
|
||||
// Right Half
|
||||
if (card.isInstant()) {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.INSTANT);
|
||||
} else {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.SORCERY);
|
||||
}
|
||||
flashbackAbility.setSourceId(card.getId());
|
||||
flashbackAbility.setControllerId(card.getOwnerId());
|
||||
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_RIGHT);
|
||||
flashbackAbility.setAbilityName(((SplitCard) card).getRightHalfCard().getName());
|
||||
if (flashbackAbility.canActivate(playerId, game).canActivate()) {
|
||||
useable.put(flashbackAbility.getId(), flashbackAbility);
|
||||
}
|
||||
if (card != null) {
|
||||
if (card.isSplitCard() && ability instanceof FlashbackAbility) {
|
||||
FlashbackAbility flashbackAbility;
|
||||
// Left Half
|
||||
if (card.isInstant()) {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.INSTANT);
|
||||
} else {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getLeftHalfCard().getManaCost(), TimingRule.SORCERY);
|
||||
}
|
||||
flashbackAbility.setSourceId(card.getId());
|
||||
flashbackAbility.setControllerId(card.getOwnerId());
|
||||
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_LEFT);
|
||||
flashbackAbility.setAbilityName(((SplitCard) card).getLeftHalfCard().getName());
|
||||
if (flashbackAbility.canActivate(playerId, game).canActivate()) {
|
||||
useable.put(flashbackAbility.getId(), flashbackAbility);
|
||||
}
|
||||
// Right Half
|
||||
if (card.isInstant()) {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.INSTANT);
|
||||
} else {
|
||||
flashbackAbility = new FlashbackAbility(((SplitCard) card).getRightHalfCard().getManaCost(), TimingRule.SORCERY);
|
||||
}
|
||||
flashbackAbility.setSourceId(card.getId());
|
||||
flashbackAbility.setControllerId(card.getOwnerId());
|
||||
flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_RIGHT);
|
||||
flashbackAbility.setAbilityName(((SplitCard) card).getRightHalfCard().getName());
|
||||
if (flashbackAbility.canActivate(playerId, game).canActivate()) {
|
||||
useable.put(flashbackAbility.getId(), flashbackAbility);
|
||||
}
|
||||
|
||||
} else {
|
||||
useable.put(ability.getId(), ability);
|
||||
} else {
|
||||
useable.put(ability.getId(), ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1690,9 +1693,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
leftForUntap = getPermanentsThatCanBeUntapped(game, canBeUntapped, handledEntry.getKey().getKey(), notMoreThanEffectsUsage);
|
||||
// remove already selected permanents
|
||||
for (Permanent permanent : selectedToUntap) {
|
||||
if (leftForUntap.contains(permanent)) {
|
||||
leftForUntap.remove(permanent);
|
||||
}
|
||||
leftForUntap.remove(permanent);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -1961,7 +1962,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
sourceControllerId = ((Card) source).getOwnerId();
|
||||
} else if (source instanceof CommandObject) {
|
||||
sourceControllerId = ((CommandObject) source).getControllerId();
|
||||
sourceAbilities = ((CommandObject) source).getAbilities();
|
||||
sourceAbilities = source.getAbilities();
|
||||
}
|
||||
} else {
|
||||
sourceAbilities = ((Permanent) source).getAbilities(game);
|
||||
|
|
@ -2847,9 +2848,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (canPlayCardByAlternateCost(card, available, ability, game)) {
|
||||
return true;
|
||||
}
|
||||
return canPlayCardByAlternateCost(card, available, ability, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3582,7 +3581,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
case OUTSIDE:
|
||||
for (Card card : cards) {
|
||||
if (card instanceof Permanent) {
|
||||
game.getBattlefield().removePermanent(((Permanent) card).getId());
|
||||
game.getBattlefield().removePermanent(card.getId());
|
||||
ZoneChangeEvent event = new ZoneChangeEvent(card.getId(), (source == null ? null : source.getSourceId()),
|
||||
byOwner ? card.getOwnerId() : getId(), Zone.BATTLEFIELD, Zone.OUTSIDE, appliedEffects);
|
||||
game.fireEvent(event);
|
||||
|
|
@ -3731,7 +3730,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
boolean result = false;
|
||||
// Zone fromZone = game.getState().getZone(card.getId());
|
||||
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone == Zone.BATTLEFIELD : false)) {
|
||||
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null && fromZone == Zone.BATTLEFIELD)) {
|
||||
if (!game.isSimulation()) {
|
||||
if (card instanceof PermanentCard && game.getCard(card.getId()) != null) {
|
||||
card = game.getCard(card.getId());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue