Added restrict effect hints to permanents;

This commit is contained in:
Oleg Agafonov 2019-02-08 03:08:28 +04:00
parent 92ce8be91d
commit 1b32793388
7 changed files with 120 additions and 49 deletions

View file

@ -775,6 +775,9 @@ public final class ManaSymbols {
if (replaced.contains(HintUtils.HINT_ICON_BAD)) { if (replaced.contains(HintUtils.HINT_ICON_BAD)) {
replaced = replaced.replace(HintUtils.HINT_ICON_BAD, GuiDisplayUtil.getHintIconHtml("bad", symbolSize) + " "); replaced = replaced.replace(HintUtils.HINT_ICON_BAD, GuiDisplayUtil.getHintIconHtml("bad", symbolSize) + " ");
} }
if (replaced.contains(HintUtils.HINT_ICON_RESTRICT)) {
replaced = replaced.replace(HintUtils.HINT_ICON_RESTRICT, GuiDisplayUtil.getHintIconHtml("restrict", symbolSize) + " ");
}
// ignored data restore // ignored data restore
replaced = replaced replaced = replaced

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -7,9 +7,13 @@ import java.awt.*;
*/ */
public class HintUtils { public class HintUtils {
public static final boolean ABILITY_HINTS_ENABLE = true;
public static final boolean RESTRICT_HINTS_ENABLE = true;
// icons changes to real files on client side (see mana icons replacement) // icons changes to real files on client side (see mana icons replacement)
public static final String HINT_ICON_GOOD = "ICON_GOOD"; public static final String HINT_ICON_GOOD = "ICON_GOOD";
public static final String HINT_ICON_BAD = "ICON_BAD"; public static final String HINT_ICON_BAD = "ICON_BAD";
public static final String HINT_ICON_RESTRICT = "ICON_RESTRICT";
public static String prepareText(String text, Color color) { public static String prepareText(String text, Color color) {
return prepareText(text, color, null); return prepareText(text, color, null);

View file

@ -6,6 +6,7 @@ import mage.Mana;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.*; import mage.abilities.*;
import mage.abilities.hint.Hint; import mage.abilities.hint.Hint;
import mage.abilities.hint.HintUtils;
import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.repository.PluginClassloaderRegistery; import mage.cards.repository.PluginClassloaderRegistery;
import mage.constants.*; import mage.constants.*;
@ -254,15 +255,26 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
rules.add(ability.getRule()); rules.add(ability.getRule());
} }
} }
// extra hints
for (Ability ability : abilities) { // ability hints
for (Hint hint : ability.getHints()) { List<String> abilityHints = new ArrayList<>();
String s = hint.getText(game, ability); if (HintUtils.ABILITY_HINTS_ENABLE) {
if (s != null && !s.isEmpty()) { for (Ability ability : abilities) {
rules.add(s); for (Hint hint : ability.getHints()) {
String s = hint.getText(game, ability);
if (s != null && !s.isEmpty()) {
abilityHints.add(s);
}
} }
} }
} }
// restrict hints only for permanents, not cards
// total hints
if (!abilityHints.isEmpty()) {
rules.addAll(abilityHints);
}
} }
return rules; return rules;
} catch (Exception e) { } catch (Exception e) {

View file

@ -9,6 +9,7 @@ import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.RestrictionEffect;
import mage.abilities.hint.Hint; import mage.abilities.hint.Hint;
import mage.abilities.hint.HintUtils;
import mage.abilities.keyword.*; import mage.abilities.keyword.*;
import mage.abilities.text.TextPart; import mage.abilities.text.TextPart;
import mage.cards.Card; import mage.cards.Card;
@ -245,22 +246,74 @@ public abstract class PermanentImpl extends CardImpl implements Permanent {
} }
} }
// extra hints // ability hints
for (Ability ability : abilities) { List<String> abilityHints = new ArrayList<>();
for (Hint hint : ability.getHints()) { if (HintUtils.ABILITY_HINTS_ENABLE) {
String s = hint.getText(game, ability); for (Ability ability : abilities) {
if (s != null && !s.isEmpty()) { for (Hint hint : ability.getHints()) {
rules.add(s); String s = hint.getText(game, ability);
if (s != null && !s.isEmpty()) {
abilityHints.add(s);
}
} }
} }
} }
// restrict hints
List<String> restrictHints = new ArrayList<>();
if (HintUtils.RESTRICT_HINTS_ENABLE) {
for (Map.Entry<RestrictionEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(this, game).entrySet()) {
for (Ability ability : entry.getValue()) {
if (!entry.getKey().applies(this, ability, game)) {
continue;
}
if (!entry.getKey().canAttack(game) || !entry.getKey().canAttack(this, null, ability, game)) {
restrictHints.add(HintUtils.prepareText("Can't attack" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canBlock(null, this, ability, game)) {
restrictHints.add(HintUtils.prepareText("Can't block" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canBeUntapped(this, ability, game)) {
restrictHints.add(HintUtils.prepareText("Can't untapped" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canUseActivatedAbilities(this, ability, game)) {
restrictHints.add(HintUtils.prepareText("Can't use activated abilities" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canTransform(this, ability, game)) {
restrictHints.add(HintUtils.prepareText("Can't transform" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
}
}
restrictHints.sort(String::compareTo);
}
// total hints
if (!abilityHints.isEmpty() || !restrictHints.isEmpty()) {
rules.addAll(abilityHints);
rules.addAll(restrictHints);
}
return rules; return rules;
} catch (Exception e) { } catch (Exception e) {
return rulesError; return rulesError;
} }
} }
private String addSourceObjectName(Game game, Ability ability) {
if (ability != null) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
return " (" + object.getIdName() + ")";
}
}
return "";
}
@Override @Override
public Abilities<Ability> getAbilities() { public Abilities<Ability> getAbilities() {
return abilities; return abilities;

View file

@ -1,9 +1,5 @@
package mage.players; package mage.players;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import mage.ConditionalMana; import mage.ConditionalMana;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
@ -69,6 +65,11 @@ import mage.util.GameLog;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
public abstract class PlayerImpl implements Player, Serializable { public abstract class PlayerImpl implements Player, Serializable {
private static final Logger logger = Logger.getLogger(PlayerImpl.class); private static final Logger logger = Logger.getLogger(PlayerImpl.class);
@ -1422,10 +1423,10 @@ public abstract class PlayerImpl implements Player, Serializable {
!= null != null
// if anyone sees an issue with this code, please report it. Worked in my testing. // if anyone sees an issue with this code, please report it. Worked in my testing.
|| game.getContinuousEffects().asThough(object.getId(), || game.getContinuousEffects().asThough(object.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE,
ability, ability,
this.getId(), this.getId(),
game) game)
!= null) { != null) {
if (canUse if (canUse
|| ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
@ -2527,7 +2528,7 @@ public abstract class PlayerImpl implements Player, Serializable {
for (Card card : library.getCards(game)) { for (Card card : library.getCards(game)) {
for (Ability ability : card.getAbilities()) { for (Ability ability : card.getAbilities()) {
if (ability.getClass() == WhileSearchingPlayFromLibraryAbility.class) { if (ability.getClass() == WhileSearchingPlayFromLibraryAbility.class) {
libraryCastableCardTracker.put(card.getId(), card.getName() + " [" + card.getId().toString().substring(0, 3) + "]"); libraryCastableCardTracker.put(card.getId(), card.getIdName());
} }
} }
} }
@ -2636,7 +2637,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param game * @param game
* @param appliedEffects * @param appliedEffects
* @param numSides Number of sides the dice has * @param numSides Number of sides the dice has
* @return the number that the player rolled * @return the number that the player rolled
*/ */
@Override @Override
@ -2670,10 +2671,10 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param game * @param game
* @param appliedEffects * @param appliedEffects
* @param numberChaosSides The number of chaos sides the planar die * @param numberChaosSides The number of chaos sides the planar die
* currently has (normally 1 but can be 5) * currently has (normally 1 but can be 5)
* @param numberPlanarSides The number of chaos sides the planar die * @param numberPlanarSides The number of chaos sides the planar die
* currently has (normally 1) * currently has (normally 1)
* @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll * @return the outcome that the player rolled. Either ChaosRoll, PlanarRoll
* or NilRoll * or NilRoll
*/ */
@ -2830,7 +2831,7 @@ public abstract class PlayerImpl implements Player, Serializable {
/** /**
* @param ability * @param ability
* @param available if null, it won't be checked if enough mana is available * @param available if null, it won't be checked if enough mana is available
* @param sourceObject * @param sourceObject
* @param game * @param game
* @return * @return
@ -3380,7 +3381,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId, public boolean canPaySacrificeCost(Permanent permanent, UUID sourceId,
UUID controllerId, Game game UUID controllerId, Game game
) { ) {
return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game); return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, sourceId, controllerId, game);
} }
@ -3528,8 +3529,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCards(Card card, Zone toZone, public boolean moveCards(Card card, Zone toZone,
Ability source, Game game, Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) { ) {
Set<Card> cardList = new HashSet<>(); Set<Card> cardList = new HashSet<>();
if (card != null) { if (card != null) {
@ -3540,22 +3541,22 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCards(Cards cards, Zone toZone, public boolean moveCards(Cards cards, Zone toZone,
Ability source, Game game Ability source, Game game
) { ) {
return moveCards(cards.getCards(game), toZone, source, game); return moveCards(cards.getCards(game), toZone, source, game);
} }
@Override @Override
public boolean moveCards(Set<Card> cards, Zone toZone, public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game Ability source, Game game
) { ) {
return moveCards(cards, toZone, source, game, false, false, false, null); return moveCards(cards, toZone, source, game, false, false, false, null);
} }
@Override @Override
public boolean moveCards(Set<Card> cards, Zone toZone, public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game, Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
return true; return true;
@ -3641,8 +3642,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardsToExile(Card card, Ability source, public boolean moveCardsToExile(Card card, Ability source,
Game game, boolean withName, UUID exileId, Game game, boolean withName, UUID exileId,
String exileZoneName String exileZoneName
) { ) {
Set<Card> cards = new HashSet<>(); Set<Card> cards = new HashSet<>();
cards.add(card); cards.add(card);
@ -3651,8 +3652,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardsToExile(Set<Card> cards, Ability source, public boolean moveCardsToExile(Set<Card> cards, Ability source,
Game game, boolean withName, UUID exileId, Game game, boolean withName, UUID exileId,
String exileZoneName String exileZoneName
) { ) {
if (cards.isEmpty()) { if (cards.isEmpty()) {
return true; return true;
@ -3667,14 +3668,14 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game Game game
) { ) {
return this.moveCardToHandWithInfo(card, sourceId, game, true); return this.moveCardToHandWithInfo(card, sourceId, game, true);
} }
@Override @Override
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, public boolean moveCardToHandWithInfo(Card card, UUID sourceId,
Game game, boolean withName Game game, boolean withName
) { ) {
boolean result = false; boolean result = false;
Zone fromZone = game.getState().getZone(card.getId()); Zone fromZone = game.getState().getZone(card.getId());
@ -3699,7 +3700,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source, public Set<Card> moveCardsToGraveyardWithInfo(Set<Card> allCards, Ability source,
Game game, Zone fromZone Game game, Zone fromZone
) { ) {
UUID sourceId = source == null ? null : source.getSourceId(); UUID sourceId = source == null ? null : source.getSourceId();
Set<Card> movedCards = new LinkedHashSet<>(); Set<Card> movedCards = new LinkedHashSet<>();
@ -3707,7 +3708,7 @@ public abstract class PlayerImpl implements Player, Serializable {
// identify cards from one owner // identify cards from one owner
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
UUID ownerId = null; UUID ownerId = null;
for (Iterator<Card> it = allCards.iterator(); it.hasNext();) { for (Iterator<Card> it = allCards.iterator(); it.hasNext(); ) {
Card card = it.next(); Card card = it.next();
if (cards.isEmpty()) { if (cards.isEmpty()) {
ownerId = card.getOwnerId(); ownerId = card.getOwnerId();
@ -3768,7 +3769,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone Game game, Zone fromZone
) { ) {
if (card == null) { if (card == null) {
return false; return false;
@ -3797,8 +3798,8 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId,
Game game, Zone fromZone, Game game, Zone fromZone,
boolean toTop, boolean withName boolean toTop, boolean withName
) { ) {
if (card == null) { if (card == null) {
return false; return false;
@ -3832,7 +3833,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override @Override
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId,
Game game, Zone fromZone, boolean withName) { Game game, Zone fromZone, boolean withName) {
if (card == null) { if (card == null) {
return false; return false;
} }

View file

@ -1,11 +1,9 @@
package mage.util; package mage.util;
import mage.MageObject; import mage.MageObject;
import mage.ObjectColor; import mage.ObjectColor;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class GameLog { public final class GameLog {
@ -40,11 +38,11 @@ public final class GameLog {
} }
public static String getColoredObjectIdName(MageObject mageObject) { public static String getColoredObjectIdName(MageObject mageObject) {
return "<font color=\'" + getColorName(mageObject.getColor(null)) + "\'>" + mageObject.getName() + " [" + mageObject.getId().toString().substring(0, 3) + "]</font>"; return "<font color=\'" + getColorName(mageObject.getColor(null)) + "\'>" + mageObject.getIdName() + "</font>";
} }
public static String getColoredObjectIdNameForTooltip(MageObject mageObject) { public static String getColoredObjectIdNameForTooltip(MageObject mageObject) {
return "<font color=\'" + getTooltipColorName(mageObject.getColor(null)) + "\'>" + mageObject.getName() + " [" + mageObject.getId().toString().substring(0, 3) + "]</font>"; return "<font color=\'" + getTooltipColorName(mageObject.getColor(null)) + "\'>" + mageObject.getIdName() + "</font>";
} }
public static String getNeutralColoredText(String text) { public static String getNeutralColoredText(String text) {