use of mage.game.stack.StackObject in project mage by magefree.
the class TomikDistinguishedAdvokistRestrictionEffect method applies.
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Card targetCard = game.getCard(event.getTargetId());
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
Player player = game.getPlayer(source.getControllerId());
return targetCard != null && stackObject != null && player != null && player.hasOpponent(stackObject.getControllerId(), game) && game.getState().getZone(targetCard.getId()) == Zone.GRAVEYARD && targetCard.isLand(game);
}
use of mage.game.stack.StackObject in project mage by magefree.
the class ExileTargetEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Set<Card> toExile = new LinkedHashSet<>();
if (multitargetHandling && targetPointer instanceof FirstTargetPointer && (source.getTargets().size() > 1 || (source.getTargets().size() > 0 && source.getTargets().get(0).getTargets().size() > 1))) {
for (Target target : source.getTargets()) {
for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null && permanent.isPhasedIn()) {
Zone currentZone = game.getState().getZone(permanent.getId());
if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == Zone.BATTLEFIELD)) {
toExile.add(permanent);
}
} else {
Card card = game.getCard(targetId);
if (card != null) {
Zone currentZone = game.getState().getZone(card.getId());
if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == currentZone)) {
toExile.add(card);
}
} else {
StackObject stackObject = game.getStack().getStackObject(targetId);
if (stackObject instanceof Spell) {
toExile.add((Spell) stackObject);
}
}
}
}
}
} else {
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null && permanent.isPhasedIn()) {
Zone currentZone = game.getState().getZone(permanent.getId());
if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == Zone.BATTLEFIELD)) {
toExile.add(permanent);
}
} else {
Card card = game.getCard(targetId);
if (card != null) {
Zone currentZone = game.getState().getZone(card.getId());
if (currentZone != Zone.EXILED && (onlyFromZone == null || onlyFromZone == currentZone)) {
toExile.add(card);
}
} else {
StackObject stackObject = game.getStack().getStackObject(targetId);
if (stackObject instanceof Spell) {
toExile.add((Spell) stackObject);
}
}
}
}
}
if (toSourceExileZone) {
MageObject sourceObject = source.getSourceObject(game);
exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (sourceObject != null) {
exileZone = sourceObject.getIdName();
}
}
controller.moveCardsToExile(toExile, source, game, withName, exileId, exileZone);
return true;
}
return false;
}
use of mage.game.stack.StackObject in project mage by magefree.
the class PermanentImpl method doDamage.
/**
* @param damageAmount
* @param attackerId id of the permanent or player who make damage (source.getSourceId() in most cases)
* @param source
* @param game
* @param preventable
* @param combat
* @param markDamage If true, damage will be dealt later in applyDamage
* method, uses only in inner markDamage.
* @return
*/
private int doDamage(int damageAmount, UUID attackerId, Ability source, Game game, boolean preventable, boolean combat, boolean markDamage, List<UUID> appliedEffects) {
int damageDone = 0;
if (damageAmount < 1 || !canDamage(game.getObject(attackerId), game)) {
return 0;
}
DamageEvent event = new DamagePermanentEvent(objectId, attackerId, controllerId, damageAmount, preventable, combat);
event.setAppliedEffects(appliedEffects);
if (game.replaceEvent(event)) {
return 0;
}
int actualDamage = checkProtectionAbilities(event, attackerId, source, game);
if (actualDamage < 1) {
return 0;
}
int lethal = getLethalDamage(attackerId, game);
MageObject attacker = game.getObject(attackerId);
if (this.isCreature(game)) {
if (checkWither(event, attacker, game)) {
if (markDamage) {
// mark damage only
markDamage(CounterType.M1M1.createInstance(actualDamage), attacker, true);
} else {
Ability damageSourceAbility = null;
if (attacker instanceof Permanent) {
damageSourceAbility = ((Permanent) attacker).getSpellAbility();
}
// deal damage immediately
addCounters(CounterType.M1M1.createInstance(actualDamage), game.getControllerId(attackerId), damageSourceAbility, game);
}
} else {
this.damage = CardUtil.overflowInc(this.damage, actualDamage);
}
}
if (this.isPlaneswalker(game)) {
int loyalty = getCounters(game).getCount(CounterType.LOYALTY);
int countersToRemove = Math.min(actualDamage, loyalty);
if (attacker != null && markDamage) {
markDamage(CounterType.LOYALTY.createInstance(countersToRemove), attacker, false);
} else {
removeCounters(CounterType.LOYALTY.getName(), countersToRemove, source, game);
}
}
DamagedEvent damagedEvent = new DamagedPermanentEvent(this.getId(), attackerId, this.getControllerId(), actualDamage, combat);
damagedEvent.setExcess(actualDamage - lethal);
game.fireEvent(damagedEvent);
game.getState().addSimultaneousDamage(damagedEvent, game);
damageDone = actualDamage;
if (damageDone < 1) {
return 0;
}
UUID sourceControllerId = null;
Abilities sourceAbilities = null;
attacker = game.getPermanentOrLKIBattlefield(attackerId);
if (attacker == null) {
StackObject stackObject = game.getStack().getStackObject(attackerId);
if (stackObject != null) {
attacker = stackObject.getStackAbility().getSourceObject(game);
} else {
attacker = game.getObject(attackerId);
}
if (attacker instanceof Spell) {
sourceAbilities = ((Spell) attacker).getAbilities(game);
sourceControllerId = ((Spell) attacker).getControllerId();
} else if (attacker instanceof Card) {
sourceAbilities = ((Card) attacker).getAbilities(game);
sourceControllerId = ((Card) attacker).getOwnerId();
} else if (attacker instanceof CommandObject) {
sourceControllerId = ((CommandObject) attacker).getControllerId();
sourceAbilities = attacker.getAbilities();
} else {
attacker = null;
}
} else {
sourceAbilities = ((Permanent) attacker).getAbilities(game);
sourceControllerId = ((Permanent) attacker).getControllerId();
}
if (attacker != null && sourceAbilities != null) {
if (sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) {
if (markDamage) {
game.getPermanent(attackerId).markLifelink(damageDone);
} else {
Player player = game.getPlayer(sourceControllerId);
player.gainLife(damageDone, game, source);
}
}
if (sourceAbilities.containsKey(DeathtouchAbility.getInstance().getId())) {
deathtouched = true;
}
if (dealtDamageByThisTurn == null) {
dealtDamageByThisTurn = new HashSet<>();
}
// Unstable ability - Earl of Squirrel
if (sourceAbilities.containsKey(SquirrellinkAbility.getInstance().getId())) {
Player player = game.getPlayer(sourceControllerId);
new SquirrelToken().putOntoBattlefield(damageDone, game, source, player.getId());
}
dealtDamageByThisTurn.add(new MageObjectReference(attacker, game));
}
if (attacker == null) {
game.informPlayers(getLogName() + " gets " + damageDone + " damage");
} else {
game.informPlayers(attacker.getLogName() + " deals " + damageDone + " damage to " + getLogName());
}
return damageDone;
}
use of mage.game.stack.StackObject in project mage by magefree.
the class DjinnIlluminatusGainReplicateEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Permanent djinn = game.getPermanent(source.getSourceId());
if (djinn == null) {
return false;
}
for (StackObject stackObject : game.getStack()) {
// only spells cast, so no copies of spells
if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId()) && // verify that the controller of the djinn cast that spell
djinn.isControlledBy(source.getControllerId()) && !stackObject.getManaCost().isEmpty()) {
// handle cases like Ancestral Vision
Spell spell = (Spell) stackObject;
if (filter.match(stackObject, game)) {
ReplicateAbility replicateAbility = replicateAbilities.computeIfAbsent(spell.getId(), k -> new ReplicateAbility(spell.getCard(), spell.getSpellAbility().getManaCosts().getText()));
// Do not copy because paid and # of activations state is handled in the baility
game.getState().addOtherAbility(spell.getCard(), replicateAbility, false);
}
}
}
if (game.getStack().isEmpty()) {
replicateAbilities.clear();
}
return true;
}
use of mage.game.stack.StackObject in project mage by magefree.
the class ForceChokeEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
StackObject stackObject = (StackObject) game.getObject(getTargetPointer().getFirst(game, source));
Player objectController = game.getPlayer(stackObject.getControllerId());
if (player != null) {
Cost cost = new PayLifeCost(stackObject.getManaValue());
if (cost.canPay(source, source, objectController.getId(), game) && objectController.chooseUse(Outcome.LoseLife, "Pay " + stackObject.getManaValue() + " life?", source, game) && cost.pay(source, game, source, objectController.getId(), false, null)) {
objectController.moveCards((Card) stackObject, Zone.HAND, source, game);
} else {
game.getStack().counter(stackObject.getId(), source, game);
}
return true;
}
return false;
}
Aggregations