mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
[MH2] Implemented Chef's Kiss
This commit is contained in:
parent
d202278ccd
commit
b75c09688c
4 changed files with 156 additions and 2 deletions
151
Mage.Sets/src/mage/cards/c/ChefsKiss.java
Normal file
151
Mage.Sets/src/mage/cards/c/ChefsKiss.java
Normal file
|
@ -0,0 +1,151 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.MageItem;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.util.RandomUtil;
|
||||
import mage.util.TargetAddress;
|
||||
import mage.util.functions.StackObjectCopyApplier;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ChefsKiss extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter
|
||||
= new FilterSpell("spell that targets only a single permanent or player");
|
||||
|
||||
static {
|
||||
filter.add(ChefsKissPredicate.instance);
|
||||
}
|
||||
|
||||
public ChefsKiss(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{R}");
|
||||
|
||||
// Gain control of target spell that targets only a single permanent or player. Copy it, then reselect the targets at random for the spell and the copy. The new targets can't be you or a permanent you control.
|
||||
this.getSpellAbility().addEffect(new ChefsKissEffect());
|
||||
this.getSpellAbility().addTarget(new TargetSpell(filter));
|
||||
}
|
||||
|
||||
private ChefsKiss(final ChefsKiss card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChefsKiss copy() {
|
||||
return new ChefsKiss(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum ChefsKissPredicate implements Predicate<StackObject> {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(StackObject input, Game game) {
|
||||
Spell spell = (Spell) input;
|
||||
Set<UUID> targets = new HashSet<>();
|
||||
for (TargetAddress addr : TargetAddress.walk(spell)) {
|
||||
Target targetInstance = addr.getTarget(spell);
|
||||
for (UUID target : targetInstance.getTargets()) {
|
||||
if (game.getPermanent(target) != null || game.getPlayer(target) != null) {
|
||||
targets.add(target);
|
||||
}
|
||||
if (targets.size() > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return targets.size() == 1;
|
||||
}
|
||||
}
|
||||
|
||||
class ChefsKissEffect extends OneShotEffect {
|
||||
|
||||
ChefsKissEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "gain control of target spell that targets only a single permanent or player. " +
|
||||
"Copy it, then reselect the targets at random for the spell and the copy. " +
|
||||
"The new targets can't be you or a permanent you control";
|
||||
}
|
||||
|
||||
private ChefsKissEffect(final ChefsKissEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChefsKissEffect copy() {
|
||||
return new ChefsKissEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Spell spell = game.getSpell(source.getFirstTarget());
|
||||
if (spell == null) {
|
||||
return false;
|
||||
}
|
||||
spell.setControllerId(source.getControllerId());
|
||||
List<UUID> possibleTargets = new ArrayList<>(game.getState().getPlayersInRange(source.getControllerId(), game));
|
||||
possibleTargets.remove(source.getControllerId());
|
||||
game.getBattlefield()
|
||||
.getActivePermanents(source.getControllerId(), game)
|
||||
.stream()
|
||||
.filter(p -> !p.isControlledBy(source.getControllerId()))
|
||||
.map(MageItem::getId)
|
||||
.forEach(possibleTargets::add);
|
||||
possibleTargets.removeIf(uuid -> !spell.canTarget(game, uuid));
|
||||
StackObjectCopyApplier applier;
|
||||
MageObjectReferencePredicate predicate;
|
||||
if (possibleTargets.isEmpty()) {
|
||||
applier = null;
|
||||
predicate = null;
|
||||
} else {
|
||||
applier = new ChefsKissApplier(possibleTargets.get(RandomUtil.nextInt(possibleTargets.size())), game);
|
||||
predicate = new MageObjectReferencePredicate(new MageObjectReference(
|
||||
possibleTargets.get(RandomUtil.nextInt(possibleTargets.size())), game
|
||||
));
|
||||
}
|
||||
spell.createCopyOnStack(game, source, source.getControllerId(), false, 1, applier);
|
||||
if (predicate != null) {
|
||||
spell.chooseNewTargets(game, source.getControllerId(), true, true, predicate);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class ChefsKissApplier implements StackObjectCopyApplier {
|
||||
|
||||
private final Iterator<MageObjectReferencePredicate> predicate;
|
||||
|
||||
ChefsKissApplier(UUID targetId, Game game) {
|
||||
this.predicate = Arrays.asList(new MageObjectReferencePredicate(
|
||||
new MageObjectReference(targetId, game)
|
||||
)).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifySpell(StackObject stackObject, Game game) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MageObjectReferencePredicate getNextPredicate() {
|
||||
if (predicate.hasNext()) {
|
||||
return predicate.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@ public final class ModernHorizons2 extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Chance Encounter", 277, Rarity.RARE, mage.cards.c.ChanceEncounter.class));
|
||||
cards.add(new SetCardInfo("Chatterfang, Squirrel General", 151, Rarity.MYTHIC, mage.cards.c.ChatterfangSquirrelGeneral.class));
|
||||
cards.add(new SetCardInfo("Chatterstorm", 152, Rarity.COMMON, mage.cards.c.Chatterstorm.class));
|
||||
cards.add(new SetCardInfo("Chef's Kiss", 120, Rarity.RARE, mage.cards.c.ChefsKiss.class));
|
||||
cards.add(new SetCardInfo("Clattering Augur", 79, Rarity.UNCOMMON, mage.cards.c.ClatteringAugur.class));
|
||||
cards.add(new SetCardInfo("Chitterspitter", 153, Rarity.RARE, mage.cards.c.Chitterspitter.class));
|
||||
cards.add(new SetCardInfo("Chrome Courier", 190, Rarity.COMMON, mage.cards.c.ChromeCourier.class));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.game.stack;
|
||||
|
||||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Zone;
|
||||
|
@ -28,7 +29,7 @@ public interface StackObject extends MageObject, Controllable {
|
|||
|
||||
Ability getStackAbility();
|
||||
|
||||
boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget, Predicate extraPredicate);
|
||||
boolean chooseNewTargets(Game game, UUID playerId, boolean forceChange, boolean onlyOneTarget, Predicate<MageItem> extraPredicate);
|
||||
|
||||
boolean canTarget(Game game, UUID targetId);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.game.stack;
|
||||
|
||||
import mage.MageItem;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
|
@ -219,7 +220,7 @@ public abstract class StackObjectImpl implements StackObject {
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean chooseNewTargets(Game game, UUID targetControllerId, boolean forceChange, boolean onlyOneTarget, Predicate extraPredicate) {
|
||||
public boolean chooseNewTargets(Game game, UUID targetControllerId, boolean forceChange, boolean onlyOneTarget, Predicate<MageItem> extraPredicate) {
|
||||
Player targetController = game.getPlayer(targetControllerId);
|
||||
if (targetController != null) {
|
||||
StringBuilder oldTargetDescription = new StringBuilder();
|
||||
|
|
Loading…
Reference in a new issue