Adding new PC keywords Concealed and Exposed, with associated rules and unit tests. Adding new PC race Warg. Adding new PC possession type Pony.

This commit is contained in:
Christian 'ketura' McCarty
2021-02-06 19:11:09 -06:00
parent 6465cbfb35
commit 7ba8203fa6
7 changed files with 201 additions and 4 deletions

View File

@@ -30,7 +30,10 @@ public enum Keyword implements Filterable {
WARG_RIDER("Warg-rider", true), BESIEGER("Besieger", true), CORSAIR("Corsair", true),
//Additional Hobbit Draft keywords
WISE("Wise", true), BURGLAR("Burglar", true);
WISE("Wise", true), BURGLAR("Burglar", true),
//PC Keywords
CONCEALED("Concealed", true), EXPOSED("Exposed", true);
private String _humanReadable;
private boolean _infoDisplayable;

View File

@@ -4,7 +4,12 @@ public enum PossessionClass implements Filterable {
HAND_WEAPON("Hand Weapon"), ARMOR("Armor"), HELM("Helm"), MOUNT("Mount"), RANGED_WEAPON("Ranged Weapon"),
CLOAK("Cloak"), PIPE("Pipe"), SHIELD("Shield"), BRACERS("Bracers"), STAFF("Staff"), RING("Ring"),
BROOCH("Brooch"), GAUNTLETS("Gauntlets"), BOX("Box"), PALANTIR("Palantir"), PHIAL("Phial"), HORN("Horn"),
CLASSLESS("Classless");
CLASSLESS("Classless"),
//PC Classes
PONY("Pony")
;
private String _humanReadable;

View File

@@ -7,7 +7,10 @@ public enum Race implements Filterable {
GOBLIN("Goblin"),
//Additional Hobbit Draft races
DRAGON("Dragon"), EAGLE("Eagle"), BIRD("Bird");
DRAGON("Dragon"), EAGLE("Eagle"), BIRD("Bird"),
//PC Races
WARG("Warg");
private String _humanReadable;

View File

@@ -384,9 +384,10 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
@Override
public boolean addsTwilightForCompanionMove(LotroGame game, PhysicalCard companion) {
for (Modifier modifier : getModifiersAffectingCard(game, ModifierEffect.MOVE_TWILIGHT_MODIFIER, companion))
for (Modifier modifier : getModifiersAffectingCard(game, ModifierEffect.MOVE_TWILIGHT_MODIFIER, companion)) {
if (!modifier.addsTwilightForCompanionMove(game, companion))
return false;
}
return true;
}

View File

@@ -65,5 +65,6 @@ public class RuleSet {
new HealByDiscardRule(_actionsEnvironment).applyRule();
new TakeOffRingRule(_actionsEnvironment).applyRule();
new ConcealedRule(_actionsEnvironment).applyRule();
}
}

View File

@@ -0,0 +1,64 @@
package com.gempukku.lotro.logic.timing.rules;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.AbstractActionProxy;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.actions.RequiredTriggerAction;
import com.gempukku.lotro.logic.effects.*;
import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator;
import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator;
import com.gempukku.lotro.logic.modifiers.evaluator.LocationEvaluator;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import com.gempukku.lotro.logic.timing.PlayConditions;
import com.gempukku.lotro.logic.timing.TriggerConditions;
import java.util.*;
public class ConcealedRule {
private DefaultActionsEnvironment _actionsEnvironment;
public ConcealedRule(DefaultActionsEnvironment actionsEnvironment) {
_actionsEnvironment = actionsEnvironment;
}
public void applyRule() {
_actionsEnvironment.addAlwaysOnActionProxy(
new AbstractActionProxy() {
@Override
public List<? extends RequiredTriggerAction> getRequiredAfterTriggers(final LotroGame game, EffectResult effectResult) {
if (TriggerConditions.moves(game, effectResult)
&& game.getGameState().getCurrentPhase() == Phase.FELLOWSHIP) {
List<RequiredTriggerAction> actions = new ArrayList<>();
int twilight = Filters.filterActive(game, CardType.COMPANION, Keyword.CONCEALED).size();
if(twilight == 0)
return null;
final RequiredTriggerAction action = new RequiredTriggerAction(null);
LocationEvaluator loc = new LocationEvaluator(twilight, 0, Keyword.EXPOSED);
action.appendEffect(new RemoveTwilightEffect(new LocationEvaluator(twilight, 0, Keyword.EXPOSED)));
if(loc.evaluateExpression(game, null) == 0) {
action.setText("Concealed companions were exposed! No twilight was removed.");
}
else {
action.setText("Concealed companions trigger removal of " + twilight + " twilight.");
}
actions.add(action);
return actions;
}
return null;
}
});
}
}

View File

@@ -0,0 +1,120 @@
package com.gempukku.lotro.at;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.game.PhysicalCardImpl;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.modifiers.KeywordModifier;
import org.junit.Test;
import java.util.HashMap;
import static junit.framework.Assert.*;
import static org.junit.Assert.assertTrue;
public class ConcealedExposedAtTest extends AbstractAtTest {
protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("aragorn", "1_89");
put("arwen", "1_30");
}}
);
}
@Test
public void ConcealedDoesNothingIfNoTwilight() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl aragorn = scn.GetFreepsCard("aragorn");
scn.FreepsMoveCharToTable(aragorn);
scn.StartGame();
scn.InsertAdHocModifier(new KeywordModifier(aragorn, aragorn, Keyword.CONCEALED));
assertEquals(0, scn.GetTwilight());
scn.FreepsSkipCurrentPhaseAction();
//1 for the ring-bearer, 1 for aragorn, 1 for the site (King's Tent)
assertEquals(3, scn.GetTwilight());
}
@Test
public void ConcealedRemovesOneIfAvailable() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl aragorn = scn.GetFreepsCard("aragorn");
PhysicalCardImpl nostranger = scn.GetFreepsCard("nostranger");
scn.FreepsMoveCardToHand(aragorn);
scn.StartGame();
scn.FreepsPlayCard(aragorn);
scn.InsertAdHocModifier(new KeywordModifier(aragorn, aragorn, Keyword.CONCEALED));
//4 from playing aragorn
assertEquals(4, scn.GetTwilight());
scn.FreepsSkipCurrentPhaseAction();
//4 from playing aragorn, 1 for the ring-bearer, 1 for aragorn, 1 for the site (King's Tent), -1 for concealed
assertEquals(6, scn.GetTwilight());
}
@Test
public void TwoConcealedRemovesTwoIfAvailable() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl aragorn = scn.GetFreepsCard("aragorn");
PhysicalCardImpl arwen = scn.GetFreepsCard("arwen");
scn.FreepsMoveCardToHand(aragorn);
scn.FreepsMoveCharToTable(arwen);
scn.StartGame();
scn.FreepsPlayCard(aragorn);
scn.InsertAdHocModifier(new KeywordModifier(aragorn, Keyword.RANGER, Keyword.CONCEALED));
//4 from playing aragorn
assertEquals(4, scn.GetTwilight());
scn.FreepsSkipCurrentPhaseAction();
//4 from playing aragorn, 1+1+1 for companions, 1 for the site (King's Tent), -2 for concealed
assertEquals(6, scn.GetTwilight());
}
@Test
public void ConcealedRemovesNothingIfExposed() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetScenario();
PhysicalCardImpl aragorn = scn.GetFreepsCard("aragorn");
scn.FreepsMoveCardToHand(aragorn);
scn.StartGame();
scn.FreepsPlayCard(aragorn);
scn.InsertAdHocModifier(new KeywordModifier(aragorn, Keyword.RANGER, Keyword.CONCEALED));
scn.InsertAdHocModifier(new KeywordModifier(null, CardType.SITE, Keyword.EXPOSED));
//4 from playing aragorn
assertEquals(4, scn.GetTwilight());
scn.FreepsSkipCurrentPhaseAction();
//4 from playing aragorn, 1 for the ring-bearer, 1 for aragorn, 1 for the site (King's Tent), 0 for exposed concealed
assertEquals(7, scn.GetTwilight());
}
}