Adding initiative to the mix.

Removing Side.Site and Side.RING, wherever they were used, replaced with CardType.SITE, CardType.THE_ONE_RING.
This commit is contained in:
marcins78@gmail.com
2011-10-25 13:28:35 +00:00
parent 0f90f8f9b0
commit 31d1a4f8b2
17 changed files with 94 additions and 17 deletions

View File

@@ -2,7 +2,6 @@ package com.gempukku.lotro.cards;
import com.gempukku.lotro.common.Block; import com.gempukku.lotro.common.Block;
import com.gempukku.lotro.common.CardType; import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.timing.Action; import com.gempukku.lotro.logic.timing.Action;
@@ -14,7 +13,7 @@ public abstract class AbstractSite extends AbstractLotroCardBlueprint {
private Direction _siteDirection; private Direction _siteDirection;
public AbstractSite(String name, Block block, int siteNumber, int twilight, Direction siteDirection) { public AbstractSite(String name, Block block, int siteNumber, int twilight, Direction siteDirection) {
super(Side.SITE, CardType.SITE, null, name); super(null, CardType.SITE, null, name);
_block = block; _block = block;
_siteNumber = siteNumber; _siteNumber = siteNumber;
_twilight = twilight; _twilight = twilight;

View File

@@ -83,6 +83,7 @@ public class PlayEventAction extends AbstractCostToEffectAction {
if (!_cardRemoved) { if (!_cardRemoved) {
_cardRemoved = true; _cardRemoved = true;
game.getGameState().removeCardsFromZone(_eventPlayed.getOwner(), Collections.singleton(_eventPlayed)); game.getGameState().removeCardsFromZone(_eventPlayed.getOwner(), Collections.singleton(_eventPlayed));
game.getGameState().addCardToZone(game, _eventPlayed, Zone.VOID);
} }
if (!isCostFailed()) { if (!isCostFailed()) {

View File

@@ -69,6 +69,7 @@ public class PlayPermanentAction extends AbstractCostToEffectAction {
if (!_cardRemoved) { if (!_cardRemoved) {
_cardRemoved = true; _cardRemoved = true;
game.getGameState().removeCardsFromZone(_permanentPlayed.getOwner(), Collections.singleton(_permanentPlayed)); game.getGameState().removeCardsFromZone(_permanentPlayed.getOwner(), Collections.singleton(_permanentPlayed));
game.getGameState().addCardToZone(game, _permanentPlayed, Zone.VOID);
} }
if (!isCostFailed()) { if (!isCostFailed()) {

View File

@@ -11,7 +11,6 @@ import com.gempukku.lotro.cards.modifiers.VitalityModifier;
import com.gempukku.lotro.common.CardType; import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword; import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.filters.Filter; import com.gempukku.lotro.filters.Filter;
import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.PhysicalCard;
@@ -40,7 +39,7 @@ import java.util.List;
*/ */
public class Card1_001 extends AbstractAttachable { public class Card1_001 extends AbstractAttachable {
public Card1_001() { public Card1_001() {
super(Side.RING, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true); super(null, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true);
} }
@Override @Override

View File

@@ -10,7 +10,6 @@ import com.gempukku.lotro.cards.modifiers.StrengthModifier;
import com.gempukku.lotro.common.CardType; import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword; import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.filters.Filter; import com.gempukku.lotro.filters.Filter;
import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.PhysicalCard;
@@ -39,7 +38,7 @@ import java.util.List;
*/ */
public class Card1_002 extends AbstractAttachable { public class Card1_002 extends AbstractAttachable {
public Card1_002() { public Card1_002() {
super(Side.RING, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true); super(null, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true);
} }
@Override @Override

View File

@@ -11,7 +11,6 @@ import com.gempukku.lotro.cards.modifiers.VitalityModifier;
import com.gempukku.lotro.common.CardType; import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword; import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.filters.Filter; import com.gempukku.lotro.filters.Filter;
import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.PhysicalCard;
@@ -38,7 +37,7 @@ import java.util.List;
*/ */
public class Card4_001 extends AbstractAttachable { public class Card4_001 extends AbstractAttachable {
public Card4_001() { public Card4_001() {
super(Side.RING, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true); super(null, CardType.THE_ONE_RING, 0, null, null, "The One Ring", true);
} }
@Override @Override

View File

@@ -63,6 +63,7 @@ public class Card6_011 extends AbstractEvent {
@Override @Override
protected void validDecisionMade(int index, String result) { protected void validDecisionMade(int index, String result) {
action.skipDiscardPart(); action.skipDiscardPart();
game.getGameState().removeCardsFromZone(playerId, Collections.singleton(self));
if (index == 0) if (index == 0)
game.getGameState().putCardOnTopOfDeck(self); game.getGameState().putCardOnTopOfDeck(self);
else else

View File

@@ -1,5 +1,5 @@
package com.gempukku.lotro.common; package com.gempukku.lotro.common;
public enum Side implements Filterable { public enum Side implements Filterable {
FREE_PEOPLE, SHADOW, RING, SITE FREE_PEOPLE, SHADOW
} }

View File

@@ -3,7 +3,7 @@ package com.gempukku.lotro.common;
public enum Zone implements Filterable { public enum Zone implements Filterable {
FREE_CHARACTERS("play", true), SUPPORT("play", true), SHADOW_CHARACTERS("play", true), FREE_CHARACTERS("play", true), SUPPORT("play", true), SHADOW_CHARACTERS("play", true),
ADVENTURE_PATH("play", true), ADVENTURE_PATH("play", true),
HAND("hand", false), DECK("deck", false), ATTACHED("play", true), STACKED("stacked", false), HAND("hand", false), VOID("void", false), DECK("deck", false), ATTACHED("play", true), STACKED("stacked", false),
DISCARD("discard", false), DEAD("dead pile", false); DISCARD("discard", false), DEAD("dead pile", false);
private String _humanReadable; private String _humanReadable;

View File

@@ -29,6 +29,8 @@ public class GameState {
private Map<String, List<PhysicalCardImpl>> _deadPiles = new HashMap<String, List<PhysicalCardImpl>>(); private Map<String, List<PhysicalCardImpl>> _deadPiles = new HashMap<String, List<PhysicalCardImpl>>();
private Map<String, List<PhysicalCardImpl>> _stacked = new HashMap<String, List<PhysicalCardImpl>>(); private Map<String, List<PhysicalCardImpl>> _stacked = new HashMap<String, List<PhysicalCardImpl>>();
private Map<String, List<PhysicalCardImpl>> _voids = new HashMap<String, List<PhysicalCardImpl>>();
private List<PhysicalCardImpl> _inPlay = new LinkedList<PhysicalCardImpl>(); private List<PhysicalCardImpl> _inPlay = new LinkedList<PhysicalCardImpl>();
private Map<Integer, PhysicalCardImpl> _allCards = new HashMap<Integer, PhysicalCardImpl>(); private Map<Integer, PhysicalCardImpl> _allCards = new HashMap<Integer, PhysicalCardImpl>();
@@ -42,6 +44,8 @@ public class GameState {
private boolean _wearingRing; private boolean _wearingRing;
private boolean _consecutiveAction; private boolean _consecutiveAction;
private Side _initiativeSide;
private Map<String, Integer> _playerPosition = new HashMap<String, Integer>(); private Map<String, Integer> _playerPosition = new HashMap<String, Integer>();
private Map<PhysicalCard, Map<Token, Integer>> _cardTokens = new HashMap<PhysicalCard, Map<Token, Integer>>(); private Map<PhysicalCard, Map<Token, Integer>> _cardTokens = new HashMap<PhysicalCard, Map<Token, Integer>>();
@@ -67,6 +71,7 @@ public class GameState {
_adventureDecks.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _adventureDecks.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_decks.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _decks.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_hands.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _hands.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_voids.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_discards.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _discards.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_deadPiles.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _deadPiles.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
_stacked.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>()); _stacked.put(stringListEntry.getKey(), new LinkedList<PhysicalCardImpl>());
@@ -97,6 +102,14 @@ public class GameState {
return new String(chars); return new String(chars);
} }
public void setInitiativeSide(Side initiativeSide) {
_initiativeSide = initiativeSide;
}
public Side getInitiativeSide() {
return _initiativeSide;
}
public void gameFinished() { public void gameFinished() {
File gameReplayFolder = new File("i:\\gemp-lotr\\replay"); File gameReplayFolder = new File("i:\\gemp-lotr\\replay");
gameReplayFolder.mkdirs(); gameReplayFolder.mkdirs();
@@ -345,6 +358,8 @@ public class GameState {
return _deadPiles.get(playerId); return _deadPiles.get(playerId);
else if (zone == Zone.HAND) else if (zone == Zone.HAND)
return _hands.get(playerId); return _hands.get(playerId);
else if (zone == Zone.VOID)
return _voids.get(playerId);
else if (zone == Zone.STACKED) else if (zone == Zone.STACKED)
return _stacked.get(playerId); return _stacked.get(playerId);
else else
@@ -527,7 +542,7 @@ public class GameState {
return true; return true;
for (PhysicalCardImpl physicalCard : _inPlay) { for (PhysicalCardImpl physicalCard : _inPlay) {
if (physicalCard.getOwner().equals(player) if (physicalCard.getOwner().equals(player)
&& physicalCard.getBlueprint().getSide() != Side.SITE && isCardInPlayActive(physicalCard)) && physicalCard.getBlueprint().getCardType() != CardType.SITE && isCardInPlayActive(physicalCard))
if (physicalCardVisitor.visitPhysicalCard(physicalCard)) if (physicalCardVisitor.visitPhysicalCard(physicalCard))
return true; return true;
} }
@@ -561,6 +576,10 @@ public class GameState {
return Collections.unmodifiableList(_hands.get(playerId)); return Collections.unmodifiableList(_hands.get(playerId));
} }
public List<? extends PhysicalCard> getVoid(String playerId) {
return Collections.unmodifiableList(_voids.get(playerId));
}
public List<? extends PhysicalCard> getDeck(String playerId) { public List<? extends PhysicalCard> getDeck(String playerId) {
return Collections.unmodifiableList(_decks.get(playerId)); return Collections.unmodifiableList(_decks.get(playerId));
} }
@@ -731,7 +750,7 @@ public class GameState {
Side side = card.getBlueprint().getSide(); Side side = card.getBlueprint().getSide();
// Either it's not attached or attached to active card // Either it's not attached or attached to active card
// AND is a site or fp/ring of current player or shadow of any other player // AND is a site or fp/ring of current player or shadow of any other player
return side == Side.SITE return card.getBlueprint().getCardType() == CardType.SITE
|| ( || (
card.getAttachedTo() == null && card.getAttachedTo() == null &&
((card.getOwner().equals(_currentPlayerId) && (side == Side.FREE_PEOPLE)) ((card.getOwner().equals(_currentPlayerId) && (side == Side.FREE_PEOPLE))
@@ -743,7 +762,7 @@ public class GameState {
public void startAffectingCardsForCurrentPlayer(LotroGame game) { public void startAffectingCardsForCurrentPlayer(LotroGame game) {
// Active non-sites are affecting // Active non-sites are affecting
for (PhysicalCardImpl physicalCard : _inPlay) { for (PhysicalCardImpl physicalCard : _inPlay) {
if (isCardInPlayActive(physicalCard) && physicalCard.getBlueprint().getSide() != Side.SITE) if (isCardInPlayActive(physicalCard) && physicalCard.getBlueprint().getCardType() != CardType.SITE)
startAffecting(game, physicalCard); startAffecting(game, physicalCard);
} }
@@ -759,7 +778,7 @@ public class GameState {
public void stopAffectingCardsForCurrentPlayer() { public void stopAffectingCardsForCurrentPlayer() {
for (PhysicalCardImpl physicalCard : _inPlay) { for (PhysicalCardImpl physicalCard : _inPlay) {
if (isCardInPlayActive(physicalCard) && physicalCard.getBlueprint().getSide() != Side.SITE) if (isCardInPlayActive(physicalCard) && physicalCard.getBlueprint().getCardType() != CardType.SITE)
stopAffecting(physicalCard); stopAffecting(physicalCard);
} }

View File

@@ -13,7 +13,7 @@ public class PlayCardEffect extends AbstractEffect {
private PhysicalCard _attachedToCard; private PhysicalCard _attachedToCard;
public PlayCardEffect(PhysicalCard cardPlayed) { public PlayCardEffect(PhysicalCard cardPlayed) {
_cardPlayed = cardPlayed; this(cardPlayed, null);
} }
public PlayCardEffect(PhysicalCard cardPlayed, PhysicalCard attachedToCard) { public PlayCardEffect(PhysicalCard cardPlayed, PhysicalCard attachedToCard) {
@@ -46,6 +46,7 @@ public class PlayCardEffect extends AbstractEffect {
@Override @Override
protected FullEffectResult playEffectReturningResult(LotroGame game) { protected FullEffectResult playEffectReturningResult(LotroGame game) {
game.getGameState().removeCardsFromZone(_cardPlayed.getOwner(), Collections.singleton(_cardPlayed));
return new FullEffectResult(Collections.singleton(new PlayCardResult(_cardPlayed, _attachedToCard)), true, true); return new FullEffectResult(Collections.singleton(new PlayCardResult(_cardPlayed, _attachedToCard)), true, true);
} }
} }

View File

@@ -7,11 +7,13 @@ import com.gempukku.lotro.logic.timing.results.PlayEventResult;
import java.util.Collections; import java.util.Collections;
public class PlayEventEffect extends PlayCardEffect { public class PlayEventEffect extends PlayCardEffect {
private PhysicalCard _cardPlayed;
private boolean _requiresRanger; private boolean _requiresRanger;
private PlayEventResult _playEventResult; private PlayEventResult _playEventResult;
public PlayEventEffect(PhysicalCard cardPlayed, boolean requiresRanger) { public PlayEventEffect(PhysicalCard cardPlayed, boolean requiresRanger) {
super(cardPlayed); super(cardPlayed);
_cardPlayed = cardPlayed;
_requiresRanger = requiresRanger; _requiresRanger = requiresRanger;
_playEventResult = new PlayEventResult(getPlayedCard(), _requiresRanger); _playEventResult = new PlayEventResult(getPlayedCard(), _requiresRanger);
} }
@@ -22,6 +24,7 @@ public class PlayEventEffect extends PlayCardEffect {
@Override @Override
protected FullEffectResult playEffectReturningResult(LotroGame game) { protected FullEffectResult playEffectReturningResult(LotroGame game) {
game.getGameState().removeCardsFromZone(_cardPlayed.getOwner(), Collections.singleton(_cardPlayed));
return new FullEffectResult(Collections.singleton(_playEventResult), true, true); return new FullEffectResult(Collections.singleton(_playEventResult), true, true);
} }
} }

View File

@@ -527,6 +527,16 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
return true; return true;
} }
@Override
public boolean hasInitiative(GameState gameState, Side side) {
int freePeopleInitiativeHandSize = gameState.getHand(gameState.getCurrentPlayerId()).size()
+ gameState.getVoid(gameState.getCurrentPlayerId()).size();
if (side == Side.SHADOW)
return freePeopleInitiativeHandSize < 4;
else
return freePeopleInitiativeHandSize >= 4;
}
@Override @Override
public int getSpotCount(GameState gameState, Filter filter, int inPlayCount) { public int getSpotCount(GameState gameState, Filter filter, int inPlayCount) {
int result = inPlayCount; int result = inPlayCount;

View File

@@ -88,6 +88,8 @@ public interface ModifiersQuerying {
public boolean canDiscardCardsFromTopOfDeck(GameState gameState, String playerId, PhysicalCard source); public boolean canDiscardCardsFromTopOfDeck(GameState gameState, String playerId, PhysicalCard source);
public boolean hasInitiative(GameState gameState, Side side);
public int getSpotCount(GameState gameState, Filter filter, int inPlayCount); public int getSpotCount(GameState gameState, Filter filter, int inPlayCount);
public boolean hasFlagActive(ModifierFlag modifierFlag); public boolean hasFlagActive(ModifierFlag modifierFlag);

View File

@@ -19,7 +19,8 @@ public abstract class EffectResult {
PUT_ON_THE_ONE_RING, REMOVE_BURDEN, ADD_BURDEN, PUT_ON_THE_ONE_RING, REMOVE_BURDEN, ADD_BURDEN,
WHEN_MOVE_FROM, WHEN_FELLOWSHIP_MOVES, WHEN_MOVE_TO, WHEN_MOVE_FROM, WHEN_FELLOWSHIP_MOVES, WHEN_MOVE_TO,
REVEAL_CARDS_FROM_HAND REVEAL_CARDS_FROM_HAND,
INITIATIVE_CHANGE
} }
private Type _type; private Type _type;

View File

@@ -1,5 +1,6 @@
package com.gempukku.lotro.logic.timing; package com.gempukku.lotro.logic.timing;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.communication.UserFeedback; import com.gempukku.lotro.communication.UserFeedback;
import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.game.state.LotroGame;
@@ -11,6 +12,7 @@ import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.timing.actions.SystemAction; import com.gempukku.lotro.logic.timing.actions.SystemAction;
import com.gempukku.lotro.logic.timing.processes.GameProcess; import com.gempukku.lotro.logic.timing.processes.GameProcess;
import com.gempukku.lotro.logic.timing.processes.pregame.BiddingGameProcess; import com.gempukku.lotro.logic.timing.processes.pregame.BiddingGameProcess;
import com.gempukku.lotro.logic.timing.results.InitiativeChangeResult;
import java.util.*; import java.util.*;
@@ -39,6 +41,16 @@ public class TurnProcedure {
return _gameStats; return _gameStats;
} }
private EffectResult getOptionalInitiativeChangeResult() {
Side oldSide = _game.getGameState().getInitiativeSide();
if (!_game.getModifiersQuerying().hasInitiative(_game.getGameState(), oldSide)) {
Side newSide = (oldSide == Side.SHADOW) ? Side.FREE_PEOPLE : Side.SHADOW;
_game.getGameState().setInitiativeSide(newSide);
return new InitiativeChangeResult(newSide);
}
return null;
}
public void carryOutPendingActionsUntilDecisionNeeded() { public void carryOutPendingActionsUntilDecisionNeeded() {
while (!_userFeedback.hasPendingDecisions() && _game.getWinnerPlayerId() == null) { while (!_userFeedback.hasPendingDecisions() && _game.getWinnerPlayerId() == null) {
if (_actionStack.isEmpty()) { if (_actionStack.isEmpty()) {
@@ -100,7 +112,20 @@ public class TurnProcedure {
return new StackActionEffect(action); return new StackActionEffect(action);
} }
if (!_effectPlayed) { if (!_effectPlayed) {
_effectResults = _effect.playEffect(_game); final Collection<? extends EffectResult> effectResults = _effect.playEffect(_game);
List<EffectResult> results = new LinkedList<EffectResult>();
if (effectResults != null)
results.addAll(effectResults);
// check for changing initiative, ugly but it's a sort of state based effect and not a trigger, just
// results in maybe generating a trigger along with others that might happen at the same time (discard
// cards, play cards, draw cards, etc)
EffectResult initiativeEffectResult = getOptionalInitiativeChangeResult();
if (initiativeEffectResult != null)
results.add(initiativeEffectResult);
_effectResults = results;
if (_gameStats.updateGameStats(_game)) if (_gameStats.updateGameStats(_game))
_game.getGameState().sendGameStats(_gameStats); _game.getGameState().sendGameStats(_gameStats);
_effectPlayed = true; _effectPlayed = true;

View File

@@ -0,0 +1,17 @@
package com.gempukku.lotro.logic.timing.results;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.logic.timing.EffectResult;
public class InitiativeChangeResult extends EffectResult {
private Side _side;
public InitiativeChangeResult(Side side) {
super(Type.INITIATIVE_CHANGE);
_side = side;
}
public Side getSide() {
return _side;
}
}