Improving performance of major filterings, etc.
This commit is contained in:
@@ -5,10 +5,11 @@ import com.gempukku.lotro.filters.Filter;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.state.GameState;
|
||||
import com.gempukku.lotro.logic.modifiers.AbstractModifier;
|
||||
import com.gempukku.lotro.logic.modifiers.KeywordAffectingModifier;
|
||||
import com.gempukku.lotro.logic.modifiers.ModifierEffect;
|
||||
import com.gempukku.lotro.logic.modifiers.ModifiersQuerying;
|
||||
|
||||
public class CancelKeywordBonusModifier extends AbstractModifier {
|
||||
public class CancelKeywordBonusModifier extends AbstractModifier implements KeywordAffectingModifier {
|
||||
private Keyword _keyword;
|
||||
|
||||
public CancelKeywordBonusModifier(PhysicalCard source, Keyword keyword, Filter affectFilter) {
|
||||
@@ -22,4 +23,9 @@ public class CancelKeywordBonusModifier extends AbstractModifier {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keyword getKeyword() {
|
||||
return _keyword;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gempukku.lotro.logic.modifiers;
|
||||
|
||||
import com.gempukku.lotro.common.Keyword;
|
||||
|
||||
public interface KeywordAffectingModifier {
|
||||
public Keyword getKeyword();
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import com.gempukku.lotro.game.state.GameState;
|
||||
import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator;
|
||||
import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator;
|
||||
|
||||
public class KeywordModifier extends AbstractModifier {
|
||||
public class KeywordModifier extends AbstractModifier implements KeywordAffectingModifier {
|
||||
private Keyword _keyword;
|
||||
private Evaluator _evaluator;
|
||||
|
||||
@@ -29,6 +29,11 @@ public class KeywordModifier extends AbstractModifier {
|
||||
_evaluator = evaluator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keyword getKeyword() {
|
||||
return _keyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard self) {
|
||||
if (_keyword.isMultiples()) {
|
||||
|
||||
@@ -3,28 +3,74 @@ package com.gempukku.lotro.logic.modifiers;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LoggingThreadLocal {
|
||||
private static final Logger LOG = Logger.getLogger(LoggingThreadLocal.class);
|
||||
private static ThreadLocal<StringBuilder> _logLocal = new ThreadLocal<StringBuilder>();
|
||||
private static ThreadLocal<Long> _start = new ThreadLocal<Long>();
|
||||
private static ThreadLocal<Integer> _level = new ThreadLocal<Integer>();
|
||||
|
||||
public static void start() {
|
||||
_logLocal.set(new StringBuilder());
|
||||
_start.set(System.currentTimeMillis());
|
||||
private static FileOutputStream _fos = null;
|
||||
|
||||
private static synchronized void initializeOutputStream() {
|
||||
if (_fos == null) {
|
||||
try {
|
||||
_fos = new FileOutputStream(new File("I:\\dev\\logMethod-2.txt"));
|
||||
} catch (IOException exp) {
|
||||
throw new RuntimeException(exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void log(PhysicalCard card, String desc) {
|
||||
public static void start() {
|
||||
if (_fos == null)
|
||||
initializeOutputStream();
|
||||
|
||||
_logLocal.set(new StringBuilder());
|
||||
_start.set(System.currentTimeMillis());
|
||||
_level.set(0);
|
||||
}
|
||||
|
||||
public static void logMethodStart(PhysicalCard card, String desc) {
|
||||
StringBuilder builder = _logLocal.get();
|
||||
if (builder != null && card != null)
|
||||
builder.append(card.getBlueprintId()).append(" ").append(desc).append(" - ");
|
||||
if (builder != null) {
|
||||
int level = _level.get();
|
||||
for (int i = 0; i < level; i++)
|
||||
builder.append("\t");
|
||||
builder.append(desc);
|
||||
if (card != null)
|
||||
builder.append(" ").append(card.getBlueprintId());
|
||||
builder.append("\r\n");
|
||||
_level.set(level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logMethodEnd() {
|
||||
StringBuilder builder = _logLocal.get();
|
||||
if (builder != null) {
|
||||
_level.set(_level.get() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void stop(boolean writeOperation) {
|
||||
long start = _start.get();
|
||||
long time = System.currentTimeMillis() - start;
|
||||
if (time > 100)
|
||||
LOG.error("Processing took (" + writeOperation + ")" + time + "ms: \n" + _logLocal.get().toString());
|
||||
if (time > 10) {
|
||||
String str = "Processing took (" + writeOperation + ") " + time + "ms: \n" + _logLocal.get().toString();
|
||||
try {
|
||||
synchronized (_fos) {
|
||||
_fos.write(str.getBytes());
|
||||
_fos.flush();
|
||||
}
|
||||
} catch (IOException exp) {
|
||||
throw new RuntimeException(exp);
|
||||
}
|
||||
}
|
||||
_start.set(null);
|
||||
_logLocal.set(null);
|
||||
_level.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,50 +188,63 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
||||
|
||||
@Override
|
||||
public boolean hasKeyword(GameState gameState, PhysicalCard physicalCard, Keyword keyword) {
|
||||
LoggingThreadLocal.log(physicalCard, "hasKeyword");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
if (modifier.isKeywordRemoved(gameState, this, physicalCard, keyword))
|
||||
return false;
|
||||
}
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "hasKeyword " + keyword.getHumanReadable());
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (((KeywordAffectingModifier) modifier).getKeyword() == keyword)
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
if (modifier.isKeywordRemoved(gameState, this, physicalCard, keyword))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (physicalCard.getBlueprint().hasKeyword(keyword))
|
||||
return true;
|
||||
if (physicalCard.getBlueprint().hasKeyword(keyword))
|
||||
return true;
|
||||
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesKeywordModifier(gameState, modifier.getSource(), keyword))
|
||||
if (modifier.hasKeyword(gameState, this, physicalCard, keyword))
|
||||
return true;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (((KeywordAffectingModifier) modifier).getKeyword() == keyword)
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesKeywordModifier(gameState, modifier.getSource(), keyword))
|
||||
if (modifier.hasKeyword(gameState, this, physicalCard, keyword))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getKeywordCount(GameState gameState, PhysicalCard physicalCard, Keyword keyword) {
|
||||
LoggingThreadLocal.log(physicalCard, "getKeywordCount");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
if (modifier.isKeywordRemoved(gameState, this, physicalCard, keyword))
|
||||
return 0;
|
||||
}
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getKeywordCount " + keyword.getHumanReadable());
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (((KeywordAffectingModifier) modifier).getKeyword() == keyword)
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
if (modifier.isKeywordRemoved(gameState, this, physicalCard, keyword))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = physicalCard.getBlueprint().getKeywordCount(keyword);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesKeywordModifier(gameState, modifier.getSource(), keyword))
|
||||
result += modifier.getKeywordCountModifier(gameState, this, physicalCard, keyword);
|
||||
int result = physicalCard.getBlueprint().getKeywordCount(keyword);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (((KeywordAffectingModifier) modifier).getKeyword() == keyword)
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesKeywordModifier(gameState, modifier.getSource(), keyword))
|
||||
result += modifier.getKeywordCountModifier(gameState, this, physicalCard, keyword);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
private boolean appliesKeywordModifier(GameState gameState, PhysicalCard modifierSource, Keyword keyword) {
|
||||
if (modifierSource == null)
|
||||
return true;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.KEYWORD_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, modifierSource, modifier))
|
||||
if (!modifier.appliesKeywordModifier(gameState, this, modifierSource, keyword))
|
||||
return false;
|
||||
if (((KeywordAffectingModifier) modifier).getKeyword() == keyword)
|
||||
if (affectsCardWithSkipSet(gameState, modifierSource, modifier))
|
||||
if (!modifier.appliesKeywordModifier(gameState, this, modifierSource, keyword))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -254,14 +267,18 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
||||
|
||||
@Override
|
||||
public int getStrength(GameState gameState, PhysicalCard physicalCard) {
|
||||
LoggingThreadLocal.log(physicalCard, "getStrength");
|
||||
int result = physicalCard.getBlueprint().getStrength();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.STRENGTH_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesStrengthModifier(gameState, modifier.getSource()))
|
||||
result += modifier.getStrengthModifier(gameState, this, physicalCard);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getStrength");
|
||||
try {
|
||||
int result = physicalCard.getBlueprint().getStrength();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.STRENGTH_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier)
|
||||
&& appliesStrengthModifier(gameState, modifier.getSource()))
|
||||
result += modifier.getStrengthModifier(gameState, this, physicalCard);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
private boolean appliesStrengthModifier(GameState gameState, PhysicalCard modifierSource) {
|
||||
@@ -277,173 +294,233 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
||||
|
||||
@Override
|
||||
public int getVitality(GameState gameState, PhysicalCard physicalCard) {
|
||||
LoggingThreadLocal.log(physicalCard, "getVitality");
|
||||
int result = physicalCard.getBlueprint().getVitality() - gameState.getWounds(physicalCard);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.VITALITY_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getVitalityModifier(gameState, this, physicalCard);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getVitality");
|
||||
try {
|
||||
int result = physicalCard.getBlueprint().getVitality() - gameState.getWounds(physicalCard);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.VITALITY_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getVitalityModifier(gameState, this, physicalCard);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResistance(GameState gameState, PhysicalCard physicalCard) {
|
||||
LoggingThreadLocal.log(physicalCard, "getResistance");
|
||||
int result = physicalCard.getBlueprint().getResistance() - gameState.getBurdens();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.RESISTANCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getResistanceModifier(gameState, this, physicalCard);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getResistance");
|
||||
try {
|
||||
int result = physicalCard.getBlueprint().getResistance() - gameState.getBurdens();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.RESISTANCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getResistanceModifier(gameState, this, physicalCard);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinionSiteNumber(GameState gameState, PhysicalCard physicalCard) {
|
||||
LoggingThreadLocal.log(physicalCard, "getMinionSiteNumber");
|
||||
int result = physicalCard.getBlueprint().getSiteNumber();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.SITE_NUMBER_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getMinionSiteNumberModifier(gameState, this, physicalCard);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getMinionSiteNumber");
|
||||
try {
|
||||
int result = physicalCard.getBlueprint().getSiteNumber();
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.SITE_NUMBER_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getMinionSiteNumberModifier(gameState, this, physicalCard);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTwilightCost(GameState gameState, PhysicalCard physicalCard, boolean ignoreRoamingPenalty) {
|
||||
LoggingThreadLocal.log(physicalCard, "getTwilightCost");
|
||||
int result = physicalCard.getBlueprint().getTwilightCost();
|
||||
result += physicalCard.getBlueprint().getTwilightCostModifier(gameState, this, physicalCard);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getTwilightCostModifier(gameState, this, physicalCard, ignoreRoamingPenalty);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getTwilightCost");
|
||||
try {
|
||||
int result = physicalCard.getBlueprint().getTwilightCost();
|
||||
result += physicalCard.getBlueprint().getTwilightCostModifier(gameState, this, physicalCard);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getTwilightCostModifier(gameState, this, physicalCard, ignoreRoamingPenalty);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayOnTwilightCost(GameState gameState, PhysicalCard physicalCard, PhysicalCard target) {
|
||||
LoggingThreadLocal.log(physicalCard, "getPlayOnTwilightCost");
|
||||
int result = getTwilightCost(gameState, physicalCard, false);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getPlayOnTwilightCostModifier(gameState, this, physicalCard, target);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getPlayOnTwilightCost");
|
||||
try {
|
||||
int result = getTwilightCost(gameState, physicalCard, false);
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getPlayOnTwilightCostModifier(gameState, this, physicalCard, target);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRoamingPenalty(GameState gameState, PhysicalCard physicalCard) {
|
||||
LoggingThreadLocal.log(physicalCard, "getRoamingPenalty");
|
||||
int result = 2;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getRoamingPenaltyModifier(gameState, this, physicalCard);
|
||||
LoggingThreadLocal.logMethodStart(physicalCard, "getRoamingPenalty");
|
||||
try {
|
||||
int result = 2;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.TWILIGHT_COST_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, physicalCard, modifier))
|
||||
result += modifier.getRoamingPenaltyModifier(gameState, this, physicalCard);
|
||||
}
|
||||
return Math.max(0, result);
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return Math.max(0, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOverwhelmMultiplier(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "getOverwhelmMultiplier");
|
||||
int overwhelmMultiplier = 2;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.OVERWHELM_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
overwhelmMultiplier = Math.max(overwhelmMultiplier, modifier.getOverwhelmMultiplier(gameState, this, card));
|
||||
LoggingThreadLocal.logMethodStart(card, "getOverwhelmMultiplier");
|
||||
try {
|
||||
int overwhelmMultiplier = 2;
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.OVERWHELM_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
overwhelmMultiplier = Math.max(overwhelmMultiplier, modifier.getOverwhelmMultiplier(gameState, this, card));
|
||||
}
|
||||
return overwhelmMultiplier;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return overwhelmMultiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeWound(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "canTakeWound");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier)) {
|
||||
Integer woundsTaken = _woundsPerPhaseMap.get(card.getCardId());
|
||||
if (woundsTaken == null)
|
||||
woundsTaken = 0;
|
||||
if (!modifier.canTakeWound(gameState, this, card, woundsTaken))
|
||||
return false;
|
||||
LoggingThreadLocal.logMethodStart(card, "canTakeWound");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier)) {
|
||||
Integer woundsTaken = _woundsPerPhaseMap.get(card.getCardId());
|
||||
if (woundsTaken == null)
|
||||
woundsTaken = 0;
|
||||
if (!modifier.canTakeWound(gameState, this, card, woundsTaken))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeArcheryWound(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "canTakeArcheryWound");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier)) {
|
||||
if (!modifier.canTakeArcheryWound(gameState, this, card))
|
||||
return false;
|
||||
LoggingThreadLocal.logMethodStart(card, "canTakeArcheryWound");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier)) {
|
||||
if (!modifier.canTakeArcheryWound(gameState, this, card))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeExerted(GameState gameState, PhysicalCard source, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "canBeExerted");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeExerted(gameState, this, source, card))
|
||||
return false;
|
||||
LoggingThreadLocal.logMethodStart(card, "canBeExerted");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeExerted(gameState, this, source, card))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllyAllowedToParticipateInArcheryFire(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "isAllyAllowedToParticipateInArcheryFire");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyParticipateInArcheryFire(gameState, this, card))
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "isAllyAllowedToParticipateInArcheryFire");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyParticipateInArcheryFire(gameState, this, card))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToParticipateInSkirmishes(GameState gameState, Side sidePlayer, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "isAllowedToParticipateInSkirmished");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isParticipateInSkirmishes(gameState, sidePlayer, this, card))
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "isAllowedToParticipateInSkirmishes");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isParticipateInSkirmishes(gameState, sidePlayer, this, card))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllyPreventedFromParticipatingInArcheryFire(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "isAllyPreventedFromParticipatingInArcheryFire");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyPreventedFromParticipatingInArcheryFire(gameState, this, card))
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "isAllyPreventedFromParticipatingInArcheryFire");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyPreventedFromParticipatingInArcheryFire(gameState, this, card))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllyPreventedFromParticipatingInSkirmishes(GameState gameState, Side sidePlayer, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "isAllyPreventedFromParticipatingInSkirmishes");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyPreventedFromParticipatingInSkirmishes(gameState, sidePlayer, this, card))
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "isAllyPreventedFromParticipatingInSkirmishes");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.PRESENCE_MODIFIER)) {
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (modifier.isAllyPreventedFromParticipatingInSkirmishes(gameState, sidePlayer, this, card))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addsToArcheryTotal(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "addsToArcheryTotal");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.ARCHERY_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.addsToArcheryTotal(gameState, this, card))
|
||||
return false;
|
||||
LoggingThreadLocal.logMethodStart(card, "addsToArcheryTotal");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.ARCHERY_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.addsToArcheryTotal(gameState, this, card))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -512,32 +589,44 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
||||
|
||||
@Override
|
||||
public boolean canBeAssignedToSkirmish(GameState gameState, Side sidePlayer, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "canBeAssignedToSkirmish");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.ASSIGNMENT_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeAssignedToSkirmish(gameState, sidePlayer, this, card))
|
||||
return false;
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "canBeAssignedToSkirmish");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.ASSIGNMENT_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeAssignedToSkirmish(gameState, sidePlayer, this, card))
|
||||
return false;
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeDiscardedFromPlay(GameState gameState, PhysicalCard card, PhysicalCard source) {
|
||||
LoggingThreadLocal.log(card, "canBeDiscardedFromPlay");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.DISCARD_FROM_PLAY_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeDiscardedFromPlay(gameState, this, card, source))
|
||||
return false;
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "canBeDiscardedFromPlay");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.DISCARD_FROM_PLAY_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeDiscardedFromPlay(gameState, this, card, source))
|
||||
return false;
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHealed(GameState gameState, PhysicalCard card) {
|
||||
LoggingThreadLocal.log(card, "canBeHealed");
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeHealed(gameState, this, card))
|
||||
return false;
|
||||
return true;
|
||||
LoggingThreadLocal.logMethodStart(card, "canBeHealed");
|
||||
try {
|
||||
for (Modifier modifier : getModifiers(gameState, ModifierEffect.WOUND_MODIFIER))
|
||||
if (affectsCardWithSkipSet(gameState, card, modifier))
|
||||
if (!modifier.canBeHealed(gameState, this, card))
|
||||
return false;
|
||||
return true;
|
||||
} finally {
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,12 +5,11 @@ import com.gempukku.lotro.common.Keyword;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.state.GameState;
|
||||
|
||||
public class RemoveKeywordModifier extends AbstractModifier {
|
||||
public class RemoveKeywordModifier extends AbstractModifier implements KeywordAffectingModifier {
|
||||
private Keyword _keyword;
|
||||
|
||||
public RemoveKeywordModifier(PhysicalCard physicalCard, Filterable affectFilter, Keyword keyword) {
|
||||
super(physicalCard, "Loses " + keyword.getHumanReadable() + "keyword(s)", affectFilter, ModifierEffect.KEYWORD_MODIFIER);
|
||||
_keyword = keyword;
|
||||
this(physicalCard, affectFilter, null, keyword);
|
||||
}
|
||||
|
||||
public RemoveKeywordModifier(PhysicalCard physicalCard, Filterable affectFilter, Condition condition, Keyword keyword) {
|
||||
@@ -18,6 +17,11 @@ public class RemoveKeywordModifier extends AbstractModifier {
|
||||
_keyword = keyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keyword getKeyword() {
|
||||
return _keyword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeywordRemoved(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard, Keyword keyword) {
|
||||
return _keyword == keyword;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package com.gempukku.lotro.logic.timing;
|
||||
|
||||
import com.gempukku.lotro.common.Keyword;
|
||||
import com.gempukku.lotro.common.Phase;
|
||||
import com.gempukku.lotro.common.Zone;
|
||||
import com.gempukku.lotro.communication.GameStateListener;
|
||||
import com.gempukku.lotro.communication.UserFeedback;
|
||||
import com.gempukku.lotro.filters.Filters;
|
||||
import com.gempukku.lotro.game.ActionsEnvironment;
|
||||
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
|
||||
import com.gempukku.lotro.game.LotroFormat;
|
||||
@@ -175,12 +174,13 @@ public class DefaultLotroGame implements LotroGame {
|
||||
GameState gameState = getGameState();
|
||||
if (gameState != null && gameState.getCurrentPhase() != Phase.PLAY_STARTING_FELLOWSHIP && gameState.getCurrentPhase() != Phase.BETWEEN_TURNS && gameState.getCurrentPhase() != Phase.PUT_RING_BEARER) {
|
||||
// Ring-bearer death
|
||||
if (!Filters.canSpot(gameState, getModifiersQuerying(), Filters.keyword(Keyword.RING_BEARER))) {
|
||||
PhysicalCard ringBearer = gameState.getRingBearer(gameState.getCurrentPlayerId());
|
||||
Zone zone = ringBearer.getZone();
|
||||
if (zone == null || !zone.isInPlay()) {
|
||||
playerLost(getGameState().getCurrentPlayerId(), "The Ring-Bearer is dead");
|
||||
return;
|
||||
} else {
|
||||
// Ring-bearer corruption
|
||||
PhysicalCard ringBearer = Filters.findFirstActive(getGameState(), getModifiersQuerying(), Filters.keyword(Keyword.RING_BEARER));
|
||||
int ringBearerResistance = getModifiersQuerying().getResistance(getGameState(), ringBearer);
|
||||
if (ringBearerResistance <= 0) {
|
||||
playerLost(getGameState().getCurrentPlayerId(), "The Ring-Bearer is corrupted");
|
||||
|
||||
@@ -13,13 +13,6 @@ import com.gempukku.lotro.logic.modifiers.ModifiersQuerying;
|
||||
public class RuleUtils {
|
||||
public static int calculateFellowshipArcheryTotal(LotroGame game) {
|
||||
int normalArcheryTotal = Filters.countActive(game.getGameState(), game.getModifiersQuerying(),
|
||||
Filters.keyword(Keyword.ARCHER),
|
||||
new Filter() {
|
||||
@Override
|
||||
public boolean accepts(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard) {
|
||||
return modifiersQuerying.addsToArcheryTotal(gameState, physicalCard);
|
||||
}
|
||||
},
|
||||
Filters.or(
|
||||
Filters.type(CardType.COMPANION),
|
||||
Filters.and(
|
||||
@@ -40,21 +33,28 @@ public class RuleUtils {
|
||||
}
|
||||
})
|
||||
)
|
||||
));
|
||||
|
||||
return game.getModifiersQuerying().getArcheryTotal(game.getGameState(), Side.FREE_PEOPLE, normalArcheryTotal);
|
||||
}
|
||||
|
||||
public static int calculateShadowArcheryTotal(LotroGame game) {
|
||||
int normalArcheryTotal = Filters.countActive(game.getGameState(), game.getModifiersQuerying(),
|
||||
),
|
||||
Filters.keyword(Keyword.ARCHER),
|
||||
new Filter() {
|
||||
@Override
|
||||
public boolean accepts(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard) {
|
||||
return modifiersQuerying.addsToArcheryTotal(gameState, physicalCard);
|
||||
}
|
||||
},
|
||||
Filters.type(CardType.MINION));
|
||||
});
|
||||
|
||||
return game.getModifiersQuerying().getArcheryTotal(game.getGameState(), Side.FREE_PEOPLE, normalArcheryTotal);
|
||||
}
|
||||
|
||||
public static int calculateShadowArcheryTotal(LotroGame game) {
|
||||
int normalArcheryTotal = Filters.countActive(game.getGameState(), game.getModifiersQuerying(),
|
||||
Filters.type(CardType.MINION),
|
||||
Filters.keyword(Keyword.ARCHER),
|
||||
new Filter() {
|
||||
@Override
|
||||
public boolean accepts(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard) {
|
||||
return modifiersQuerying.addsToArcheryTotal(gameState, physicalCard);
|
||||
}
|
||||
});
|
||||
|
||||
return game.getModifiersQuerying().getArcheryTotal(game.getGameState(), Side.SHADOW, normalArcheryTotal);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.gempukku.lotro.logic.actions.SystemQueueAction;
|
||||
import com.gempukku.lotro.logic.decisions.ActionSelectionDecision;
|
||||
import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
import com.gempukku.lotro.logic.modifiers.LoggingThreadLocal;
|
||||
import com.gempukku.lotro.logic.timing.actions.SystemAction;
|
||||
import com.gempukku.lotro.logic.timing.processes.GameProcess;
|
||||
import com.gempukku.lotro.logic.timing.processes.pregame.BiddingGameProcess;
|
||||
@@ -106,10 +107,20 @@ public class TurnProcedure {
|
||||
|
||||
Side initiativePreEffect = _game.getModifiersQuerying().hasInitiative(_game.getGameState());
|
||||
|
||||
final Collection<? extends EffectResult> effectResults = _effect.playEffect(_game);
|
||||
List<EffectResult> results = new LinkedList<EffectResult>();
|
||||
if (effectResults != null)
|
||||
results.addAll(effectResults);
|
||||
|
||||
Action topmostAction = _actionStack.getTopmostAction();
|
||||
if (topmostAction != null && topmostAction.getActionSource() != null)
|
||||
LoggingThreadLocal.logMethodStart(topmostAction.getActionSource(), "playEffect");
|
||||
|
||||
try {
|
||||
final Collection<? extends EffectResult> effectResults = _effect.playEffect(_game);
|
||||
if (effectResults != null)
|
||||
results.addAll(effectResults);
|
||||
} finally {
|
||||
if (topmostAction != null && topmostAction.getActionSource() != null)
|
||||
LoggingThreadLocal.logMethodEnd();
|
||||
}
|
||||
|
||||
Side initiativePostEffect = _game.getModifiersQuerying().hasInitiative(_game.getGameState());
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ import com.gempukku.lotro.logic.timing.Action;
|
||||
public abstract class SystemAction implements Action {
|
||||
@Override
|
||||
public PhysicalCard getActionSource() {
|
||||
throw new UnsupportedOperationException("System action has no action source");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalCard getActionAttachedToCard() {
|
||||
throw new UnsupportedOperationException("System action has no action source");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,6 +36,6 @@ public abstract class SystemAction implements Action {
|
||||
|
||||
@Override
|
||||
public String getText(LotroGame game) {
|
||||
throw new UnsupportedOperationException("System action has no text");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class EnduringRule {
|
||||
|
||||
public void applyRule() {
|
||||
_modifiersLogic.addAlwaysOnModifier(
|
||||
new StrengthModifier(null, Filters.and(Keyword.ENDURING, Filters.wounded), null,
|
||||
new StrengthModifier(null, Filters.and(Filters.wounded, Keyword.ENDURING), null,
|
||||
new Evaluator() {
|
||||
@Override
|
||||
public int evaluateExpression(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard self) {
|
||||
|
||||
@@ -27,7 +27,7 @@ public class RoamingRule {
|
||||
new KeywordModifier(null, roamingFilter, Keyword.ROAMING));
|
||||
|
||||
_modifiersLogic.addAlwaysOnModifier(
|
||||
new AbstractModifier(null, null, Keyword.ROAMING, ModifierEffect.TWILIGHT_COST_MODIFIER) {
|
||||
new AbstractModifier(null, null, Filters.and(CardType.MINION, Keyword.ROAMING), ModifierEffect.TWILIGHT_COST_MODIFIER) {
|
||||
@Override
|
||||
public int getTwilightCostModifier(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard physicalCard, boolean ignoreRoamingPenalty) {
|
||||
if (ignoreRoamingPenalty)
|
||||
|
||||
Reference in New Issue
Block a user