mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
* Tromokratis - added first implementation (can't handle forced block conflicts yet)
This commit is contained in:
parent
89ac171b24
commit
99c51f8091
3 changed files with 81 additions and 51 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue