use of mage.game.events.GameEvent in project mage by magefree.
the class AbilityImpl method activate.
@Override
public boolean activate(Game game, boolean noMana) {
Player controller = game.getPlayer(this.getControllerId());
if (controller == null) {
return false;
}
game.applyEffects();
MageObject sourceObject = getSourceObject(game);
if (getSourceObjectZoneChangeCounter() == 0) {
setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(getSourceId()));
}
setSourcePermanentTransformCount(game);
/* 20130201 - 601.2b
* If the player wishes to splice any cards onto the spell (see rule 702.45), he
* or she reveals those cards in their hand.
*/
if (this.abilityType == AbilityType.SPELL) {
game.getContinuousEffects().applySpliceEffects(this, game);
}
// For Flashback ability can be set X before, so the X costs have to be restored for the flashbacked ability
if (noMana) {
if (!this.getManaCostsToPay().getVariableCosts().isEmpty()) {
int xValue = this.getManaCostsToPay().getX();
this.getManaCostsToPay().clear();
VariableManaCost xCosts = new VariableManaCost(VariableCostType.ADDITIONAL);
// no x events - rules from Unbound Flourishing:
// - Spells with additional costs that include X won't be affected by Unbound Flourishing. X must be in the spell's mana cost.
xCosts.setAmount(xValue, xValue, false);
this.getManaCostsToPay().add(xCosts);
} else {
this.getManaCostsToPay().clear();
}
}
// A player can't apply two alternative methods of casting or two alternative costs to a single spell.
if (!activateAlternateOrAdditionalCosts(sourceObject, noMana, controller, game)) {
if (getAbilityType() == AbilityType.SPELL && ((SpellAbility) this).getSpellAbilityType() == SpellAbilityType.FACE_DOWN_CREATURE) {
return false;
}
}
// }
if (getAbilityType() == AbilityType.SPELL && (getManaCostsToPay().isEmpty() && getCosts().isEmpty()) && !noMana) {
return false;
}
// 20121001 - 601.2b
// If the spell has a variable cost that will be paid as it's being cast (such as an {X} in
// its mana cost; see rule 107.3), the player announces the value of that variable.
VariableManaCost variableManaCost = handleManaXCosts(game, noMana, controller);
String announceString = handleOtherXCosts(game, controller);
// For effects from cards like Void Winnower x costs have to be set
if (this.getAbilityType() == AbilityType.SPELL) {
GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL_LATE, this.getId(), this, getControllerId());
castEvent.setZone(game.getState().getZone(CardUtil.getMainCardId(game, sourceId)));
if (game.replaceEvent(castEvent, this)) {
return false;
}
}
handlePhyrexianManaCosts(game, controller);
// Kicking a spell is always optional.
if (!getModes().choose(game, this)) {
return false;
}
// 2. From single addTarget/setChoice, it's a preffered method for tests (process it in normal choose dialogs like human player)
if (controller.isTestsMode()) {
if (!controller.addTargets(this, game)) {
return false;
}
}
for (UUID modeId : this.getModes().getSelectedModes()) {
this.getModes().setActiveMode(modeId);
if (sourceObject != null && this.getAbilityType() != AbilityType.TRIGGERED) {
// triggered abilities check this already in playerImpl.triggerAbility
sourceObject.adjustTargets(this, game);
}
if (!getTargets().isEmpty()) {
Outcome outcome = getEffects().getOutcome(this);
// only activated abilities can be canceled by human user (not triggered)
boolean canCancel = this instanceof ActivatedAbility && controller.isHuman();
if (!getTargets().chooseTargets(outcome, this.controllerId, this, noMana, game, canCancel)) {
// was canceled during targer selection
return false;
}
}
}
// this is a hack to prevent mana abilities with mana costs from causing endless loops - pay other costs first
if (this instanceof ActivatedManaAbilityImpl && !costs.pay(this, game, this, controllerId, noMana, null)) {
logger.debug("activate mana ability failed - non mana costs");
return false;
}
// fused spell contains 3 abilities (fused, left, right)
// fused cost added to fused ability, so no need cost modification for other parts
boolean needCostModification = !CardUtil.isFusedPartAbility(this, game);
// 20101001 - 601.2e
if (needCostModification && sourceObject != null) {
// still needed for CostAdjuster objects (to handle some types of dynamic costs)
sourceObject.adjustCosts(this, game);
game.getContinuousEffects().costModification(this, game);
}
UUID activatorId = controllerId;
if ((this instanceof ActivatedAbilityImpl) && ((ActivatedAbilityImpl) this).getActivatorId() != null) {
activatorId = ((ActivatedAbilityImpl) this).getActivatorId();
}
// 20100716 - 601.2f (noMana is not used here, because mana costs were cleared for this ability before adding additional costs and applying cost modification effects)
if (!manaCostsToPay.pay(this, game, this, activatorId, false, null)) {
// cancel during mana payment
return false;
}
// 20100716 - 601.2g
if (!costs.pay(this, game, this, activatorId, noMana, null)) {
logger.debug("activate failed - non mana costs");
return false;
}
// inform about x costs now, so canceled announcements are not shown in the log
if ((announceString != null) && (!announceString.equals(""))) {
game.informPlayers(announceString);
}
if (variableManaCost != null) {
int xValue = getManaCostsToPay().getX();
game.informPlayers(controller.getLogName() + " announces a value of " + xValue + " for " + variableManaCost.getText());
}
activated = true;
return true;
}
use of mage.game.events.GameEvent in project mage by magefree.
the class AbilityImpl method handleManaXMultiplier.
public int handleManaXMultiplier(Game game, int value) {
// some spells can change X value without new pays (Unbound Flourishing doubles X)
GameEvent xEvent = GameEvent.getEvent(GameEvent.EventType.X_MANA_ANNOUNCE, this.getId(), this, getControllerId(), value);
game.replaceEvent(xEvent, this);
return xEvent.getAmount();
}
use of mage.game.events.GameEvent in project mage by magefree.
the class SpellAbility method canActivate.
@Override
public ActivationStatus canActivate(UUID playerId, Game game) {
if (this.spellCanBeActivatedRegularlyNow(playerId, game)) {
if (spellAbilityType == SpellAbilityType.SPLIT || spellAbilityType == SpellAbilityType.SPLIT_AFTERMATH) {
return ActivationStatus.getFalse();
}
// play from not own hand
ApprovingObject approvingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this, playerId, game);
if (approvingObject == null) {
Card card = game.getCard(sourceId);
if (!(card != null && card.isOwnedBy(playerId))) {
return ActivationStatus.getFalse();
}
}
// Check if rule modifying events prevent to cast the spell in check playable mode
if (game.inCheckPlayableState()) {
Card card = game.getCard(sourceId);
GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, this.getId(), this, playerId);
castEvent.setZone(card == null ? null : game.getState().getZone(card.getMainCard().getId()));
if (game.getContinuousEffects().preventedByRuleModification(castEvent, this, game, true)) {
return ActivationStatus.getFalse();
}
}
// Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option
if (getSpellAbilityType() == SpellAbilityType.BASE_ALTERNATE) {
Player player = game.getPlayer(playerId);
if (player != null && player.getCastSourceIdWithAlternateMana().contains(getSourceId())) {
return ActivationStatus.getFalse();
}
}
// can pay all costs and choose targets
if (costs.canPay(this, this, playerId, game)) {
if (getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
SplitCard splitCard = (SplitCard) game.getCard(getSourceId());
if (splitCard != null) {
// see https://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/251926-snapcaster-mage-and-fuse
if (game.getState().getZone(splitCard.getId()) == Zone.HAND) {
return new ActivationStatus(splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game, playerId) && splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game, playerId), null);
}
}
return ActivationStatus.getFalse();
} else {
return new ActivationStatus(canChooseTarget(game, playerId), approvingObject);
}
}
}
return ActivationStatus.getFalse();
}
use of mage.game.events.GameEvent in project mage by magefree.
the class CumulativeUpkeepEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
int ageCounter = permanent.getCounters(game).getCount(CounterType.AGE);
if (cumulativeCost instanceof ManaCost) {
ManaCostsImpl totalCost = new ManaCostsImpl<>();
for (int i = 0; i < ageCounter; i++) {
totalCost.add((ManaCost) cumulativeCost.copy());
}
if (player.chooseUse(Outcome.Benefit, "Pay " + totalCost.getText() + '?', source, game)) {
totalCost.clearPaid();
if (totalCost.payOrRollback(source, game, source, source.getControllerId())) {
game.fireEvent(new ManaEvent(EventType.PAID_CUMULATIVE_UPKEEP, permanent.getId(), source, player.getId(), totalCost.getUsedManaToPay()));
return true;
}
}
game.fireEvent(new GameEvent(GameEvent.EventType.DIDNT_PAY_CUMULATIVE_UPKEEP, permanent.getId(), source, player.getId(), ageCounter, false));
if (source.getControllerId().equals(permanent.getControllerId())) {
// Permanent can only be sacrificed if you still control it
permanent.sacrifice(source, game);
}
return true;
} else {
CostsImpl<Cost> totalCost = new CostsImpl<>();
for (int i = 0; i < ageCounter; i++) {
totalCost.add(cumulativeCost.copy());
}
if (player.chooseUse(Outcome.Benefit, totalCost.getText() + '?', source, game)) {
totalCost.clearPaid();
int bookmark = game.bookmarkState();
if (totalCost.pay(source, game, source, source.getControllerId(), false, null)) {
game.fireEvent(new GameEvent(GameEvent.EventType.PAID_CUMULATIVE_UPKEEP, permanent.getId(), source, player.getId(), ageCounter, false));
return true;
} else {
player.restoreState(bookmark, source.getRule(), game);
}
}
game.fireEvent(new GameEvent(GameEvent.EventType.DIDNT_PAY_CUMULATIVE_UPKEEP, permanent.getId(), source, player.getId(), ageCounter, false));
permanent.sacrifice(source, game);
return true;
}
}
return false;
}
use of mage.game.events.GameEvent in project mage by magefree.
the class CandlesGlowPreventDamageTargetEffect method replaceEvent.
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new PreventDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), event.getAmount(), ((DamageEvent) event).isCombatDamage());
if (!game.replaceEvent(preventEvent)) {
int prevented;
if (event.getAmount() >= this.amount) {
int damage = amount;
event.setAmount(event.getAmount() - amount);
this.used = true;
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
prevented = damage;
} else {
int damage = event.getAmount();
event.setAmount(0);
amount -= damage;
game.fireEvent(new PreventedDamageEvent(event.getTargetId(), source.getSourceId(), source, source.getControllerId(), damage));
prevented = damage;
}
// add live now
if (prevented > 0) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.gainLife(prevented, game, source);
game.informPlayers("Candles' Glow: Prevented " + prevented + " damage ");
game.informPlayers("Candles' Glow: " + controller.getLogName() + " gained " + prevented + "life");
}
}
}
return false;
}
Aggregations