- Basic support for CountersMoveAi (e.g. The Ozolith) so at least it doesn't crash, needs improvement.

This commit is contained in:
Hans Mackowiak
2020-05-27 00:17:28 +00:00
committed by Sol
parent 955a16f1e0
commit 6fde7149a4
180 changed files with 1995 additions and 1619 deletions

View File

@@ -17,7 +17,6 @@ import forge.game.card.CardView;
import forge.game.event.*;
import forge.game.player.Player;
import forge.game.player.PlayerView;
import forge.game.zone.PlayerZone;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.interfaces.IGuiGame;
@@ -294,7 +293,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
@Override
public Void visit(final GameEventCardAttachment event) {
final Game game = event.equipment.getGame();
final PlayerZone zEq = (PlayerZone)game.getZoneOf(event.equipment);
final Zone zEq = (Zone)game.getZoneOf(event.equipment);
if (event.oldEntiy instanceof Card) {
updateZone(game.getZoneOf((Card)event.oldEntiy));
}

View File

@@ -189,6 +189,21 @@ public final class InputSelectTargets extends InputSyncronizedBase {
}
}
// If all cards must have different controllers
if (tgt.isSameController()) {
final List<Player> targetedControllers = new ArrayList<>();
for (final GameObject o : targetDepth.keySet()) {
if (o instanceof Card) {
final Player p = ((Card) o).getController();
targetedControllers.add(p);
}
}
if (!targetedControllers.isEmpty() && !targetedControllers.contains(card.getController())) {
showMessage(sa.getHostCard() + " - Cannot target this card (must have same controller)");
return false;
}
}
// If all cards must have different controllers
if (tgt.isDifferentControllers()) {
final List<Player> targetedControllers = new ArrayList<>();
@@ -333,7 +348,6 @@ public final class InputSelectTargets extends InputSyncronizedBase {
return tgt.isMaxTargetsChosen(sa.getHostCard(), sa) || ( tgt.getStillToDivide() == 0 && tgt.isDividedAsYouChoose());
}
@Override
protected void onStop() {
getController().getGui().clearSelectables();

View File

@@ -24,6 +24,7 @@ import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CardPredicates.Presets;
import forge.game.card.CardView;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
import forge.game.cost.*;
import forge.game.player.Player;
@@ -625,7 +626,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
@Override
public PaymentDecision visit(final CostPayEnergy cost) {
final String amount = cost.getAmount();
final int energy = player.getCounters(CounterType.ENERGY);
final int energy = player.getCounters(CounterEnumType.ENERGY);
Integer c = cost.convertAmount();
if (c == null) {
@@ -641,7 +642,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
}
if (player.canPayEnergy(c) &&
player.getController().confirmPayment(cost, Localizer.getInstance().getMessage("lblPayEnergyConfirm", cost.toString(), String.valueOf(player.getCounters(CounterType.ENERGY)), "{E}"), ability)) {
player.getController().confirmPayment(cost, Localizer.getInstance().getMessage("lblPayEnergyConfirm", cost.toString(), String.valueOf(player.getCounters(CounterEnumType.ENERGY)), "{E}"), ability)) {
return PaymentDecision.number(c);
}
return null;

View File

@@ -566,7 +566,7 @@ public class HumanPlay {
}
}
else if (part instanceof CostPayEnergy) {
CounterType counterType = CounterType.ENERGY;
CounterType counterType = CounterType.get(CounterEnumType.ENERGY);
int amount = getAmountFromPartX(part, source, sourceAbility);
if (!part.canPay(sourceAbility, p)) {

View File

@@ -214,7 +214,7 @@ public class HumanPlaySpellAbility {
final FCollection<Player> candidates = AbilityUtils.getDefinedPlayers(source, currentAbility.getParam("TargetingPlayer"), currentAbility);
// activator chooses targeting player
targetingPlayer = ability.getActivatingPlayer().getController().chooseSingleEntityForEffect(
candidates, currentAbility, "Choose the targeting player");
candidates, currentAbility, "Choose the targeting player", null);
} else {
targetingPlayer = ability.getActivatingPlayer();
}

View File

@@ -392,13 +392,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public CardCollectionView chooseCardsForEffect(final CardCollectionView sourceList, final SpellAbility sa,
final String title, final int min, final int max, final boolean isOptional) {
final String title, final int min, final int max, final boolean isOptional, Map<String, Object> params) {
// If only one card to choose, use a dialog box.
// Otherwise, use the order dialog to be able to grab multiple cards in
// one shot
if (max == 1) {
final Card singleChosen = chooseSingleEntityForEffect(sourceList, sa, title, isOptional);
final Card singleChosen = chooseSingleEntityForEffect(sourceList, sa, title, isOptional, params);
return singleChosen == null ? CardCollection.EMPTY : new CardCollection(singleChosen);
}
@@ -427,7 +427,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
@Override
public <T extends GameEntity> T chooseSingleEntityForEffect(final FCollectionView<T> optionList,
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final boolean isOptional,
final Player targetedPlayer) {
final Player targetedPlayer, Map<String, Object> params) {
// Human is supposed to read the message and understand from it what to
// choose
if (optionList.isEmpty()) {
@@ -465,6 +465,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final GameEntityView result = getGui().chooseSingleEntityForEffect(title,
gameCacheChoose.getTrackableKeys(), delayedReveal, isOptional);
endTempShowCards();
if (result != null || !gameCacheChoose.containsKey(result)) {
return null;
}
@@ -472,9 +473,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
}
@Override
public <T extends GameEntity> List<T> chooseEntitiesForEffect(final FCollectionView<T> optionList, final int min,
final int max, final DelayedReveal delayedReveal, final SpellAbility sa, final String title,
final Player targetedPlayer) {
public <T extends GameEntity> List<T> chooseEntitiesForEffect(final FCollectionView<T> optionList, final int min, final int max,
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer, Map<String, Object> params) {
// useful details for debugging problems with the mass select logic
Sentry.getContext().addExtra("Card", sa.getCardView().toString());
@@ -554,6 +555,22 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
return spellViewCache.get(choice);
}
@Override
public List<SpellAbility> chooseSpellAbilitiesForEffect(List<SpellAbility> spells, SpellAbility sa, String title, int num, Map<String, Object> params) {
List<SpellAbility> result = Lists.newArrayList();
// create a mapping between a spell's view and the spell itself
Map<SpellAbilityView, SpellAbility> spellViewCache = SpellAbilityView.getMap(spells);
List<SpellAbilityView> chosen = getGui().many(title, "", num, Lists.newArrayList(spellViewCache.keySet()), sa.getHostCard().getView());
for(SpellAbilityView view : chosen) {
if (spellViewCache.containsKey(view)) {
result.add(spellViewCache.get(view));
}
}
return result;
}
/*
* (non-Javadoc)
*
@@ -1848,13 +1865,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public Card chooseSingleCardForZoneChange(final ZoneType destination, final List<ZoneType> origin,
final SpellAbility sa, final CardCollection fetchList, final DelayedReveal delayedReveal,
final String selectPrompt, final boolean isOptional, final Player decider) {
return chooseSingleEntityForEffect(fetchList, delayedReveal, sa, selectPrompt, isOptional, decider);
return chooseSingleEntityForEffect(fetchList, delayedReveal, sa, selectPrompt, isOptional, decider, null);
}
public List<Card> chooseCardsForZoneChange(final ZoneType destination, final List<ZoneType> origin,
final SpellAbility sa, final CardCollection fetchList, final int min, final int max, final DelayedReveal delayedReveal,
final String selectPrompt, final Player decider) {
return chooseEntitiesForEffect(fetchList, min, max, delayedReveal, sa, selectPrompt, decider);
return chooseEntitiesForEffect(fetchList, min, max, delayedReveal, sa, selectPrompt, decider, null);
}
@Override
@@ -2200,7 +2217,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final Card card = gameCacheCounters.get(cv);
final ImmutableList<CounterType> counters = subtract ? ImmutableList.copyOf(card.getCounters().keySet())
: CounterType.values;
: ImmutableList.copyOf(Collections2.transform(CounterEnumType.values, new Function<CounterEnumType, CounterType>() {
@Override
public CounterType apply(CounterEnumType input) {
return CounterType.get(input);
}
}));
final CounterType counter = getGui().oneOrNone(localizer.getMessage("lblWhichTypeofCounter"), counters);
if (counter == null) {
@@ -2987,7 +3009,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public CardCollection chooseCardsForEffectMultiple(Map<String, CardCollection> validMap, SpellAbility sa, String title, boolean isOptional) {
CardCollection result = new CardCollection();
for (Map.Entry<String, CardCollection> e : validMap.entrySet()) {
result.addAll(chooseCardsForEffect(e.getValue(), sa, title + " " + e.getKey(), 0, 1, isOptional));
result.addAll(chooseCardsForEffect(e.getValue(), sa, title + " " + e.getKey(), 0, 1, isOptional, null));
}
return result;
}