Added card Okk. Incluedes a new restriction effect called "canBlockCheckAfter", an update to the combat sequence where this restriction is taken into considiration and a new test which assert the behaviour of the effect.

This commit is contained in:
icetc 2016-02-01 13:30:08 +01:00
parent 81af372bc1
commit cc7b7ec2a2
6 changed files with 307 additions and 3 deletions

View file

@ -0,0 +1,52 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eighthedition;
import java.util.UUID;
/**
*
* @author icetc
*/
public class Okk extends mage.sets.urzassaga.Okk {
public Okk(UUID ownerId) {
super(ownerId);
this.cardNumber = 206;
this.expansionSetCode = "8ED";
}
public Okk(final Okk card) {
super(card);
}
@Override
public Okk copy() {
return new Okk(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.seventhedition;
import java.util.UUID;
/**
*
* @author icetc
*/
public class Okk extends mage.sets.urzassaga.Okk {
public Okk(UUID ownerId) {
super(ownerId);
this.cardNumber = 204;
this.expansionSetCode = "7ED";
}
public Okk(final Okk card) {
super(card);
}
@Override
public Okk copy() {
return new Okk(this);
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.urzassaga;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.RestrictionEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterAttackingCreature;
import mage.filter.common.FilterBlockingCreature;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author icetc
*/
public class Okk extends CardImpl {
public Okk(UUID ownerId) {
super(ownerId, 204, "Okk", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.expansionSetCode = "USG";
this.subtype.add("Goblin");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Okk can't attack unless a creature with greater power also attacks.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OkkAttackEffect()));
// Okk can't block unless a creature with greater power also blocks.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OkkBlockEffect()));
}
public Okk(final Okk card) {
super(card);
}
@Override
public Okk copy() {
return new Okk(this);
}
}
class OkkAttackEffect extends RestrictionEffect {
private static final FilterAttackingCreature filter = new FilterAttackingCreature("Attacking creatures");
public OkkAttackEffect() {
super(Duration.WhileOnBattlefield);
staticText = "{this} can't attack unless a creature with greater power also attacks";
}
public OkkAttackEffect(final OkkAttackEffect effect) {
super(effect);
}
@Override
public OkkAttackEffect copy() {
return new OkkAttackEffect(this);
}
@Override
public boolean canAttackCheckAfter(int numberOfAttackers, Ability source, Game game) {
return false;
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
// Search for an attacking creature with greater power
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (creature.getPower().getValue() > permanent.getPower().getValue()) {
return false;
}
}
return true;
}
return false;
}
}
class OkkBlockEffect extends RestrictionEffect {
private static final FilterBlockingCreature filter = new FilterBlockingCreature("Blocking creatures");
public OkkBlockEffect() {
super(Duration.WhileOnBattlefield);
staticText = "{this} can't block unless a creature with greater power also blocks.";
}
public OkkBlockEffect(final OkkBlockEffect effect) {
super(effect);
}
@Override
public OkkBlockEffect copy() {
return new OkkBlockEffect(this);
}
@Override
public boolean canBlockCheckAfter(Ability source, Game game) {
return false;
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
// Search for a blocking creature with greater power
for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (creature.getPower().getValue() > permanent.getPower().getValue()) {
return false;
}
}
return true;
}
return false;
}
}

View file

@ -34,7 +34,7 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
* @author LevelX2, icetc
*/
public class BlockRequirementTest extends CardTestPlayerBase {
@ -154,6 +154,33 @@ public class BlockRequirementTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Pillarfield Ox", 1);
assertLife(playerB, 18);
}
/**
* Okk is red creature that can't block unless a creature with greater power also blocks.
*/
@Test
public void testOkkBlocking() {
// 3/3 Vanilla creature
addCard(Zone.BATTLEFIELD, playerA, "Hill Giant", 1);
// 4/4 Goblin:
// Okk can't attack unless a creature with greater power also attacks.
// Okk can't block unless a creature with greater power also blocks.
addCard(Zone.BATTLEFIELD, playerB, "Okk", 1); //
attack(1, playerA, "Hill Giant");
// Not allowed because of Okk's blocking restrictions
block(1, playerB, "Okk", "Hill Giant");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
// Hill giant is still alive and Played B looses 3 lives
assertPermanentCount(playerA, "Hill Giant", 1);
assertLife(playerB, 17);
}
}

View file

@ -77,10 +77,14 @@ public abstract class RestrictionEffect extends ContinuousEffectImpl {
return true;
}
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
public boolean canBlockCheckAfter(Ability source, Game game) {
return true;
}
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
return true;
}
/**
* Called for all attackers after all blocking decisions are made
*

View file

@ -910,6 +910,27 @@ public class Combat implements Serializable, Copyable<Combat> {
* @return
*/
public boolean checkBlockRestrictionsAfter(Player player, Player controller, Game game) {
// Restrictions applied to blocking creatures
for (UUID blockingCreatureId : this.getBlockers()) {
Permanent blockingCreature = game.getPermanent(blockingCreatureId);
if (blockingCreature != null) {
for (Map.Entry<RestrictionEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(blockingCreature, game).entrySet()) {
RestrictionEffect effect = entry.getKey();
for (Ability ability : entry.getValue()) {
if (!effect.canBlockCheckAfter(ability, game)) {
if (controller.isHuman()) {
game.informPlayer(controller, new StringBuilder(blockingCreature.getLogName()).append(" can't block this way.").toString());
return false;
} else {
// remove blocking creatures for AI
removeBlocker(blockingCreatureId, game);
}
}
}
}
}
}
// Restrictions applied because of attacking creatures
for (UUID attackingCreatureId : this.getAttackers()) {
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
if (attackingCreature != null) {
@ -929,7 +950,6 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
}
}
}
}