Extracting rules for playing Response cards and actions

This commit is contained in:
marcin.sciesinski
2019-10-01 14:56:00 -07:00
parent 01de8a6b42
commit 7df524733c
7 changed files with 176 additions and 91 deletions

View File

@@ -6,6 +6,7 @@ import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.TimeResolver;
import com.gempukku.lotro.cards.build.field.effect.trigger.TriggerChecker;
import com.gempukku.lotro.game.AbstractActionProxy;
import com.gempukku.lotro.game.ActionProxy;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.AbstractCostToEffectAction;
@@ -56,7 +57,7 @@ public class AddTrigger implements EffectAppenderProducer {
}
private ActionProxy createActionProxy(CostToEffectAction action, ActionContext actionContext, boolean optional, TriggerChecker trigger, Requirement[] requirements, EffectAppender[] costs, EffectAppender[] effects) {
return new ActionProxy() {
return new AbstractActionProxy() {
private boolean checkRequirements(ActionContext actionContext) {
for (Requirement requirement : requirements) {
if (!requirement.accepts(actionContext))

View File

@@ -3,12 +3,23 @@ package com.gempukku.lotro.game;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.actions.RequiredTriggerAction;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.List;
public abstract class AbstractActionProxy implements ActionProxy {
@Override
public List<? extends Action> getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) {
return null;
}
@Override
public List<? extends Action> getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) {
return null;
}
@Override
public List<? extends RequiredTriggerAction> getRequiredBeforeTriggers(LotroGame game, Effect effect) {
return null;

View File

@@ -3,17 +3,22 @@ package com.gempukku.lotro.game;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.actions.RequiredTriggerAction;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.List;
public interface ActionProxy {
public List<? extends RequiredTriggerAction> getRequiredBeforeTriggers(LotroGame lotroGame, Effect effect);
public List<? extends Action> getOptionalBeforeActions(String playerId, LotroGame game, Effect effect);
public List<? extends OptionalTriggerAction> getOptionalBeforeTriggers(String playerId, LotroGame lotroGame, Effect effect);
public List<? extends RequiredTriggerAction> getRequiredBeforeTriggers(LotroGame game, Effect effect);
public List<? extends RequiredTriggerAction> getRequiredAfterTriggers(LotroGame lotroGame, EffectResult effectResult);
public List<? extends OptionalTriggerAction> getOptionalBeforeTriggers(String playerId, LotroGame game, Effect effect);
public List<? extends OptionalTriggerAction> getOptionalAfterTriggers(String playerId, LotroGame lotroGame, EffectResult effectResult);
public List<? extends Action> getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult);
public List<? extends RequiredTriggerAction> getRequiredAfterTriggers(LotroGame game, EffectResult effectResult);
public List<? extends OptionalTriggerAction> getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult);
}

View File

@@ -3,14 +3,12 @@ package com.gempukku.lotro.game.state.actions;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.common.Zone;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.ActionProxy;
import com.gempukku.lotro.game.ActionsEnvironment;
import com.gempukku.lotro.game.CompletePhysicalCardVisitor;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.PlayUtils;
import com.gempukku.lotro.logic.actions.OptionalTriggerAction;
import com.gempukku.lotro.logic.actions.RequiredTriggerAction;
import com.gempukku.lotro.logic.timing.Action;
@@ -164,16 +162,17 @@ public class DefaultActionsEnvironment implements ActionsEnvironment {
@Override
public List<Action> getOptionalBeforeActions(String playerId, Effect effect) {
GatherOptionalBeforeActions gatherActions = new GatherOptionalBeforeActions(playerId, effect);
List<Action> result = new LinkedList<>();
_lotroGame.getGameState().iterateActivableCards(playerId, gatherActions);
List<Action> result = new LinkedList<Action>();
for (Action action : gatherActions.getActions()) {
action.setPerformingPlayer(playerId);
if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action))
result.add(action);
for (ActionProxy actionProxy : _actionProxies) {
List<? extends Action> actions = actionProxy.getOptionalBeforeActions(playerId, _lotroGame, effect);
if (actions != null) {
for (Action action : actions) {
action.setPerformingPlayer(playerId);
if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action))
result.add(action);
}
}
}
return result;
@@ -247,16 +246,19 @@ public class DefaultActionsEnvironment implements ActionsEnvironment {
@Override
public List<Action> getOptionalAfterActions(String playerId, Collection<? extends EffectResult> effectResults) {
GatherOptionalAfterActions gatherAfterActions = new GatherOptionalAfterActions(playerId, effectResults);
List<Action> result = new LinkedList<>();
_lotroGame.getGameState().iterateActivableCards(playerId, gatherAfterActions);
List<Action> result = new LinkedList<Action>();
for (Action action : gatherAfterActions.getActions()) {
action.setPerformingPlayer(playerId);
if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action))
result.add(action);
for (ActionProxy actionProxy : _actionProxies) {
for (EffectResult effectResult : effectResults) {
List<? extends Action> actions = actionProxy.getOptionalAfterActions(playerId, _lotroGame, effectResult);
if (actions != null) {
for (Action action : actions) {
action.setPerformingPlayer(playerId);
if (_lotroGame.getModifiersQuerying().canPlayAction(_lotroGame, playerId, action))
result.add(action);
}
}
}
}
return result;
@@ -356,37 +358,6 @@ public class DefaultActionsEnvironment implements ActionsEnvironment {
}
}
private class GatherOptionalBeforeActions extends CompletePhysicalCardVisitor {
private String _playerId;
private Effect _effect;
private List<Action> _actions = new LinkedList<Action>();
private GatherOptionalBeforeActions(String playerId, Effect effect) {
_playerId = playerId;
_effect = effect;
}
@Override
public void doVisitPhysicalCard(PhysicalCard physicalCard) {
if (!_lotroGame.getModifiersQuerying().hasTextRemoved(_lotroGame, physicalCard)) {
if (physicalCard.getZone().isInPlay()) {
List<? extends Action> actions = physicalCard.getBlueprint().getOptionalInPlayBeforeActions(_playerId, _lotroGame, _effect, physicalCard);
if (actions != null)
_actions.addAll(actions);
} else if (physicalCard.getZone() == Zone.HAND
&& PlayUtils.checkPlayRequirements(_lotroGame, physicalCard, Filters.any, 0, 0, false, false)) {
List<? extends Action> actions = physicalCard.getBlueprint().getPlayResponseEventBeforeActions(_playerId, _lotroGame, _effect, physicalCard);
if (actions != null)
_actions.addAll(actions);
}
}
}
public List<Action> getActions() {
return _actions;
}
}
private class GatherOptionalAfterTriggers extends CompletePhysicalCardVisitor {
private String _playerId;
private Collection<? extends EffectResult> _effectResults;
@@ -441,40 +412,6 @@ public class DefaultActionsEnvironment implements ActionsEnvironment {
}
}
private class GatherOptionalAfterActions extends CompletePhysicalCardVisitor {
private String _playerId;
private Collection<? extends EffectResult> _effectResults;
private List<Action> _actions = new LinkedList<Action>();
private GatherOptionalAfterActions(String playerId, Collection<? extends EffectResult> effectResults) {
_playerId = playerId;
_effectResults = effectResults;
}
@Override
protected void doVisitPhysicalCard(PhysicalCard physicalCard) {
if (!_lotroGame.getModifiersQuerying().hasTextRemoved(_lotroGame, physicalCard)) {
if (_effectResults != null)
for (EffectResult effectResult : _effectResults) {
if (physicalCard.getZone().isInPlay()) {
List<? extends Action> actions = physicalCard.getBlueprint().getOptionalInPlayAfterActions(_playerId, _lotroGame, effectResult, physicalCard);
if (actions != null)
_actions.addAll(actions);
} else if (physicalCard.getZone() == Zone.HAND
&& PlayUtils.checkPlayRequirements(_lotroGame, physicalCard, Filters.any, 0, 0, false, false)) {
List<? extends Action> actions = physicalCard.getBlueprint().getPlayResponseEventAfterActions(_playerId, _lotroGame, effectResult, physicalCard);
if (actions != null)
_actions.addAll(actions);
}
}
}
}
public List<Action> getActions() {
return _actions;
}
}
private class GatherPhaseActionsVisitor extends CompletePhysicalCardVisitor {
private LotroGame _game;
private String _playerId;

View File

@@ -52,8 +52,10 @@ public class RuleSet {
new FollowerRule(_actionsEnvironment).applyRule();
new PlayPermanentRule(_modifiersLogic).applyRule();
new PlayEventRule(_modifiersLogic).applyRule();
new PlayResponseEventRule(_actionsEnvironment).applyRule();
new ActivateResponseAbilitiesRule(_actionsEnvironment).applyRule();
new TakeOffRingRule(_actionsEnvironment).applyRule();
}

View File

@@ -0,0 +1,68 @@
package com.gempukku.lotro.logic.timing.rules;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.filters.Filter;
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.actions.ActivateCardAction;
import com.gempukku.lotro.logic.modifiers.condition.OrCondition;
import com.gempukku.lotro.logic.modifiers.condition.PhaseCondition;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.LinkedList;
import java.util.List;
public class ActivateResponseAbilitiesRule {
private DefaultActionsEnvironment actionsEnvironment;
public ActivateResponseAbilitiesRule(DefaultActionsEnvironment actionsEnvironment) {
this.actionsEnvironment = actionsEnvironment;
}
public void applyRule() {
actionsEnvironment.addAlwaysOnActionProxy(
new AbstractActionProxy() {
@Override
public List<? extends Action> getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) {
List<Action> result = new LinkedList<>();
for (PhysicalCard activableCard : Filters.filterActive(game, getActivatableCardsFilter(playerId))) {
if (!game.getModifiersQuerying().hasTextRemoved(game, activableCard)) {
final List<? extends ActivateCardAction> actions = activableCard.getBlueprint().getOptionalInPlayBeforeActions(playerId, game, effect, activableCard);
if (actions != null)
result.addAll(actions);
}
}
return result;
}
@Override
public List<? extends Action> getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) {
List<Action> result = new LinkedList<>();
for (PhysicalCard activableCard : Filters.filterActive(game, getActivatableCardsFilter(playerId))) {
if (!game.getModifiersQuerying().hasTextRemoved(game, activableCard)) {
final List<? extends ActivateCardAction> actions = activableCard.getBlueprint().getOptionalInPlayAfterActions(playerId, game, effectResult, activableCard);
if (actions != null)
result.addAll(actions);
}
}
return result;
}
}
);
}
private Filter getActivatableCardsFilter(String playerId) {
return Filters.conditionFilter(
Filters.or(Filters.currentSite, Filters.and(Filters.not(CardType.SITE), Filters.owner(playerId))),
new OrCondition(new PhaseCondition(Phase.PUT_RING_BEARER), new PhaseCondition(Phase.PLAY_STARTING_FELLOWSHIP)),
Filters.and(Filters.not(CardType.SITE), Filters.owner(playerId)));
}
}

View File

@@ -0,0 +1,61 @@
package com.gempukku.lotro.logic.timing.rules;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Side;
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.PlayUtils;
import com.gempukku.lotro.logic.actions.PlayEventAction;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.Effect;
import com.gempukku.lotro.logic.timing.EffectResult;
import java.util.LinkedList;
import java.util.List;
public class PlayResponseEventRule {
private DefaultActionsEnvironment actionsEnvironment;
public PlayResponseEventRule(DefaultActionsEnvironment actionsEnvironment) {
this.actionsEnvironment = actionsEnvironment;
}
public void applyRule() {
actionsEnvironment.addAlwaysOnActionProxy(
new AbstractActionProxy() {
@Override
public List<? extends Action> getOptionalAfterActions(String playerId, LotroGame game, EffectResult effectResult) {
List<Action> result = new LinkedList<>();
final Side side = GameUtils.getSide(game, playerId);
for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) {
final List<PlayEventAction> actions = responseEvent.getBlueprint().getPlayResponseEventAfterActions(playerId, game, effectResult, responseEvent);
if (actions != null)
result.addAll(actions);
}
}
return result;
}
@Override
public List<? extends Action> getOptionalBeforeActions(String playerId, LotroGame game, Effect effect) {
List<Action> result = new LinkedList<>();
final Side side = GameUtils.getSide(game, playerId);
for (PhysicalCard responseEvent : Filters.filter(game.getGameState().getHand(playerId), game, side, CardType.EVENT, Keyword.RESPONSE)) {
if (PlayUtils.checkPlayRequirements(game, responseEvent, Filters.any, 0, 0, false, false)) {
final List<PlayEventAction> actions = responseEvent.getBlueprint().getPlayResponseEventBeforeActions(playerId, game, effect, responseEvent);
if (actions != null)
result.addAll(actions);
}
}
return result;
}
}
);
}
}