diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java index f125c3a84..6b4db7475 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java @@ -47,6 +47,8 @@ public class GameState { private Side _initiativeSide; private Map _playerPosition = new HashMap(); + private Map _playerThreats = new HashMap(); + private Map> _cardTokens = new HashMap>(); private Map _ringBearers = new HashMap(); @@ -83,6 +85,8 @@ public class GameState { GatheringParticipantCommunicationChannel listener = new GatheringParticipantCommunicationChannel(playerId); listener.setPlayerOrder(playerOrder.getAllPlayers()); _recordingListeners.put(playerId, listener); + + _playerThreats.put(playerId, 0); } for (String playerId : _gameStateListeners.keySet()) @@ -610,6 +614,16 @@ public class GameState { listener.setPlayerPosition(playerId, i); } + public void addThreats(String playerId, int count) { + _playerThreats.put(playerId, _playerThreats.get(playerId) + count); + } + + public void removeThreats(String playerId, int count) { + final int oldThreats = _playerThreats.get(playerId); + count = Math.min(count, oldThreats); + _playerThreats.put(playerId, oldThreats - count); + } + public void movePlayerToNextSite(LotroGame game) { final String currentPlayerId = getCurrentPlayerId(); final int oldPlayerPosition = getPlayerPosition(currentPlayerId); @@ -672,6 +686,10 @@ public class GameState { return getTokenCount(_ringBearers.get(getCurrentPlayerId()), Token.BURDEN); } + public int getThreats() { + return _playerThreats.get(getCurrentPlayerId()); + } + public void removeBurdens(int burdens) { removeTokens(_ringBearers.get(getCurrentPlayerId()), Token.BURDEN, Math.max(0, burdens)); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/RemoveThreatsEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/RemoveThreatsEffect.java new file mode 100644 index 000000000..6b39b9a25 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/RemoveThreatsEffect.java @@ -0,0 +1,43 @@ +package com.gempukku.lotro.logic.effects; + +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.timing.AbstractEffect; + +public class RemoveThreatsEffect extends AbstractEffect { + private PhysicalCard _source; + private int _count; + + public RemoveThreatsEffect(PhysicalCard source, int count) { + _source = source; + _count = count; + } + + @Override + public String getText(LotroGame game) { + return null; + } + + @Override + public Type getType() { + return null; + } + + @Override + public boolean isPlayableInFull(LotroGame game) { + return game.getGameState().getThreats() >= _count; + } + + @Override + protected FullEffectResult playEffectReturningResult(LotroGame game) { + int toRemove = Math.min(game.getGameState().getThreats(), _count); + + if (_source != null) + game.getGameState().sendMessage(GameUtils.getCardLink(_source) + " removed " + toRemove + " threat" + ((toRemove > 1) ? "s" : "")); + + game.getGameState().removeThreats(game.getGameState().getCurrentPlayerId(), toRemove); + + return new FullEffectResult(null, _count == toRemove, _count == toRemove); + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ThreatRule.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ThreatRule.java new file mode 100644 index 000000000..902876138 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/ThreatRule.java @@ -0,0 +1,49 @@ +package com.gempukku.lotro.logic.timing.rules; + +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.AbstractActionProxy; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment; +import com.gempukku.lotro.logic.actions.RequiredTriggerAction; +import com.gempukku.lotro.logic.effects.ChooseAndWoundCharactersEffect; +import com.gempukku.lotro.logic.effects.RemoveThreatsEffect; +import com.gempukku.lotro.logic.timing.Action; +import com.gempukku.lotro.logic.timing.EffectResult; +import com.gempukku.lotro.logic.timing.results.KillResult; + +import java.util.Collections; +import java.util.List; + +public class ThreatRule { + private DefaultActionsEnvironment _actionsEnvironment; + + public ThreatRule(DefaultActionsEnvironment actionsEnvironment) { + _actionsEnvironment = actionsEnvironment; + } + + public void applyRule() { + _actionsEnvironment.addAlwaysOnActionProxy( + new AbstractActionProxy() { + @Override + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult) { + if (effectResult.getType() == EffectResult.Type.KILL) { + KillResult killResult = (KillResult) effectResult; + boolean threatsTrigger = Filters.filter(killResult.getKilledCards(), game.getGameState(), game.getModifiersQuerying(), Filters.or(CardType.COMPANION, CardType.ALLY)).size() > 0; + int threats = game.getGameState().getThreats(); + if (threatsTrigger && threats > 0) { + RequiredTriggerAction action = new RequiredTriggerAction(null); + action.setText("Threat damage assignment"); + action.appendEffect( + new RemoveThreatsEffect(null, threats)); + for (int i = 0; i < threats; i++) + action.appendEffect( + new ChooseAndWoundCharactersEffect(action, game.getGameState().getCurrentPlayerId(), 1, 1, CardType.COMPANION)); + return Collections.singletonList(action); + } + } + return null; + } + }); + } +}