package com.cardshifter.modapi.cards; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import com.cardshifter.modapi.actions.ActionAllowedCheckEvent; import com.cardshifter.modapi.actions.ActionComponent; import com.cardshifter.modapi.actions.ECSAction; import com.cardshifter.modapi.actions.TargetableCheckEvent; import com.cardshifter.modapi.base.ComponentRetriever; import com.cardshifter.modapi.base.ECSGame; import com.cardshifter.modapi.base.ECSSystem; import com.cardshifter.modapi.base.Entity; import com.cardshifter.modapi.base.PlayerComponent; import com.cardshifter.modapi.phase.Phase; import com.cardshifter.modapi.phase.PhaseController; public class MulliganSingleCards implements ECSSystem { private static final String PHASE_NAME = "Mulligan"; private static final String ACTION_NAME = "Mulligan"; private final PhaseController phases; private final AtomicInteger remainingPerforms = new AtomicInteger(0); public MulliganSingleCards(ECSGame game) { phases = ComponentRetriever.singleton(game, PhaseController.class); phases.insertTemporaryPhaseBeforeCurrent(new Phase(null, PHASE_NAME)); } @Override public void startGame(ECSGame game) { ComponentRetriever<ActionComponent> actions = ComponentRetriever.retreiverFor(ActionComponent.class); game.getEvents().registerHandlerAfter(this, TargetableCheckEvent.class, this::targetAllowed); game.getEvents().registerHandlerAfter(this, ActionAllowedCheckEvent.class, this::actionAllowed); Set<Entity> players = game.getEntitiesWithComponent(PlayerComponent.class); remainingPerforms.set(players.size()); for (Entity player : players) { ActionComponent playerActions = player.get(actions); if (playerActions == null) { playerActions = new ActionComponent(); player.addComponent(playerActions); } playerActions.addAction(createMulliganAction(player)); } } private ECSAction createMulliganAction(Entity player) { return new ECSAction(player, ACTION_NAME, act -> true, this::performAction).addTargetSet(0, Integer.MAX_VALUE); } private void actionAllowed(ActionAllowedCheckEvent event) { if (!event.getAction().getName().equals(ACTION_NAME)) { return; } if (event.getEntity() != event.getPerformer()) { event.setAllowed(false); } if (!PHASE_NAME.equals(phases.getCurrentPhase().getName())) { event.setAllowed(false); } } private void targetAllowed(TargetableCheckEvent event) { if (!event.getAction().getName().equals(ACTION_NAME)) { return; } if (!event.getTarget().hasComponent(CardComponent.class)) { event.setAllowed(false); return; } if (!Cards.isOnZone(event.getTarget(), HandComponent.class)) { event.setAllowed(false); } if (!Cards.isOwnedBy(event.getTarget(), event.getAction().getOwner())) { event.setAllowed(false); } } private void performAction(ECSAction mulliganAction) { List<Entity> chosenTargets = mulliganAction.getTargetSets().get(0).getChosenTargets(); chosenTargets.forEach(this::switchCard); Entity owner = mulliganAction.getOwner(); owner.getComponent(ActionComponent.class).removeAction(ACTION_NAME); owner.getComponent(DeckComponent.class).shuffle(); if (remainingPerforms.decrementAndGet() == 0) { phases.nextPhase(); } } private void switchCard(Entity e) { ComponentRetriever<CardComponent> cards = ComponentRetriever.retreiverFor(CardComponent.class); Entity owner = cards.get(e).getOwner(); DeckComponent deck = owner.getComponent(DeckComponent.class); cards.get(e).moveToBottom(deck); DrawStartCards.drawCard(owner); } }