* Tromokratis - added first implementation (can't handle forced block conflicts yet)

This commit is contained in:
LevelX2 2014-01-28 17:05:30 +01:00
parent 89ac171b24
commit 99c51f8091
3 changed files with 81 additions and 51 deletions

View file

@ -44,7 +44,9 @@ import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent;
/**
@ -99,20 +101,29 @@ class CantBeBlockedUnlessAllEffect extends RestrictionEffect<CantBeBlockedUnless
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(source.getSourceId())) {
return true;
}
return false;
return permanent.getId().equals(source.getSourceId());
}
@Override
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
if (blocker.getPower().getValue() < attacker.getPower().getValue()) {
return false;
public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) {
for (CombatGroup combatGroup: game.getCombat().getGroups()) {
if (combatGroup.getAttackers().contains(source.getSourceId())) {
for(UUID blockerId :combatGroup.getBlockers()) {
Permanent blockingCreature = game.getPermanent(blockerId);
if (blockingCreature != null) {
for (Permanent permanent: game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), blockingCreature.getControllerId(), game)) {
if (!combatGroup.getBlockers().contains(permanent.getId())) {
// not all creatures block Tromokratis
return false;
}
}
}
}
}
}
return true;
}
@Override
public CantBeBlockedUnlessAllEffect copy() {
return new CantBeBlockedUnlessAllEffect(this);

View file

@ -32,40 +32,23 @@ import mage.abilities.Ability;
import mage.constants.Duration;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author BetaSteward_at_googlemail.com
* @param <T>
*/
public abstract class RestrictionEffect<T extends RestrictionEffect<T>> extends ContinuousEffectImpl<T> {
private boolean notMoreThanRestriction;
private int notMoreThanNumber;
private FilterPermanent notMoreThanNumberFilter;
public RestrictionEffect(Duration duration) {
this(duration, false, 0, null);
}
public RestrictionEffect(Duration duration, boolean notMoreThanRestriction, int notMoreThanNumber, FilterPermanent notMoreThanNumberFilter) {
super(duration, Outcome.Detriment);
this.effectType = EffectType.RESTRICTION;
this.notMoreThanRestriction = notMoreThanRestriction;
this.notMoreThanNumber = notMoreThanNumber;
this.notMoreThanNumberFilter = notMoreThanNumberFilter;
this.effectType = EffectType.RESTRICTION;
}
public RestrictionEffect(final RestrictionEffect effect) {
super(effect);
this.notMoreThanRestriction = effect.notMoreThanRestriction;
this.notMoreThanNumber = effect.notMoreThanNumber;
if (this.notMoreThanNumberFilter != null) {
this.notMoreThanNumberFilter = effect.notMoreThanNumberFilter.copy();
}
}
@Override
@ -75,15 +58,6 @@ public abstract class RestrictionEffect<T extends RestrictionEffect<T>> extends
public abstract boolean applies(Permanent permanent, Ability source, Game game);
/*
* only used for the notMoreThanRestrictions, called to check if the effect shall be applied for a player
*
*/
public boolean appliesNotMoreThan(Player player, Ability source, Game game) {
return false;
}
public boolean canAttack(Game game) {
return true;
}
@ -96,6 +70,18 @@ public abstract class RestrictionEffect<T extends RestrictionEffect<T>> extends
return true;
}
/**
* Called for all attackers after all blocking decisions are made
*
* @param attacker
* @param source
* @param game
* @return true = block is ok fals = block is not valid (human: back to defining blockers, AI: remove blocker)
*/
public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) {
return true;
}
public boolean canBeUntapped(Permanent permanent, Game game) {
return true;
}
@ -103,17 +89,5 @@ public abstract class RestrictionEffect<T extends RestrictionEffect<T>> extends
public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game) {
return true;
}
public boolean isNotMoreThanRestriction() {
return notMoreThanRestriction;
}
public int getNotMoreThanNumber() {
return notMoreThanNumber;
}
public FilterPermanent getNotMoreThanNumberFilter() {
return notMoreThanNumberFilter;
}
}

View file

@ -38,6 +38,7 @@ import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.RequirementEffect;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.keyword.CanAttackOnlyAloneAbility;
import mage.abilities.keyword.CantAttackAloneAbility;
import mage.abilities.keyword.VigilanceAbility;
@ -297,8 +298,9 @@ public class Combat implements Serializable, Copyable<Combat> {
/**
* Handle the blocker selection process
*
* @param blockController player that controlls how to block, if null the defender is the controller
*
* @param blockController player that controlls how to block, if null the
* defender is the controller
* @param game
*/
public void selectBlockers(Player blockController, Game game) {
@ -323,6 +325,9 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
choose = !this.checkBlockRequirementsAfter(defender, blockController, game);
if (!choose) {
choose = !this.checkBlockRestrictionsAfter(defender, blockController, game);
}
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId));
@ -465,7 +470,7 @@ public class Combat implements Serializable, Copyable<Combat> {
// Creature is already blocking but not forced to do so
if (creature.getBlocking() > 0) {
// get all requirement effects that apply to the creature (ce.g. is able to block attacker)
// get all requirement effects that apply to the creature (e.g. is able to block attacker)
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
RequirementEffect effect = (RequirementEffect) entry.getKey();
// get possible mustBeBlockedByAtLeastOne blocker
@ -657,6 +662,46 @@ public class Combat implements Serializable, Copyable<Combat> {
return true;
}
/**
* Checks the canBeBlockedCheckAfter RestrictionEffect
* Is the block still valid after all block decisions are done
*
* @param player
* @param controller
* @param game
* @return
*/
public boolean checkBlockRestrictionsAfter(Player player, Player controller, Game game) {
for (UUID attackingCreatureId : this.getAttackers()) {
Permanent attackingCreature = game.getPermanent(attackingCreatureId);
if (attackingCreature != null) {
for (Map.Entry entry : game.getContinuousEffects().getApplicableRestrictionEffects(attackingCreature, game).entrySet()) {
RestrictionEffect effect = (RestrictionEffect) entry.getKey();
for (Ability ability : (HashSet<Ability>) entry.getValue()) {
if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) {
if (controller.isHuman()) {
game.informPlayer(controller, new StringBuilder(attackingCreature.getName()).append(" can't be blocked this way." ).toString());
return false;
} else {
// remove blocking creatures for AI
for (CombatGroup combatGroup: this.getGroups()) {
if (combatGroup.getAttackers().contains(attackingCreatureId)) {
for(UUID blockerId :combatGroup.getBlockers()) {
removeBlocker(blockerId, game);
}
}
}
}
}
}
}
}
}
return true;
}
public void setDefenders(Game game) {
Set<UUID> opponents = game.getOpponents(attackerId);
PlayerList players;