Improving performance of major filterings, etc.

This commit is contained in:
marcins78@gmail.com
2011-11-16 20:06:58 +00:00
parent 033d14dfac
commit 1d18c3bfbb
12 changed files with 357 additions and 189 deletions

View File

@@ -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;
}
}

View File

@@ -0,0 +1,7 @@
package com.gempukku.lotro.logic.modifiers;
import com.gempukku.lotro.common.Keyword;
public interface KeywordAffectingModifier {
public Keyword getKeyword();
}

View File

@@ -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()) {

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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");

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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)