mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'master' of https://github.com/Card-Forge/forge into adventure
Conflicts: forge-gui-mobile/src/forge/adventure/scene/DeckSelectScene.java forge-gui-mobile/src/forge/adventure/scene/HudScene.java forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java forge-gui-mobile/src/forge/adventure/scene/RewardScene.java forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java forge-gui-mobile/src/forge/adventure/scene/SettingsScene.java forge-gui-mobile/src/forge/adventure/scene/StartScene.java forge-gui-mobile/src/forge/adventure/scene/UIScene.java forge-gui-mobile/src/forge/adventure/stage/GameHUD.java forge-gui-mobile/src/forge/adventure/stage/GameStage.java forge-gui-mobile/src/forge/adventure/stage/MapStage.java forge-gui-mobile/src/forge/adventure/stage/WorldStage.java
This commit is contained in:
@@ -11,6 +11,10 @@
|
||||
<packaging>jar</packaging>
|
||||
<name>Forge Adventure</name>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gdx-nightlies</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
@@ -299,6 +303,11 @@
|
||||
<version>1.6.54-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
||||
<artifactId>gdx-controllers-desktop</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
@@ -306,4 +315,4 @@
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.ai.ability.ExploreAi;
|
||||
import forge.ai.ability.LearnAi;
|
||||
import forge.ai.simulation.SpellAbilityPicker;
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.CardType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.deck.Deck;
|
||||
@@ -1615,6 +1616,13 @@ public class AiController {
|
||||
}
|
||||
for (String sv : card.getSVars().keySet()) {
|
||||
String varValue = card.getSVar(sv);
|
||||
if (varValue.equals("Count$Domain")) {
|
||||
for (String type : landToPlay.getType().getLandTypes()) {
|
||||
if (CardType.isABasicLandType(type) && CardLists.getType(otb, type).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (varValue.startsWith("Count$Valid") || sv.equals("BuffedBy")) {
|
||||
if (varValue.contains("Land") || varValue.contains("Plains") || varValue.contains("Forest")
|
||||
|| varValue.contains("Mountain") || varValue.contains("Island") || varValue.contains("Swamp")
|
||||
|
||||
@@ -2,10 +2,12 @@ package forge.ai;
|
||||
|
||||
import static forge.ai.ComputerUtilCard.getBestCreatureAI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.cost.*;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
@@ -55,6 +57,14 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.number(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseColor cost) {
|
||||
int c = cost.getAbilityAmount(ability);
|
||||
List<String> choices = player.getController().chooseColors("Color", ability, c, c,
|
||||
new ArrayList<>(MagicColor.Constant.ONLY_COLORS));
|
||||
return PaymentDecision.colors(choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseCreatureType cost) {
|
||||
String choice = player.getController().chooseSomeType("Creature", ability, CardType.getAllCreatureTypes(),
|
||||
|
||||
@@ -1201,7 +1201,7 @@ public abstract class GameState {
|
||||
String[] allCounterStrings = counterString.split(",");
|
||||
for (final String counterPair : allCounterStrings) {
|
||||
String[] pair = counterPair.split("=", 2);
|
||||
entity.addCounterInternal(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, false, null);
|
||||
entity.addCounterInternal(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, false, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ public class SpecialCardAi {
|
||||
|
||||
Card animated = AnimateAi.becomeAnimated(sa.getHostCard(), sa.getSubAbility());
|
||||
if (sa.getHostCard().canReceiveCounters(CounterEnumType.P1P1)) {
|
||||
animated.addCounterInternal(CounterEnumType.P1P1, 2, ai, false, null);
|
||||
animated.addCounterInternal(CounterEnumType.P1P1, 2, ai, false, null, null);
|
||||
}
|
||||
boolean isOppEOT = ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai;
|
||||
boolean isValuableAttacker = ph.is(PhaseType.MAIN1, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated);
|
||||
|
||||
@@ -2,6 +2,7 @@ package forge.ai.ability;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCombat;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.Game;
|
||||
@@ -54,13 +55,14 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
final Game game = comp.getGame();
|
||||
Player enemy = comp.getWeakestOpponent();
|
||||
boolean dmgByCardsInHand = false;
|
||||
Card hostcard = sa.getHostCard();
|
||||
|
||||
if ("X".equals(sa.getParam("NumDmg")) && sa.getHostCard() != null && sa.hasSVar(sa.getParam("NumDmg")) &&
|
||||
if ("X".equals(sa.getParam("NumDmg")) && hostcard != null && sa.hasSVar(sa.getParam("NumDmg")) &&
|
||||
sa.getSVar(sa.getParam("NumDmg")).equals("TargetedPlayer$CardsInHand")) {
|
||||
dmgByCardsInHand = true;
|
||||
}
|
||||
// Not sure if type choice implemented for the AI yet but it should at least recognize this spell hits harder on larger enemy hand size
|
||||
if ("Blood Oath".equals(sa.getHostCard().getName())) {
|
||||
if ("Blood Oath".equals(hostcard.getName())) {
|
||||
dmgByCardsInHand = true;
|
||||
}
|
||||
|
||||
@@ -71,9 +73,13 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the opponent will gain life (ex. Fiery Justice), not beneficial unless life gain is harmful or ignored
|
||||
if ("OpponentGainLife".equals(sa.getParam("AILogic")) && ComputerUtil.lifegainPositive(enemy, hostcard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Benefits hitting players?
|
||||
// If has triggered ability on dealing damage to an opponent, go for it!
|
||||
Card hostcard = sa.getHostCard();
|
||||
for (Trigger trig : hostcard.getTriggers()) {
|
||||
if (trig.getMode() == TriggerType.DamageDone) {
|
||||
if ("Opponent".equals(trig.getParam("ValidTarget"))
|
||||
@@ -95,9 +101,9 @@ public abstract class DamageAiBase extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (!noPrevention) {
|
||||
restDamage = ComputerUtilCombat.predictDamageTo(enemy, restDamage, sa.getHostCard(), false);
|
||||
restDamage = ComputerUtilCombat.predictDamageTo(enemy, restDamage, hostcard, false);
|
||||
} else {
|
||||
restDamage = enemy.staticReplaceDamage(restDamage, sa.getHostCard(), false);
|
||||
restDamage = enemy.staticReplaceDamage(restDamage, hostcard, false);
|
||||
}
|
||||
|
||||
if (restDamage == 0) {
|
||||
|
||||
@@ -781,6 +781,13 @@ public class DamageDealAi extends DamageAiBase {
|
||||
sa.resetTargets();
|
||||
return false;
|
||||
}
|
||||
|
||||
// if opponent will gain life (ex. Fiery Justice), don't target only enemy player unless life gain is harmful or ignored
|
||||
if ("OpponentGainLife".equals(logic) && tcs.size() == 1 && tcs.contains(enemy) && ComputerUtil.lifegainPositive(enemy, source)) {
|
||||
sa.resetTargets();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,13 +105,11 @@ public class ManaEffectAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
PhaseHandler ph = ai.getGame().getPhaseHandler();
|
||||
boolean moreManaNextTurn = false;
|
||||
if (ph.is(PhaseType.END_OF_TURN) && (ph.getNextTurn() == ai || ComputerUtilCard.willUntap(ai, sa.getHostCard())) && canRampPool(ai, sa.getHostCard())) {
|
||||
moreManaNextTurn = true;
|
||||
}
|
||||
boolean moreManaNextTurn = ph.is(PhaseType.END_OF_TURN) && (ph.getNextTurn() == ai || ComputerUtilCard.willUntap(ai, sa.getHostCard()))
|
||||
&& canRampPool(ai, sa.getHostCard());
|
||||
|
||||
return sa.getPayCosts().hasNoManaCost() && sa.getPayCosts().isReusuableResource()
|
||||
&& sa.getSubAbility() == null && (ComputerUtil.playImmediately(ai, sa) || moreManaNextTurn);
|
||||
&& sa.getSubAbility() == null && (moreManaNextTurn || ComputerUtil.playImmediately(ai, sa));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -140,6 +140,7 @@ public final class CardEdition implements Comparable<CardEdition> {
|
||||
BUNDLE("bundle"),
|
||||
BOX_TOPPER("box topper"),
|
||||
DUNGEONS("dungeons"),
|
||||
JUMPSTART("jumpstart"),
|
||||
REBALANCED("rebalanced");
|
||||
|
||||
private final String name;
|
||||
|
||||
@@ -43,6 +43,11 @@ public final class CardRules implements ICardCharacteristics {
|
||||
private CardSplitType splitType;
|
||||
private ICardFace mainPart;
|
||||
private ICardFace otherPart;
|
||||
private ICardFace wSpecialize;
|
||||
private ICardFace uSpecialize;
|
||||
private ICardFace bSpecialize;
|
||||
private ICardFace rSpecialize;
|
||||
private ICardFace gSpecialize;
|
||||
private CardAiHints aiHints;
|
||||
private ColorSet colorIdentity;
|
||||
private ColorSet deckbuildingColors;
|
||||
@@ -54,6 +59,12 @@ public final class CardRules implements ICardCharacteristics {
|
||||
splitType = altMode;
|
||||
mainPart = faces[0];
|
||||
otherPart = faces[1];
|
||||
wSpecialize = faces[2];
|
||||
uSpecialize = faces[3];
|
||||
bSpecialize = faces[4];
|
||||
rSpecialize = faces[5];
|
||||
gSpecialize = faces[6];
|
||||
|
||||
aiHints = cah;
|
||||
meldWith = "";
|
||||
partnerWith = "";
|
||||
@@ -74,6 +85,11 @@ public final class CardRules implements ICardCharacteristics {
|
||||
splitType = newRules.splitType;
|
||||
mainPart = newRules.mainPart;
|
||||
otherPart = newRules.otherPart;
|
||||
wSpecialize = newRules.wSpecialize;
|
||||
uSpecialize = newRules.uSpecialize;
|
||||
bSpecialize = newRules.bSpecialize;
|
||||
rSpecialize = newRules.rSpecialize;
|
||||
gSpecialize = newRules.gSpecialize;
|
||||
aiHints = newRules.aiHints;
|
||||
colorIdentity = newRules.colorIdentity;
|
||||
meldWith = newRules.meldWith;
|
||||
@@ -132,6 +148,22 @@ public final class CardRules implements ICardCharacteristics {
|
||||
return otherPart;
|
||||
}
|
||||
|
||||
public ICardFace getWSpecialize() {
|
||||
return wSpecialize;
|
||||
}
|
||||
public ICardFace getUSpecialize() {
|
||||
return uSpecialize;
|
||||
}
|
||||
public ICardFace getBSpecialize() {
|
||||
return bSpecialize;
|
||||
}
|
||||
public ICardFace getRSpecialize() {
|
||||
return rSpecialize;
|
||||
}
|
||||
public ICardFace getGSpecialize() {
|
||||
return gSpecialize;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
switch (splitType.getAggregationMethod()) {
|
||||
case COMBINE:
|
||||
@@ -335,7 +367,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
// Reads cardname.txt
|
||||
public static class Reader {
|
||||
// fields to build
|
||||
private CardFace[] faces = new CardFace[] { null, null };
|
||||
private CardFace[] faces = new CardFace[] { null, null, null, null, null, null, null };
|
||||
private int curFace = 0;
|
||||
private CardSplitType altMode = CardSplitType.None;
|
||||
private String meldWith = "";
|
||||
@@ -382,6 +414,11 @@ public final class CardRules implements ICardCharacteristics {
|
||||
CardAiHints cah = new CardAiHints(removedFromAIDecks, removedFromRandomDecks, removedFromNonCommanderDecks, hints, needs, has);
|
||||
faces[0].assignMissingFields();
|
||||
if (null != faces[1]) faces[1].assignMissingFields();
|
||||
if (null != faces[2]) faces[2].assignMissingFields();
|
||||
if (null != faces[3]) faces[3].assignMissingFields();
|
||||
if (null != faces[4]) faces[4].assignMissingFields();
|
||||
if (null != faces[5]) faces[5].assignMissingFields();
|
||||
if (null != faces[6]) faces[6].assignMissingFields();
|
||||
final CardRules result = new CardRules(faces, altMode, cah);
|
||||
|
||||
result.setNormalizedName(this.normalizedName);
|
||||
@@ -518,6 +555,18 @@ public final class CardRules implements ICardCharacteristics {
|
||||
case 'S':
|
||||
if ("S".equals(key)) {
|
||||
this.faces[this.curFace].addStaticAbility(value);
|
||||
} else if (key.startsWith("SPECIALIZE")) {
|
||||
if (value.equals("WHITE")) {
|
||||
this.curFace = 2;
|
||||
} else if (value.equals("BLUE")) {
|
||||
this.curFace = 3;
|
||||
} else if (value.equals("BLACK")) {
|
||||
this.curFace = 4;
|
||||
} else if (value.equals("RED")) {
|
||||
this.curFace = 5;
|
||||
} else if (value.equals("GREEN")) {
|
||||
this.curFace = 6;
|
||||
}
|
||||
} else if ("SVar".equals(key)) {
|
||||
if (null == value) throw new IllegalArgumentException("SVar has no variable name");
|
||||
|
||||
@@ -600,7 +649,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
|
||||
public static CardRules getUnsupportedCardNamed(String name) {
|
||||
CardAiHints cah = new CardAiHints(true, true, true, null, null, null);
|
||||
CardFace[] faces = { new CardFace(name), null};
|
||||
CardFace[] faces = { new CardFace(name), null, null, null, null, null, null};
|
||||
faces[0].setColor(ColorSet.fromMask(0));
|
||||
faces[0].setType(CardType.parse("", false));
|
||||
faces[0].setOracleText("This card is not supported by Forge. Whenever you start a game with this card, it will be bugged.");
|
||||
|
||||
@@ -10,7 +10,8 @@ public enum CardSplitType
|
||||
Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit),
|
||||
Flip(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Flipped),
|
||||
Adventure(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Adventure),
|
||||
Modal(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Modal);
|
||||
Modal(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Modal),
|
||||
Specialize(FaceSelectionMethod.USE_ACTIVE_FACE, null);
|
||||
|
||||
CardSplitType(FaceSelectionMethod calcMode, CardStateName stateName) {
|
||||
method = calcMode;
|
||||
|
||||
@@ -10,7 +10,12 @@ public enum CardStateName {
|
||||
LeftSplit,
|
||||
RightSplit,
|
||||
Adventure,
|
||||
Modal
|
||||
Modal,
|
||||
SpecializeW,
|
||||
SpecializeU,
|
||||
SpecializeB,
|
||||
SpecializeR,
|
||||
SpecializeG
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -16,20 +16,21 @@ import forge.util.lang.LangGerman;
|
||||
import forge.util.lang.LangItalian;
|
||||
import forge.util.lang.LangJapanese;
|
||||
import forge.util.lang.LangSpanish;
|
||||
import forge.util.lang.LangFrench;
|
||||
|
||||
/**
|
||||
* Static library containing language-related utility methods.
|
||||
*/
|
||||
public abstract class Lang {
|
||||
|
||||
private static Lang instance;
|
||||
private static Lang instance;
|
||||
private static Lang englishInstance;
|
||||
|
||||
protected String languageCode;
|
||||
protected String countryCode;
|
||||
|
||||
public static void createInstance(String localeID) {
|
||||
String[] splitLocale = localeID.split("-");
|
||||
String[] splitLocale = localeID.split("-");
|
||||
String language = splitLocale[0];
|
||||
String country = splitLocale[1];
|
||||
if (language.equals("de")) {
|
||||
@@ -42,6 +43,8 @@ public abstract class Lang {
|
||||
instance = new LangChinese();
|
||||
} else if (language.equals("ja")) {
|
||||
instance = new LangJapanese();
|
||||
} else if (language.equals("fr")) {
|
||||
instance = new LangFrench();
|
||||
} else { // default is English
|
||||
instance = new LangEnglish();
|
||||
}
|
||||
@@ -54,14 +57,14 @@ public abstract class Lang {
|
||||
englishInstance.countryCode = "US";
|
||||
}
|
||||
|
||||
public static Lang getInstance() {
|
||||
return instance;
|
||||
}
|
||||
public static Lang getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Lang getEnglishInstance() {
|
||||
return englishInstance;
|
||||
}
|
||||
|
||||
|
||||
protected Lang() {
|
||||
}
|
||||
|
||||
@@ -70,7 +73,7 @@ public abstract class Lang {
|
||||
* of a numbers, eg. "st" for 1 ("first") and "th" for 4 ("fourth").
|
||||
*
|
||||
* @param position
|
||||
* the number to get the ordinal suffix for.
|
||||
* the number to get the ordinal suffix for.
|
||||
* @return a string containing two characters.
|
||||
*/
|
||||
public abstract String getOrdinal(final int position);
|
||||
@@ -81,26 +84,32 @@ public abstract class Lang {
|
||||
return has1 ? (has2 ? s1 + " and " + s2 : s1) : (has2 ? s2 : "");
|
||||
}
|
||||
|
||||
public static <T> String joinHomogenous(final Iterable<T> objects) { return joinHomogenous(Lists.newArrayList(objects)); }
|
||||
public static <T> String joinHomogenous(final Collection<T> objects) { return joinHomogenous(objects, null, "and"); }
|
||||
public static <T> String joinHomogenous(final Iterable<T> objects) {
|
||||
return joinHomogenous(Lists.newArrayList(objects));
|
||||
}
|
||||
|
||||
public static <T> String joinHomogenous(final Collection<T> objects) {
|
||||
return joinHomogenous(objects, null, "and");
|
||||
}
|
||||
|
||||
public static <T> String joinHomogenous(final Collection<T> objects, final Function<T, String> accessor) {
|
||||
return joinHomogenous(objects, accessor, "and");
|
||||
}
|
||||
public static <T> String joinHomogenous(final Collection<T> objects, final Function<T, String> accessor, final String lastUnion) {
|
||||
|
||||
public static <T> String joinHomogenous(final Collection<T> objects, final Function<T, String> accessor,
|
||||
final String lastUnion) {
|
||||
int remaining = objects.size();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final T obj : objects) {
|
||||
remaining--;
|
||||
if (accessor != null) {
|
||||
sb.append(accessor.apply(obj));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sb.append(obj);
|
||||
}
|
||||
if (remaining > 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
else if (remaining == 1) {
|
||||
} else if (remaining == 1) {
|
||||
sb.append(" ").append(lastUnion).append(" ");
|
||||
}
|
||||
}
|
||||
@@ -108,7 +117,8 @@ public abstract class Lang {
|
||||
}
|
||||
|
||||
public static <T> String joinVerb(final List<T> subjects, final String verb) {
|
||||
return subjects.size() > 1 || !subjectIsSingle3rdPerson(Iterables.getFirst(subjects, "it").toString()) ? verb : verbs3rdPersonSingular(verb);
|
||||
return subjects.size() > 1 || !subjectIsSingle3rdPerson(Iterables.getFirst(subjects, "it").toString()) ? verb
|
||||
: verbs3rdPersonSingular(verb);
|
||||
}
|
||||
|
||||
public static String joinVerb(final String subject, final String verb) {
|
||||
@@ -126,7 +136,8 @@ public abstract class Lang {
|
||||
}
|
||||
|
||||
public static String getPlural(final String noun) {
|
||||
return noun + (noun.endsWith("s") && !noun.endsWith("ds") || noun.endsWith("x") || noun.endsWith("ch") ? "es" : noun.endsWith("ds") ? "" : "s");
|
||||
return noun + (noun.endsWith("s") && !noun.endsWith("ds") || noun.endsWith("x") || noun.endsWith("ch") ? "es"
|
||||
: noun.endsWith("ds") ? "" : "s");
|
||||
}
|
||||
|
||||
public static String nounWithAmount(final int cnt, final String noun) {
|
||||
@@ -170,6 +181,7 @@ public abstract class Lang {
|
||||
}
|
||||
|
||||
public abstract String getPossesive(final String name);
|
||||
|
||||
public abstract String getPossessedObject(final String owner, final String object);
|
||||
|
||||
public static boolean startsWithVowel(final String word) {
|
||||
@@ -177,14 +189,17 @@ public abstract class Lang {
|
||||
}
|
||||
|
||||
private static final Pattern VOWEL_PATTERN = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static boolean isVowel(final char letter) {
|
||||
return VOWEL_PATTERN.matcher(String.valueOf(letter)).find();
|
||||
}
|
||||
|
||||
public final static String[] numbers0 = new String[] {
|
||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eightteen", "nineteen" };
|
||||
public final static String[] numbers20 = new String[] {"twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
|
||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eightteen",
|
||||
"nineteen" };
|
||||
public final static String[] numbers20 = new String[] { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy",
|
||||
"eighty", "ninety" };
|
||||
|
||||
public static String getNumeral(int n) {
|
||||
final String prefix = n < 0 ? "minus " : "";
|
||||
|
||||
40
forge-core/src/main/java/forge/util/lang/LangFrench.java
Normal file
40
forge-core/src/main/java/forge/util/lang/LangFrench.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package forge.util.lang;
|
||||
|
||||
import forge.util.Lang;
|
||||
|
||||
public class LangFrench extends Lang {
|
||||
|
||||
@Override
|
||||
public String getOrdinal(final int position) {
|
||||
if (position == 1) {
|
||||
return position + "ᵉʳ";
|
||||
} else {
|
||||
return position + "ᵉ";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPossesive(final String name) {
|
||||
if ("Vous".equalsIgnoreCase(name)) {
|
||||
return name;
|
||||
}
|
||||
return "de " + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPossessedObject(final String owner, final String object) {
|
||||
if ("Vous".equalsIgnoreCase(owner)) {
|
||||
return getPossesive(owner) + " " + object;
|
||||
}
|
||||
return object + " " + getPossesive(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNickName(final String name) {
|
||||
if (name.contains(",")) {
|
||||
return name.split(",")[0];
|
||||
} else {
|
||||
return name.split(" ")[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,22 @@ public class ForgeScript {
|
||||
return source.hasChosenColor()
|
||||
&& colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor());
|
||||
|
||||
} else if (property.equals("AssociatedWithChosenColor")) {
|
||||
final String color = source.getChosenColor();
|
||||
switch (color) {
|
||||
case "white":
|
||||
return cardState.getTypeWithChanges().getLandTypes().contains("Plains");
|
||||
case "blue":
|
||||
return cardState.getTypeWithChanges().getLandTypes().contains("Island");
|
||||
case "black":
|
||||
return cardState.getTypeWithChanges().getLandTypes().contains("Swamp");
|
||||
case "red":
|
||||
return cardState.getTypeWithChanges().getLandTypes().contains("Mountain");
|
||||
case "green":
|
||||
return cardState.getTypeWithChanges().getLandTypes().contains("Forest");
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("non")) {
|
||||
// ... Other Card types
|
||||
return !cardState.getTypeWithChanges().hasStringType(property.substring(3));
|
||||
@@ -100,6 +116,15 @@ public class ForgeScript {
|
||||
return cardState.getTypeWithChanges().hasStringType(source.getChosenType2());
|
||||
} else if (property.equals("IsNotChosenType2")) {
|
||||
return !cardState.getTypeWithChanges().hasStringType(source.getChosenType2());
|
||||
} else if (property.equals("NotedType")) {
|
||||
boolean found = false;
|
||||
for (String s : source.getNotedTypes()) {
|
||||
if (cardState.getTypeWithChanges().hasStringType(s)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
} else if (property.startsWith("HasSubtype")) {
|
||||
final String subType = property.substring(11);
|
||||
return cardState.getTypeWithChanges().hasSubtype(subType);
|
||||
@@ -160,6 +185,10 @@ public class ForgeScript {
|
||||
return !sa.isManaAbility();
|
||||
} else if (property.equals("withoutXCost")) {
|
||||
return !sa.costHasManaX();
|
||||
} else if (property.startsWith("XCost")) {
|
||||
String comparator = property.substring(5, 7);
|
||||
int y = AbilityUtils.calculateAmount(sa.getHostCard(), property.substring(7), sa);
|
||||
return Expressions.compare(sa.getXManaCostPaid(), comparator, y);
|
||||
} else if (property.equals("hasTapCost")) {
|
||||
Cost cost = sa.getPayCosts();
|
||||
return cost != null && cost.hasTapCost();
|
||||
@@ -207,6 +236,8 @@ public class ForgeScript {
|
||||
return sa.hasParam("Nightbound");
|
||||
} else if (property.equals("paidPhyrexianMana")) {
|
||||
return sa.getSpendPhyrexianMana();
|
||||
} else if (property.equals("LastChapter")) {
|
||||
return sa.isLastChapter();
|
||||
} else if (property.startsWith("ManaSpent")) {
|
||||
String[] k = property.split(" ", 2);
|
||||
String comparator = k[1].substring(0, 2);
|
||||
|
||||
@@ -887,8 +887,7 @@ public class Game {
|
||||
ingamePlayers.remove(p);
|
||||
lostPlayers.add(p);
|
||||
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, p);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(p);
|
||||
getTriggerHandler().runTrigger(TriggerType.LosesGame, runParams, false);
|
||||
}
|
||||
|
||||
@@ -1202,8 +1201,7 @@ public class Game {
|
||||
|
||||
// If an effect allows or instructs a player to reveal the card as it’s being drawn,
|
||||
// it’s revealed after the spell becomes cast or the ability becomes activated.
|
||||
final Map<AbilityKey, Object> runParams = Maps.newHashMap();
|
||||
runParams.put(AbilityKey.Card, c);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(c);
|
||||
runParams.put(AbilityKey.Number, facedownWhileCasting.get(c));
|
||||
runParams.put(AbilityKey.Player, this);
|
||||
runParams.put(AbilityKey.CanReveal, true);
|
||||
|
||||
@@ -608,6 +608,10 @@ public class GameAction {
|
||||
if (c.hasIntensity()) {
|
||||
copied.setIntensity(c.getIntensity(false));
|
||||
}
|
||||
// specialize is perpetual
|
||||
if (c.isSpecialized()) {
|
||||
copied.setState(c.getCurrentStateName(), false);
|
||||
}
|
||||
|
||||
// update state for view
|
||||
copied.updateStateForView();
|
||||
@@ -688,7 +692,7 @@ public class GameAction {
|
||||
}
|
||||
|
||||
if (fromBattlefield) {
|
||||
if (!c.isRealToken()) {
|
||||
if (!c.isRealToken() && !c.isSpecialized()) {
|
||||
copied.setState(CardStateName.Original, true);
|
||||
}
|
||||
// Soulbond unpairing
|
||||
@@ -848,11 +852,7 @@ public class GameAction {
|
||||
|
||||
if (zoneTo.is(ZoneType.Stack)) {
|
||||
// zoneFrom maybe null if the spell is cast from "Ouside the game", ex. ability of Garth One-Eye
|
||||
if (zoneFrom == null) {
|
||||
c.setCastFrom(null);
|
||||
} else {
|
||||
c.setCastFrom(zoneFrom);
|
||||
}
|
||||
c.setCastFrom(zoneFrom);
|
||||
if (cause != null && cause.isSpell() && c.equals(cause.getHostCard())) {
|
||||
c.setCastSA(cause);
|
||||
} else {
|
||||
@@ -1845,7 +1845,6 @@ public class GameAction {
|
||||
}
|
||||
|
||||
public final boolean destroy(final Card c, final SpellAbility sa, final boolean regenerate, CardZoneTable table, Map<AbilityKey, Object> params) {
|
||||
Player activator = null;
|
||||
if (!c.canBeDestroyed()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1862,6 +1861,7 @@ public class GameAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player activator = null;
|
||||
if (sa != null) {
|
||||
activator = sa.getActivatingPlayer();
|
||||
}
|
||||
@@ -2238,8 +2238,7 @@ public class GameAction {
|
||||
game.setMonarch(p);
|
||||
|
||||
// Run triggers
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, p);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(p);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.BecomeMonarch, runParams, false);
|
||||
}
|
||||
|
||||
@@ -2264,8 +2263,7 @@ public class GameAction {
|
||||
|
||||
// You can take the initiative even if you already have it
|
||||
// Run triggers
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, p);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(p);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.TakesInitiative, runParams, false);
|
||||
}
|
||||
|
||||
@@ -2354,8 +2352,7 @@ public class GameAction {
|
||||
|
||||
if (cause != null) {
|
||||
// set up triggers (but not actually do them until later)
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, p);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(p);
|
||||
runParams.put(AbilityKey.ScryNum, numLookedAt);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.Scry, runParams, false);
|
||||
}
|
||||
@@ -2415,7 +2412,7 @@ public class GameAction {
|
||||
}
|
||||
|
||||
// for Zangief do this before runWaitingTriggers DamageDone
|
||||
damageMap.triggerExcessDamage(isCombat, lethalDamage, game);
|
||||
damageMap.triggerExcessDamage(isCombat, lethalDamage, game, lkiCache);
|
||||
|
||||
// lose life simultaneously
|
||||
if (isCombat) {
|
||||
|
||||
@@ -580,11 +580,9 @@ public final class GameActionUtil {
|
||||
if (tr != null) {
|
||||
String n = o.split(":")[1];
|
||||
if (host.wasCast() && n.equals("X")) {
|
||||
CardCollectionView creatures = CardLists.filter(CardLists.filterControlledBy(game.getCardsIn
|
||||
(ZoneType.Battlefield), activator), CardPredicates.Presets.CREATURES);
|
||||
CardCollectionView creatures = activator.getCreaturesInPlay();
|
||||
int max = Aggregates.max(creatures, CardPredicates.Accessors.fnGetNetPower);
|
||||
int min = Aggregates.min(creatures, CardPredicates.Accessors.fnGetNetPower);
|
||||
n = Integer.toString(pc.chooseNumber(sa, "Choose X for Casualty", min, max));
|
||||
n = Integer.toString(pc.chooseNumber(sa, "Choose X for Casualty", 0, max));
|
||||
}
|
||||
final String casualtyCost = "Sac<1/Creature.powerGE" + n + "/creature with power " + n +
|
||||
" or greater>";
|
||||
@@ -592,6 +590,8 @@ public final class GameActionUtil {
|
||||
String str = "Pay for Casualty? " + cost.toSimpleString();
|
||||
boolean v = pc.addKeywordCost(sa, cost, ki, str);
|
||||
|
||||
tr.setSVar("CasualtyPaid", v ? "1" : "0");
|
||||
tr.getOverridingAbility().setSVar("CasualtyPaid", v ? "1" : "0");
|
||||
tr.setSVar("Casualty", v ? n : "0");
|
||||
tr.getOverridingAbility().setSVar("Casualty", v ? n : "0");
|
||||
|
||||
@@ -607,7 +607,7 @@ public final class GameActionUtil {
|
||||
Trigger tr = Iterables.getFirst(ki.getTriggers(), null);
|
||||
if (tr != null) {
|
||||
final String conspireCost = "tapXType<2/Creature.SharesColorWith/" +
|
||||
"untapped creature you control that shares a color with " + host.getName() + ">";
|
||||
"creature that shares a color with " + host.getName() + ">";
|
||||
final Cost cost = new Cost(conspireCost, false);
|
||||
String str = "Pay for Conspire? " + cost.toSimpleString();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
@@ -330,9 +331,9 @@ public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
subtractCounter(CounterType.get(counterName), n);
|
||||
}
|
||||
|
||||
abstract public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table);
|
||||
public void addCounterInternal(final CounterEnumType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) {
|
||||
addCounterInternal(CounterType.get(counterType), n, source, fireEvents, table);
|
||||
abstract public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params);
|
||||
public void addCounterInternal(final CounterEnumType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||
addCounterInternal(CounterType.get(counterType), n, source, fireEvents, table, params);
|
||||
}
|
||||
|
||||
public void receiveDamage(Pair<Integer, Boolean> dmg) {
|
||||
|
||||
@@ -155,11 +155,18 @@ public class GameEntityCounterTable extends ForwardingTable<Optional<Player>, Ga
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add ETB flag
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.ETB, etb);
|
||||
if (params != null) {
|
||||
runParams.putAll(params);
|
||||
}
|
||||
|
||||
// Apply counter after replacement effect
|
||||
for (Map.Entry<Optional<Player>, Map<CounterType, Integer>> e : values.entrySet()) {
|
||||
boolean remember = cause != null && cause.hasParam("RememberPut");
|
||||
for (Map.Entry<CounterType, Integer> ec : e.getValue().entrySet()) {
|
||||
gm.getKey().addCounterInternal(ec.getKey(), ec.getValue(), e.getKey().orNull(), true, result);
|
||||
gm.getKey().addCounterInternal(ec.getKey(), ec.getValue(), e.getKey().orNull(), true, result, runParams);
|
||||
if (remember && ec.getValue() >= 1) {
|
||||
cause.getHostCard().addRemembered(gm.getKey());
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ public class GameRules {
|
||||
// same for me
|
||||
private boolean useGrayText;
|
||||
|
||||
// whether to warn about cards AI can't play well
|
||||
private boolean warnAboutAICards = true;
|
||||
|
||||
public GameRules(final GameType type) {
|
||||
this.gameType = type;
|
||||
}
|
||||
@@ -109,4 +112,11 @@ public class GameRules {
|
||||
public void setUseGrayText(final boolean useGrayText) {
|
||||
this.useGrayText = useGrayText;
|
||||
}
|
||||
|
||||
public boolean warnAboutAICards() {
|
||||
return warnAboutAICards;
|
||||
}
|
||||
public void setWarnAboutAICards(final boolean warnAboutAICards) {
|
||||
this.warnAboutAICards = warnAboutAICards;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ public class Match {
|
||||
}
|
||||
|
||||
final Localizer localizer = Localizer.getInstance();
|
||||
if (!rAICards.isEmpty() && !rules.getGameType().isCardPoolLimited()) {
|
||||
if (!rAICards.isEmpty() && !rules.getGameType().isCardPoolLimited() && rules.warnAboutAICards()) {
|
||||
game.getAction().revealUnplayableByAI(localizer.getMessage("lblAICantPlayCards"), rAICards);
|
||||
}
|
||||
|
||||
|
||||
@@ -2737,10 +2737,10 @@ public class AbilityUtils {
|
||||
SpellAbility sa = (SpellAbility) ctb;
|
||||
if (sa.isReplacementAbility()) {
|
||||
if (zones.get(0).equals(ZoneType.Battlefield)) {
|
||||
cardsInZones = sa.getLastStateBattlefield();
|
||||
cardsInZones = sa.getRootAbility().getLastStateBattlefield();
|
||||
usedLastState = true;
|
||||
} else if (zones.get(0).equals(ZoneType.Graveyard)) {
|
||||
cardsInZones = sa.getLastStateGraveyard();
|
||||
cardsInZones = sa.getRootAbility().getLastStateGraveyard();
|
||||
usedLastState = true;
|
||||
}
|
||||
}
|
||||
@@ -2827,11 +2827,6 @@ public class AbilityUtils {
|
||||
CardCollection filteredCards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restrictions[1], player, c, ctb);
|
||||
return doXMath(Aggregates.sum(filteredCards, CardPredicates.Accessors.fnGetNetPower), expr, c, ctb);
|
||||
}
|
||||
if (sq[0].startsWith("HighestCMC_")) {
|
||||
final String restriction = l[0].substring(11);
|
||||
CardCollection list = CardLists.getValidCards(game.getCardsInGame(), restriction, player, c, ctb);
|
||||
return Aggregates.max(list, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
if (sq[0].startsWith("DifferentPower_")) {
|
||||
final String restriction = l[0].substring(15);
|
||||
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), restriction, player, c, ctb);
|
||||
@@ -3565,7 +3560,7 @@ public class AbilityUtils {
|
||||
* @return a int.
|
||||
*/
|
||||
public static int handlePaid(final Iterable<Card> paidList, final String string, final Card source, CardTraitBase ctb) {
|
||||
if (paidList == null) {
|
||||
if (Iterables.isEmpty(paidList)) {
|
||||
if (string.contains(".")) {
|
||||
final String[] splitString = string.split("\\.", 2);
|
||||
return doXMath(0, splitString[1], source, ctb);
|
||||
@@ -3594,6 +3589,10 @@ public class AbilityUtils {
|
||||
return Aggregates.sum(paidList, CardPredicates.Accessors.fnGetNetToughness);
|
||||
}
|
||||
|
||||
if (string.startsWith("GreatestCMC")) {
|
||||
return Aggregates.max(paidList, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
|
||||
if (string.startsWith("DifferentCMC")) {
|
||||
final Set<Integer> diffCMC = new HashSet<>();
|
||||
for (final Card card : paidList) {
|
||||
@@ -3728,7 +3727,7 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// Count$InTargetedLibrary (targeted player's cards in hand)
|
||||
// Count$InTargetedLibrary (targeted player's cards in library)
|
||||
if (sq[0].contains("InTargetedLibrary")) {
|
||||
for (Player tgtP : getDefinedPlayers(c, "TargetedPlayer", ctb)) {
|
||||
someCards.addAll(tgtP.getCardsIn(ZoneType.Library));
|
||||
|
||||
@@ -331,9 +331,24 @@ public abstract class SpellAbilityEffect {
|
||||
}
|
||||
|
||||
protected static void addSelfTrigger(final SpellAbility sa, String location, final Card card) {
|
||||
String player = "";
|
||||
String whose = " the ";
|
||||
if (location.contains("_")) {
|
||||
String[] locSplit = location.split("_");
|
||||
player = locSplit[0];
|
||||
location = locSplit[1];
|
||||
if (player.equals("You")) {
|
||||
whose = " your next ";
|
||||
}
|
||||
}
|
||||
|
||||
String trigStr = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield " +
|
||||
"| TriggerDescription$ At the beginning of the end step, " + location.toLowerCase() + " CARDNAME.";
|
||||
|
||||
"| TriggerDescription$ At the beginning of" + whose + "end step, " + location.toLowerCase()
|
||||
+ " CARDNAME.";
|
||||
if (!player.equals("")) {
|
||||
trigStr += " | Player$ " + player;
|
||||
}
|
||||
|
||||
final Trigger trig = TriggerHandler.parseTrigger(trigStr, card, true);
|
||||
|
||||
String trigSA = "";
|
||||
@@ -462,6 +477,8 @@ public abstract class SpellAbilityEffect {
|
||||
eff.setEmblem(true);
|
||||
// Emblem needs to be colorless
|
||||
eff.setColor(MagicColor.COLORLESS);
|
||||
} else if (sa.hasParam("Boon")) {
|
||||
eff.setBoon(true);
|
||||
}
|
||||
|
||||
eff.setOwner(controller);
|
||||
@@ -516,6 +533,9 @@ public abstract class SpellAbilityEffect {
|
||||
"| Origin$ Battlefield | Destination$ Graveyard " +
|
||||
"| Description$ If that permanent would die this turn, exile it instead.";
|
||||
String effect = "DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Battlefield | Destination$ " + zone;
|
||||
if (sa.hasParam("ReplaceDyingRemember")) {
|
||||
effect += " | RememberToEffectSource$ True";
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true);
|
||||
re.setLayer(ReplacementLayer.Other);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
if (sa.hasParam("Toughness")) {
|
||||
toughness = AbilityUtils.calculateAmount(host, sa.getParam("Toughness"), sa);
|
||||
}
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
final Game game = host.getGame();
|
||||
|
||||
// Every Animate event needs a unique time stamp
|
||||
final long timestamp = game.getNextTimestamp();
|
||||
@@ -142,7 +142,7 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
list = getTargetPlayers(sa).getCardsIn(ZoneType.Battlefield);
|
||||
}
|
||||
|
||||
list = CardLists.getValidCards(list, valid, host.getController(), host, sa);
|
||||
list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), host, sa);
|
||||
|
||||
for (final Card c : list) {
|
||||
doAnimate(c, sa, power, toughness, types, removeTypes, finalColors, keywords, removeKeywords,
|
||||
@@ -170,6 +170,6 @@ public class AnimateAllEffect extends AnimateEffectBase {
|
||||
addUntilCommand(sa, unanimate);
|
||||
}
|
||||
}
|
||||
} // animateAllResolve
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -789,6 +788,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("RememberToEffectSource")) {
|
||||
if (hostCard.isImmutable() && hostCard.getEffectSource() != null) {
|
||||
hostCard.getEffectSource().addRemembered(movedCard);
|
||||
}
|
||||
}
|
||||
if (remember != null) {
|
||||
hostCard.addRemembered(movedCard);
|
||||
// addRememberedFromCardState ?
|
||||
@@ -1143,16 +1147,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
fetchList = CardLists.filter(fetchList, Predicates.not(CardPredicates.sharesCMCWith(c)));
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("DifferentPower")) {
|
||||
for (Card c : chosenCards) {
|
||||
fetchList = CardLists.filter(fetchList, Predicates.not(Predicates.compose(Predicates.equalTo(c.getNetPower()), CardPredicates.Accessors.fnGetNetPower)));
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("ShareLandType")) {
|
||||
// After the first card is chosen, check if the land type is shared
|
||||
for (final Card card : chosenCards) {
|
||||
fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.sharesLandTypeWith(card);
|
||||
}
|
||||
|
||||
});
|
||||
for (final Card c : chosenCards) {
|
||||
fetchList = CardLists.filter(fetchList, CardPredicates.sharesLandTypeWith(c));
|
||||
}
|
||||
}
|
||||
if (totalcmc != null) {
|
||||
@@ -1494,6 +1497,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
&& !sa.hasParam("Mandatory") // only handle optional decisions, for now
|
||||
&& !sa.hasParam("ShareLandType")
|
||||
&& !sa.hasParam("DifferentNames")
|
||||
&& !sa.hasParam("DifferentPower")
|
||||
&& !sa.hasParam("DifferentCMC")
|
||||
&& !sa.hasParam("AtRandom")
|
||||
&& (!sa.hasParam("Defined") || sa.hasParam("ChooseFromDefined"))
|
||||
|
||||
@@ -9,9 +9,12 @@ import forge.card.CardType;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
@@ -58,6 +61,15 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sa.hasParam("MostPrevalentInDefinedZone")) {
|
||||
final String[] info = sa.getParam("MostPrevalentInDefinedZone").split("_");
|
||||
final Player definedP = AbilityUtils.getDefinedPlayers(sa.getHostCard(), info[0], sa).get(0);
|
||||
final ZoneType z = info.length > 1 ? ZoneType.smartValueOf(info[1]) : ZoneType.Battlefield;
|
||||
CardCollectionView zoneCards = definedP.getCardsIn(z);
|
||||
for (String s : CardFactoryUtil.getMostProminentCreatureType(zoneCards)) {
|
||||
validTypes.add(s);
|
||||
}
|
||||
|
||||
} else {
|
||||
validTypes.addAll(CardType.getAllCreatureTypes());
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
CardCollectionView cards = game.getCardsIn(zone);
|
||||
cards = CardLists.getValidCards(cards, valid, host.getController(), host, sa);
|
||||
cards = CardLists.getValidCards(cards, valid, activator, host, sa);
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
final Player pl = sa.getTargets().getFirstTargetedPlayer();
|
||||
@@ -80,7 +80,7 @@ public class CountersPutAllEffect extends SpellAbilityEffect {
|
||||
ZoneType.smartValueOf(sa.getParam("ValidZone2")) : zone;
|
||||
if (sa.hasParam("ValidCards2")) {
|
||||
cards = CardLists.getValidCards(game.getCardsIn(zone2), sa.getParam("ValidCards2"),
|
||||
host.getController(), host, sa);
|
||||
activator, host, sa);
|
||||
if (sa.usesTargeting()) {
|
||||
cards = CardLists.filterControlledBy(cards, sa.getTargets().getFirstTargetedPlayer());
|
||||
}
|
||||
|
||||
@@ -450,11 +450,12 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
0);
|
||||
}
|
||||
if (sa.hasParam("UpTo")) {
|
||||
int min = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("UpToMin", "0"), sa);
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Target", obj);
|
||||
params.put("CounterType", counterType);
|
||||
counterAmount = pc.chooseNumber(sa,
|
||||
Localizer.getInstance().getMessage("lblHowManyCounters"), 0, counterAmount, params);
|
||||
Localizer.getInstance().getMessage("lblHowManyCounters"), min, counterAmount, params);
|
||||
}
|
||||
if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
@@ -479,6 +480,10 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("ReadAhead")) {
|
||||
gameCard.setReadAhead(counterAmount);
|
||||
}
|
||||
|
||||
if (sa.hasParam("Tribute")) {
|
||||
// make a copy to check if it would be on the battlefield
|
||||
Card noTributeLKI = CardUtil.getLKICopy(gameCard);
|
||||
@@ -608,8 +613,7 @@ public class CountersPutEffect extends SpellAbilityEffect {
|
||||
&& !sa.hasParam("CounterTypes") && !sa.hasParam("ChooseDifferent")
|
||||
&& !sa.hasParam("PutOnEachOther") && !sa.hasParam("PutOnDefined")) {
|
||||
try {
|
||||
counterType = chooseTypeFromList(sa, sa.getParam("CounterType"), null,
|
||||
placer.getController());
|
||||
counterType = chooseTypeFromList(sa, sa.getParam("CounterType"), null, placer.getController());
|
||||
} catch (Exception e) {
|
||||
System.out.println("Counter type doesn't match, nor does an SVar exist with the type name.");
|
||||
return;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class CountersRemoveAllEffect extends SpellAbilityEffect {
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
|
||||
CardCollectionView cards = game.getCardsIn(zone);
|
||||
cards = CardLists.getValidCards(cards, valid, sa.getHostCard().getController(), sa.getHostCard(), sa);
|
||||
cards = CardLists.getValidCards(cards, valid, sa.getActivatingPlayer(), sa.getHostCard(), sa);
|
||||
|
||||
if (sa.usesTargeting()) {
|
||||
final Player pl = sa.getTargets().getFirstTargetedPlayer();
|
||||
|
||||
@@ -83,7 +83,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
|
||||
|
||||
if (sa.hasParam("Optional")) {
|
||||
String ctrs = cntToRemove > 1 ? Localizer.getInstance().getMessage("lblCounters") : num.equals("All") ? Localizer.getInstance().getMessage("lblAllCounters") : Localizer.getInstance().getMessage("lblACounters");
|
||||
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblRemove") + " " + ctrs + "?", null)) {
|
||||
if (!pc.confirmAction(sa, null, Localizer.getInstance().getMessage("lblRemove") + " " + ctrs + "?", null)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class CountersRemoveEffect extends SpellAbilityEffect {
|
||||
if (num.equals("Any")) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("CounterType", counterType);
|
||||
srcCards = player.getController().chooseCardsForEffect(srcCards, sa, title, 0, srcCards.size(), true, params);
|
||||
srcCards = pc.chooseCardsForEffect(srcCards, sa, title, 0, srcCards.size(), true, params);
|
||||
}
|
||||
} else if (sa.hasParam("Choices") && counterType != null) {
|
||||
ZoneType choiceZone = sa.hasParam("ChoiceZone") ? ZoneType.smartValueOf(sa.getParam("ChoiceZone"))
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DamageEachEffect extends DamageBaseEffect {
|
||||
|
||||
FCollectionView<Card> sources = game.getCardsIn(ZoneType.Battlefield);
|
||||
if (sa.hasParam("ValidCards")) {
|
||||
sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), card.getController(), card, sa);
|
||||
sources = CardLists.getValidCards(sources, sa.getParam("ValidCards"), sa.getActivatingPlayer(), card, sa);
|
||||
}
|
||||
|
||||
final List<GameObject> tgts = getTargets(sa, "DefinedPlayers");
|
||||
@@ -121,7 +121,7 @@ public class DamageEachEffect extends DamageBaseEffect {
|
||||
final int dmg = AbilityUtils.calculateAmount(source, "X", sa);
|
||||
final Card sourceLKI = source.getGame().getChangeZoneLKIInfo(source);
|
||||
|
||||
for (final Object o : sa.getHostCard().getRemembered()) {
|
||||
for (final Object o : card.getRemembered()) {
|
||||
if (o instanceof Card) {
|
||||
Card rememberedcard = (Card) o;
|
||||
damageMap.put(sourceLKI, rememberedcard, dmg);
|
||||
|
||||
@@ -122,7 +122,7 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
|
||||
String name = sa.getParam("Name");
|
||||
if (name == null) {
|
||||
name = hostCard.getName() + "'s Effect";
|
||||
name = hostCard.getName() + (sa.hasParam("Boon") ? "'s Boon" : "'s Effect");
|
||||
}
|
||||
|
||||
// Unique Effects shouldn't be duplicated
|
||||
@@ -226,6 +226,8 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
if (!"Stack".equals(sa.getParam("ForgetOnMoved"))) {
|
||||
addForgetOnCastTrigger(eff);
|
||||
}
|
||||
} else if (sa.hasParam("ForgetOnCast")) {
|
||||
addForgetOnCastTrigger(eff);
|
||||
} else if (sa.hasParam("ExileOnMoved")) {
|
||||
addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved"));
|
||||
}
|
||||
@@ -277,6 +279,14 @@ public class EffectEffect extends SpellAbilityEffect {
|
||||
eff.setNamedCard(hostCard.getNamedCard());
|
||||
}
|
||||
|
||||
// chosen number
|
||||
if (sa.hasParam("SetChosenNumber")) {
|
||||
eff.setChosenNumber(AbilityUtils.calculateAmount(sa.getHostCard(),
|
||||
sa.getParam("SetChosenNumber"), sa));
|
||||
} else if (hostCard.hasChosenNumber()) {
|
||||
eff.setChosenNumber(hostCard.getChosenNumber());
|
||||
}
|
||||
|
||||
if (sa.hasParam("CopySVar")) {
|
||||
eff.setSVar(sa.getParam("CopySVar"), hostCard.getSVar(sa.getParam("CopySVar")));
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ public class LifeSetEffect extends SpellAbilityEffect {
|
||||
for (final Player p : players.threadSafeIterable()) {
|
||||
if (tgt == null || p.canBeTargetedBy(sa)) {
|
||||
if (!redistribute) {
|
||||
p.setLife(lifeAmount, sa.getHostCard());
|
||||
p.setLife(lifeAmount, sa);
|
||||
} else {
|
||||
List<Integer> validChoices = getDistribution(players, true, lifetotals);
|
||||
int life = sa.getActivatingPlayer().getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblLifeTotal") + ": " + p, validChoices, p);
|
||||
p.setLife(life, sa.getHostCard());
|
||||
p.setLife(life, sa);
|
||||
lifetotals.remove((Integer) life);
|
||||
players.remove(p);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.StaticData;
|
||||
import forge.card.ICardFace;
|
||||
import forge.game.Game;
|
||||
@@ -17,6 +18,7 @@ import forge.game.card.CardZoneTable;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerCollection;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.CardTranslation;
|
||||
@@ -34,18 +36,25 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
||||
for (final Player player : players) {
|
||||
final Game game = player.getGame();
|
||||
|
||||
String name = sa.getParamOrDefault("Name", "");
|
||||
if (name.equals("ChosenName")) {
|
||||
if (sa.getHostCard().hasChosenName()) {
|
||||
name = sa.getHostCard().getChosenName();
|
||||
List<String> names = Lists.newArrayList();
|
||||
if (sa.hasParam("Name")) {
|
||||
final String n = sa.getParam("Name");
|
||||
if (n.equals("ChosenName")) {
|
||||
if (source.hasChosenName()) {
|
||||
names.add(source.getChosenName());
|
||||
} else {
|
||||
System.err.println("Malformed MakeCard entry! - " + source.toString());
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
names.add(n);
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("DefinedName")) {
|
||||
final CardCollection def = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedName"), sa);
|
||||
if (def.size() > 0) {
|
||||
name = def.getFirst().getName();
|
||||
for (final Card c : def) {
|
||||
names.add(c.getName());
|
||||
}
|
||||
}
|
||||
} else if (sa.hasParam("Spellbook")) {
|
||||
List<String> spellbook = Arrays.asList(sa.getParam("Spellbook").split(","));
|
||||
@@ -56,43 +65,61 @@ public class MakeCardEffect extends SpellAbilityEffect {
|
||||
faces.add(StaticData.instance().getCommonCards().getFaceByName(s));
|
||||
}
|
||||
if (sa.hasParam("AtRandom")) {
|
||||
name = Aggregates.random(faces).getName();
|
||||
names.add(Aggregates.random(faces).getName());
|
||||
} else {
|
||||
name = player.getController().chooseCardName(sa, faces,
|
||||
Localizer.getInstance().getMessage("lblChooseFromSpellbook", CardTranslation.getTranslatedName(source.getName())));
|
||||
names.add(player.getController().chooseCardName(sa, faces,
|
||||
Localizer.getInstance().getMessage("lblChooseFromSpellbook",
|
||||
CardTranslation.getTranslatedName(source.getName()))));
|
||||
}
|
||||
}
|
||||
final ZoneType zone = ZoneType.smartValueOf(sa.getParamOrDefault("Zone", "Library"));
|
||||
int amount = sa.hasParam("Amount") ?
|
||||
AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa) : 1;
|
||||
final int amount = sa.hasParam("Amount") ?
|
||||
AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa) : 1;
|
||||
|
||||
CardCollection cards = new CardCollection();
|
||||
|
||||
if (!name.equals("")) {
|
||||
while (amount > 0) {
|
||||
Card card = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name), player);
|
||||
card.setTokenCard(true);
|
||||
game.getAction().moveTo(ZoneType.None, card, sa, moveParams);
|
||||
cards.add(card);
|
||||
amount--;
|
||||
for (final String name : names) {
|
||||
int toMake = amount;
|
||||
if (!name.equals("")) {
|
||||
while (toMake > 0) {
|
||||
Card card = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name),
|
||||
player);
|
||||
if (sa.hasParam("TokenCard")) {
|
||||
card.setTokenCard(true);
|
||||
}
|
||||
game.getAction().moveTo(ZoneType.None, card, sa, moveParams);
|
||||
cards.add(card);
|
||||
toMake--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final CardZoneTable triggerList = new CardZoneTable();
|
||||
for (final Card c : cards) {
|
||||
Card made = game.getAction().moveTo(zone, c, sa, moveParams);
|
||||
triggerList.put(ZoneType.None, made.getZone().getZoneType(), made);
|
||||
if (sa.hasParam("RememberMade")) {
|
||||
sa.getHostCard().addRemembered(made);
|
||||
}
|
||||
if (sa.hasParam("ImprintMade")) {
|
||||
sa.getHostCard().addImprintedCard(made);
|
||||
}
|
||||
final CardZoneTable triggerList = new CardZoneTable();
|
||||
CardCollection madeCards = new CardCollection();
|
||||
for (final Card c : cards) {
|
||||
Card made = game.getAction().moveTo(zone, c, sa, moveParams);
|
||||
triggerList.put(ZoneType.None, made.getZone().getZoneType(), made);
|
||||
madeCards.add(made);
|
||||
if (sa.hasParam("RememberMade")) {
|
||||
source.addRemembered(made);
|
||||
}
|
||||
triggerList.triggerChangesZoneAll(game, sa);
|
||||
if (zone.equals(ZoneType.Library)) {
|
||||
player.shuffle(sa);
|
||||
if (sa.hasParam("ImprintMade")) {
|
||||
source.addImprintedCard(made);
|
||||
}
|
||||
}
|
||||
triggerList.triggerChangesZoneAll(game, sa);
|
||||
|
||||
if (sa.hasParam("Conjure")) {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, player);
|
||||
runParams.put(AbilityKey.Cards, madeCards);
|
||||
runParams.put(AbilityKey.Cause, sa); //-- currently not needed
|
||||
game.getTriggerHandler().runTrigger(TriggerType.ConjureAll, runParams, false);
|
||||
}
|
||||
|
||||
if (zone.equals(ZoneType.Library)) {
|
||||
player.shuffle(sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
final boolean imprint = sa.hasParam("ImprintPlayed");
|
||||
final boolean forget = sa.hasParam("ForgetPlayed");
|
||||
final boolean hasTotalCMCLimit = sa.hasParam("WithTotalCMC");
|
||||
int amount = 1;
|
||||
int totalCMCLimit = Integer.MAX_VALUE;
|
||||
int amount = 1;
|
||||
if (sa.hasParam("Amount") && !sa.getParam("Amount").equals("All")) {
|
||||
amount = AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ import forge.card.CardStateName;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntityCounterTable;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.*;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Lang;
|
||||
@@ -17,19 +20,28 @@ import forge.util.Localizer;
|
||||
import forge.util.TextUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SetStateEffect extends SpellAbilityEffect {
|
||||
|
||||
@Override
|
||||
protected String getStackDescription(final SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean specialize = sa.getParam("Mode").equals("Specialize");
|
||||
|
||||
if (sa.hasParam("Flip")) {
|
||||
sb.append("Flip ");
|
||||
} else if (specialize) { // verb will come later
|
||||
} else {
|
||||
sb.append("Transform ");
|
||||
}
|
||||
|
||||
sb.append(Lang.joinHomogenous(getTargetCards(sa)));
|
||||
if (specialize) {
|
||||
sb.append(" perpetually specializes into ");
|
||||
sb.append(host.hasChosenColor() ? host.getChosenColor() : "the chosen color");
|
||||
}
|
||||
sb.append(".");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -87,7 +99,9 @@ public class SetStateEffect extends SpellAbilityEffect {
|
||||
|
||||
// Cards which are not on the battlefield should not be able to transform.
|
||||
// TurnFace should be allowed in other zones like Exile too
|
||||
if (!"TurnFace".equals(mode) && !gameCard.isInPlay() && !sa.hasParam("ETB")) {
|
||||
// Specialize and Unspecialize are allowed in other zones
|
||||
if (!"TurnFace".equals(mode) && !"Unspecialize".equals(mode) && !"Specialize".equals(mode)
|
||||
&& !gameCard.isInPlay() && !sa.hasParam("ETB")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -160,6 +174,9 @@ public class SetStateEffect extends SpellAbilityEffect {
|
||||
hasTransformed = gameCard.turnFaceUp(sa);
|
||||
} else if (sa.isManifestUp()) {
|
||||
hasTransformed = gameCard.turnFaceUp(true, true, sa);
|
||||
} else if ("Specialize".equals(mode)) {
|
||||
hasTransformed = gameCard.changeCardState(mode, host.getChosenColor(), sa);
|
||||
host.setChosenColors(null);
|
||||
} else {
|
||||
hasTransformed = gameCard.changeCardState(mode, sa.getParam("NewState"), sa);
|
||||
if (gameCard.isFaceDown() && (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness")
|
||||
@@ -193,6 +210,17 @@ public class SetStateEffect extends SpellAbilityEffect {
|
||||
}
|
||||
if (!gameCard.isDoubleFaced())
|
||||
transformedCards.add(gameCard);
|
||||
if ("Specialize".equals(mode)) {
|
||||
gameCard.setSpecialized(true);
|
||||
//run Specializes trigger
|
||||
final TriggerHandler th = game.getTriggerHandler();
|
||||
th.clearActiveTriggers(gameCard, null);
|
||||
th.registerActiveTrigger(gameCard, false);
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(gameCard);
|
||||
th.runTrigger(TriggerType.Specializes, runParams, false);
|
||||
} else if ("Unspecialize".equals(mode)) {
|
||||
gameCard.setSpecialized(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
table.replaceCounterEffect(game, sa, true);
|
||||
|
||||
@@ -37,7 +37,7 @@ public class UntapAllEffect extends SpellAbilityEffect {
|
||||
}
|
||||
list = list2;
|
||||
}
|
||||
list = CardLists.getValidCards(list, valid, card.getController(), card, sa);
|
||||
list = CardLists.getValidCards(list, valid, sa.getActivatingPlayer(), card, sa);
|
||||
|
||||
boolean remember = sa.hasParam("RememberUntapped");
|
||||
for (Card c : list) {
|
||||
|
||||
@@ -212,6 +212,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
private boolean foretoldThisTurn;
|
||||
private boolean foretoldByEffect;
|
||||
|
||||
private boolean specialized;
|
||||
|
||||
private int timesCrewedThisTurn = 0;
|
||||
|
||||
private int classLevel = 1;
|
||||
@@ -239,6 +241,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
// for Vanguard / Manapool / Emblems etc.
|
||||
private boolean isImmutable = false;
|
||||
private boolean isEmblem = false;
|
||||
private boolean isBoon = false;
|
||||
|
||||
private int exertThisTurn = 0;
|
||||
private PlayerCollection exertedByPlayer = new PlayerCollection();
|
||||
@@ -336,6 +339,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
private ReplacementEffect shieldCounterReplaceDestroy = null;
|
||||
private ReplacementEffect stunCounterReplaceUntap = null;
|
||||
|
||||
private Integer readAhead = null;
|
||||
|
||||
// Enumeration for CMC request types
|
||||
public enum SplitCMCMode {
|
||||
CurrentSideCMC,
|
||||
@@ -661,6 +666,20 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
} else if (mode.equals("Meld") && isMeldable()) {
|
||||
return changeToState(CardStateName.Meld);
|
||||
} else if (mode.equals("Specialize") && canSpecialize()) {
|
||||
if (customState.equalsIgnoreCase("white")) {
|
||||
return changeToState(CardStateName.SpecializeW);
|
||||
} else if (customState.equalsIgnoreCase("blue")) {
|
||||
return changeToState(CardStateName.SpecializeU);
|
||||
} else if (customState.equalsIgnoreCase("black")) {
|
||||
return changeToState(CardStateName.SpecializeB);
|
||||
} else if (customState.equalsIgnoreCase("red")) {
|
||||
return changeToState(CardStateName.SpecializeR);
|
||||
} else if (customState.equalsIgnoreCase("green")) {
|
||||
return changeToState(CardStateName.SpecializeG);
|
||||
}
|
||||
} else if (mode.equals("Unspecialize") && isSpecialized()) {
|
||||
return changeToState(CardStateName.Original);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1370,6 +1389,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
public final boolean hasDoubleStrike() {
|
||||
return hasKeyword(Keyword.DOUBLE_STRIKE);
|
||||
}
|
||||
|
||||
public final boolean hasDoubleTeam() {
|
||||
return hasKeyword(Keyword.DOUBLE_TEAM);
|
||||
}
|
||||
|
||||
public final boolean hasSecondStrike() {
|
||||
return hasDoubleStrike() || !hasFirstStrike();
|
||||
@@ -1389,7 +1412,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) {
|
||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||
int addAmount = n;
|
||||
if (addAmount <= 0 || !canReceiveCounters(counterType)) {
|
||||
// As per rule 107.1b
|
||||
@@ -1423,6 +1446,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(this);
|
||||
runParams.put(AbilityKey.Source, source);
|
||||
runParams.put(AbilityKey.CounterType, counterType);
|
||||
if (params != null) {
|
||||
runParams.putAll(params);
|
||||
}
|
||||
for (int i = 0; i < addAmount; i++) {
|
||||
runParams.put(AbilityKey.CounterAmount, oldValue + i + 1);
|
||||
getGame().getTriggerHandler().runTrigger(
|
||||
@@ -2093,12 +2119,18 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
sbLong.append("Trample over planeswalkers").append(" (").append(inst.getReminderText()).append(")").append("\r\n");
|
||||
} else if (keyword.startsWith("Hexproof:")) {
|
||||
final String[] k = keyword.split(":");
|
||||
sbLong.append("Hexproof from ");
|
||||
if (k[2].equals("chosen")) {
|
||||
k[2] = k[1].substring(5).toLowerCase();
|
||||
if(!k[2].equals("Secondary")) {
|
||||
sbLong.append("Hexproof from ");
|
||||
if (k[2].equals("chosen")) {
|
||||
k[2] = k[1].substring(5).toLowerCase();
|
||||
}
|
||||
sbLong.append(k[2]);
|
||||
if (!k[2].contains(" and ")) { // skip reminder text for more complicated Hexproofs
|
||||
sbLong.append(" (").append(inst.getReminderText().replace("chosen", k[2]));
|
||||
sbLong.append(")");
|
||||
}
|
||||
sbLong.append("\r\n");
|
||||
}
|
||||
sbLong.append(k[2]).append(" (").append(inst.getReminderText().replace("chosen", k[2]))
|
||||
.append(")").append("\r\n");
|
||||
} else if (inst.getKeyword().equals(Keyword.COMPANION)) {
|
||||
sbLong.append("Companion — ");
|
||||
sbLong.append(((Companion)inst).getDescription());
|
||||
@@ -2117,6 +2149,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|| keyword.equals("Living Weapon") || keyword.equals("Myriad") || keyword.equals("Exploit")
|
||||
|| keyword.equals("Changeling") || keyword.equals("Delve") || keyword.equals("Decayed")
|
||||
|| keyword.equals("Split second") || keyword.equals("Sunburst")
|
||||
|| keyword.equals("Double team")
|
||||
|| keyword.equals("Suspend") // for the ones without amount
|
||||
|| keyword.equals("Foretell") // for the ones without cost
|
||||
|| keyword.equals("Ascend") || keyword.equals("Totem armor")
|
||||
@@ -2217,11 +2250,12 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|| keyword.startsWith("Embalm") || keyword.startsWith("Level up") || keyword.equals("Prowess")
|
||||
|| keyword.startsWith("Eternalize") || keyword.startsWith("Reinforce")
|
||||
|| keyword.startsWith("Champion") || keyword.startsWith("Prowl") || keyword.startsWith("Adapt")
|
||||
|| keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") || keyword.startsWith("Saga")
|
||||
|| keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") || keyword.startsWith("Saga") || keyword.startsWith("Read ahead")
|
||||
|| keyword.startsWith("Transfigure") || keyword.startsWith("Aura swap")
|
||||
|| keyword.startsWith("Cycling") || keyword.startsWith("TypeCycling")
|
||||
|| keyword.startsWith("Encore") || keyword.startsWith("Mutate") || keyword.startsWith("Dungeon")
|
||||
|| keyword.startsWith("Class") || keyword.startsWith("Blitz")) {
|
||||
|| keyword.startsWith("Class") || keyword.startsWith("Blitz")
|
||||
|| keyword.startsWith("Specialize")) {
|
||||
// keyword parsing takes care of adding a proper description
|
||||
} else if (keyword.equals("Unblockable")) {
|
||||
sbLong.append(getName()).append(" can't be blocked.\r\n");
|
||||
@@ -2242,7 +2276,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
keyword = keyword.replace("Strike", "strike");
|
||||
}
|
||||
sb.append(i !=0 && sb.length() !=0 ? ", " : "");
|
||||
sb.append(i > 0 && sb.length() !=0 ? keyword.toLowerCase() : keyword);
|
||||
sb.append(i > 0 && sb.length() !=0 ? StringUtils.uncapitalize(keyword) : keyword);
|
||||
}
|
||||
if (sbLong.length() > 0) {
|
||||
sbLong.append("\r\n");
|
||||
@@ -3980,6 +4014,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
public final CardStateName getFaceupCardStateName() {
|
||||
if (isFlipped() && hasState(CardStateName.Flipped)) {
|
||||
return CardStateName.Flipped;
|
||||
} else if (isSpecialized()) {
|
||||
return getCurrentStateName();
|
||||
} else if (backside && hasBackSide()) {
|
||||
CardStateName stateName = getRules().getSplitType().getChangedStateName();
|
||||
if (hasState(stateName)) {
|
||||
@@ -4501,7 +4537,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public final void addKeywordForStaticAbility(KeywordInterface kw) {
|
||||
if (kw.getStaticId() > 0) {
|
||||
storedKeywords.put(kw.getStaticId(), kw.getOriginal(), kw);
|
||||
@@ -5185,6 +5221,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
public final boolean isEmblem() {
|
||||
return isEmblem;
|
||||
}
|
||||
public final void setBoon(final boolean isBoon0) {
|
||||
isBoon = isBoon0;
|
||||
view.updateBoon(this);
|
||||
}
|
||||
|
||||
public final boolean isBoon() {
|
||||
return isBoon;
|
||||
}
|
||||
|
||||
public final void setEmblem(final boolean isEmblem0) {
|
||||
isEmblem = isEmblem0;
|
||||
view.updateEmblem(this);
|
||||
@@ -5730,6 +5775,16 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
foretoldThisTurn = false;
|
||||
}
|
||||
|
||||
public boolean isSpecialized() {
|
||||
return specialized;
|
||||
}
|
||||
public final void setSpecialized(final boolean bool) {
|
||||
specialized = bool;
|
||||
}
|
||||
public final boolean canSpecialize() {
|
||||
return getRules() != null && getRules().getSplitType() == CardSplitType.Specialize;
|
||||
}
|
||||
|
||||
public int getTimesCrewedThisTurn() {
|
||||
return timesCrewedThisTurn;
|
||||
}
|
||||
@@ -7103,4 +7158,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
return StaticAbilityIgnoreLegendRule.ignoreLegendRule(this);
|
||||
}
|
||||
|
||||
public Integer getReadAhead() {
|
||||
return readAhead;
|
||||
}
|
||||
public void setReadAhead(int value) {
|
||||
readAhead = value;
|
||||
}
|
||||
|
||||
public boolean attackVigilance() {
|
||||
return StaticAbilityAttackVigilance.attackVigilance(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DamageAll, runParams, false);
|
||||
}
|
||||
|
||||
public void triggerExcessDamage(boolean isCombat, Map<Card, Integer> lethalDamage, final Game game) {
|
||||
public void triggerExcessDamage(boolean isCombat, Map<Card, Integer> lethalDamage, final Game game, final Map<Integer, Card> lkiCache) {
|
||||
for (Entry<Card, Integer> damaged : lethalDamage.entrySet()) {
|
||||
int sum = 0;
|
||||
for (Integer i : this.column(damaged.getKey()).values()) {
|
||||
@@ -112,6 +112,10 @@ public class CardDamageMap extends ForwardingTable<Card, GameEntity, Integer> {
|
||||
}
|
||||
|
||||
int excess = sum - (damaged.getKey().hasBeenDealtDeathtouchDamage() ? 1 : damaged.getValue());
|
||||
|
||||
// also update the DamageHistory, but overwrite previous excess outcomes
|
||||
// because Rith, Liberated Primeval cares about who controlled it at this moment
|
||||
lkiCache.get(damaged.getKey().getId()).setHasBeenDealtExcessDamageThisTurn(excess > 0);
|
||||
if (excess > 0) {
|
||||
damaged.getKey().setHasBeenDealtExcessDamageThisTurn(true);
|
||||
// Run triggers
|
||||
|
||||
@@ -77,7 +77,7 @@ public class CardFactory {
|
||||
*/
|
||||
public final static Card copyCard(final Card in, boolean assignNewId) {
|
||||
Card out;
|
||||
if (!(in.isToken() || in.getCopiedPermanent() != null)) {
|
||||
if (!(in.isRealToken() || in.getCopiedPermanent() != null)) {
|
||||
out = assignNewId ? getCard(in.getPaperCard(), in.getOwner(), in.getGame())
|
||||
: getCard(in.getPaperCard(), in.getOwner(), in.getId(), in.getGame());
|
||||
} else { // token
|
||||
@@ -97,6 +97,7 @@ public class CardFactory {
|
||||
out.setAttachedCards(in.getAttachedCards());
|
||||
out.setEntityAttachedTo(in.getEntityAttachedTo());
|
||||
|
||||
out.setSpecialized(in.isSpecialized());
|
||||
out.addRemembered(in.getRemembered());
|
||||
out.addImprintedCards(in.getImprintedCards());
|
||||
out.setCommander(in.isRealCommander());
|
||||
@@ -364,7 +365,33 @@ public class CardFactory {
|
||||
|
||||
readCardFace(card, rules.getMainPart());
|
||||
|
||||
if (st != CardSplitType.None) {
|
||||
if (st == CardSplitType.Specialize) {
|
||||
card.addAlternateState(CardStateName.SpecializeW, false);
|
||||
card.setState(CardStateName.SpecializeW, false);
|
||||
if (rules.getWSpecialize() != null) {
|
||||
readCardFace(card, rules.getWSpecialize());
|
||||
}
|
||||
card.addAlternateState(CardStateName.SpecializeU, false);
|
||||
card.setState(CardStateName.SpecializeU, false);
|
||||
if (rules.getUSpecialize() != null) {
|
||||
readCardFace(card, rules.getUSpecialize());
|
||||
}
|
||||
card.addAlternateState(CardStateName.SpecializeB, false);
|
||||
card.setState(CardStateName.SpecializeB, false);
|
||||
if (rules.getBSpecialize() != null) {
|
||||
readCardFace(card, rules.getBSpecialize());
|
||||
}
|
||||
card.addAlternateState(CardStateName.SpecializeR, false);
|
||||
card.setState(CardStateName.SpecializeR, false);
|
||||
if (rules.getRSpecialize() != null) {
|
||||
readCardFace(card, rules.getRSpecialize());
|
||||
}
|
||||
card.addAlternateState(CardStateName.SpecializeG, false);
|
||||
card.setState(CardStateName.SpecializeG, false);
|
||||
if (rules.getGSpecialize() != null) {
|
||||
readCardFace(card, rules.getGSpecialize());
|
||||
}
|
||||
} else if (st != CardSplitType.None) {
|
||||
card.addAlternateState(st.getChangedStateName(), false);
|
||||
card.setState(st.getChangedStateName(), false);
|
||||
if (rules.getOtherPart() != null) {
|
||||
|
||||
@@ -162,14 +162,12 @@ public class CardFactoryUtil {
|
||||
*/
|
||||
public static SpellAbility abilityMorphUp(final CardState cardState, final String costStr, final boolean mega) {
|
||||
Cost cost = new Cost(costStr, true);
|
||||
String costDesc = cost.toString();
|
||||
StringBuilder sbCost = new StringBuilder(mega ? "Megamorph" : "Morph");
|
||||
sbCost.append(" ");
|
||||
if (!cost.isOnlyManaCost()) {
|
||||
sbCost.append("— ");
|
||||
}
|
||||
// get rid of the ": " at the end
|
||||
sbCost.append(costDesc, 0, costDesc.length() - 2);
|
||||
sbCost.append(cost.toString());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("ST$ SetState | Cost$ ").append(costStr).append(" | CostDesc$ ").append(sbCost);
|
||||
@@ -957,8 +955,9 @@ public class CardFactoryUtil {
|
||||
inst.addTrigger(parsedTrigger);
|
||||
inst.addTrigger(parsedTrigReturn);
|
||||
} else if (keyword.startsWith("Casualty")) {
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | CheckSVar$ Casualty | TriggerZones$ Stack | Secondary$ True";
|
||||
String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ 1 | MayChooseTarget$ True";
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | TriggerZones$ Stack | " +
|
||||
"CheckSVar$ CasualtyPaid | Secondary$ True";
|
||||
String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True";
|
||||
String[] k = keyword.split(":");
|
||||
if (k.length > 2) {
|
||||
abString = abString + " | " + k[2];
|
||||
@@ -967,6 +966,7 @@ public class CardFactoryUtil {
|
||||
final Trigger casualtyTrigger = TriggerHandler.parseTrigger(trigScript, card, intrinsic);
|
||||
casualtyTrigger.setOverridingAbility(AbilityFactory.getAbility(abString, card));
|
||||
casualtyTrigger.setSVar("Casualty", "0");
|
||||
casualtyTrigger.setSVar("CasualtyPaid", "0");
|
||||
|
||||
inst.addTrigger(casualtyTrigger);
|
||||
} else if (keyword.equals("Conspire")) {
|
||||
@@ -1063,6 +1063,23 @@ public class CardFactoryUtil {
|
||||
dethroneTrigger.setOverridingAbility(AbilityFactory.getAbility(abString, card));
|
||||
|
||||
inst.addTrigger(dethroneTrigger);
|
||||
} else if (keyword.equals("Double team")) {
|
||||
final String trigString = "Mode$ Attacks | ValidCard$ Card.Self+nonToken | TriggerZones$ Battlefield" +
|
||||
" | Secondary$ True | TriggerDescription$ Double team (" + inst.getReminderText() + ")";
|
||||
final String makeString = "DB$ MakeCard | DefinedName$ Self | Zone$ Hand | RememberMade$ True | Conjure$ True";
|
||||
final String forgetString = "DB$ Effect | Duration$ Permanent | RememberObjects$ Remembered | ImprintCards$ TriggeredAttacker | StaticAbilities$ RemoveDoubleTeamMade";
|
||||
final String madeforgetmadeString = "Mode$ Continuous | EffectZone$ Command | Affected$ Card.IsRemembered,Card.IsImprinted | RemoveKeyword$ Double team | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ Both cards perpetually lose double team.";
|
||||
final String CleanupString = "DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True";
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigString, card, intrinsic);
|
||||
final SpellAbility youMake = AbilityFactory.getAbility(makeString, card);
|
||||
final AbilitySub forget = (AbilitySub) AbilityFactory.getAbility(forgetString, card);
|
||||
final AbilitySub Cleanup = (AbilitySub) AbilityFactory.getAbility(CleanupString, card);
|
||||
forget.setSVar("RemoveDoubleTeamMade",madeforgetmadeString);
|
||||
youMake.setSubAbility(forget);
|
||||
forget.setSubAbility(Cleanup);
|
||||
trigger.setOverridingAbility(youMake);
|
||||
|
||||
inst.addTrigger(trigger);
|
||||
} else if (keyword.startsWith("Echo")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String cost = k[1];
|
||||
@@ -1697,7 +1714,7 @@ public class CardFactoryUtil {
|
||||
parsedTrigger.setOverridingAbility(sa);
|
||||
|
||||
inst.addTrigger(parsedTrigger);
|
||||
} else if (keyword.startsWith("Saga")) {
|
||||
} else if (keyword.startsWith("Saga") || keyword.startsWith("Read ahead")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final List<String> abs = Arrays.asList(k[2].split(","));
|
||||
if (abs.size() != Integer.valueOf(k[1])) {
|
||||
@@ -1724,9 +1741,10 @@ public class CardFactoryUtil {
|
||||
for (int i = idx; i <= skipId; i++) {
|
||||
SpellAbility sa = AbilityFactory.getAbility(card, ab);
|
||||
sa.setChapter(i);
|
||||
sa.setLastChapter(idx == abs.size());
|
||||
|
||||
StringBuilder trigStr = new StringBuilder("Mode$ CounterAdded | ValidCard$ Card.Self | TriggerZones$ Battlefield");
|
||||
trigStr.append("| CounterType$ LORE | CounterAmount$ EQ").append(i);
|
||||
trigStr.append("| Chapter$ True | CounterType$ LORE | CounterAmount$ EQ").append(i);
|
||||
if (i != idx) {
|
||||
trigStr.append(" | Secondary$ True");
|
||||
}
|
||||
@@ -2311,6 +2329,23 @@ public class CardFactoryUtil {
|
||||
re.getOverridingAbility().setSVar("Sunburst", "Count$Converge");
|
||||
}
|
||||
inst.addReplacement(re);
|
||||
} else if (keyword.startsWith("Read ahead")) {
|
||||
final String[] k = keyword.split(":");
|
||||
String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | Secondary$ True | ReplacementResult$ Updated | Description$ Choose a chapter and start with that many lore counters.";
|
||||
|
||||
String effStr = "DB$ PutCounter | Defined$ Self | CounterType$ LORE | ETB$ True | UpTo$ True | UpToMin$ 1 | ReadAhead$ True | CounterNum$ " + k[1];
|
||||
|
||||
SpellAbility saCounter = AbilityFactory.getAbility(effStr, card);
|
||||
|
||||
if (!intrinsic) {
|
||||
saCounter.setIntrinsic(false);
|
||||
}
|
||||
|
||||
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card);
|
||||
|
||||
re.setOverridingAbility(saCounter);
|
||||
|
||||
inst.addReplacement(re);
|
||||
} else if (keyword.equals("Rebound")) {
|
||||
String repeffstr = "Event$ Moved | ValidLKI$ Card.Self+wasCastFromHand+YouOwn+YouCtrl "
|
||||
+ " | Origin$ Stack | Destination$ Graveyard | Fizzle$ False "
|
||||
@@ -3215,6 +3250,22 @@ public class CardFactoryUtil {
|
||||
final AbilitySub cleanSub = (AbilitySub) AbilityFactory.getAbility(cleanStr, card);
|
||||
effectSub.setSubAbility(cleanSub);
|
||||
|
||||
sa.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Specialize")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String cost = k[1];
|
||||
String flavor = k.length > 2 && !k[2].isEmpty() ? k[2] + " – " : "";
|
||||
String condition = k.length > 3 && !k[3].isEmpty() ? ". " + k[3] : "";
|
||||
String extra = k.length > 4 && !k[4].isEmpty() ? k[4] + " | " : "";
|
||||
|
||||
final String effect = "AB$ SetState | Cost$ " + cost + " ChooseColor<1> Discard<1/Card.ChosenColor;" +
|
||||
"Card.AssociatedWithChosenColor/card of the chosen color or its associated basic land type> | " +
|
||||
"Mode$ Specialize | SorcerySpeed$ True | " + extra + "PrecostDesc$ " + flavor + "Specialize | " +
|
||||
"CostDesc$ " + ManaCostParser.parse(cost) + condition + " | SpellDescription$ (" +
|
||||
inst.getReminderText() + ")";
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Spectacle")) {
|
||||
@@ -3660,6 +3711,9 @@ public class CardFactoryUtil {
|
||||
String effect = "Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Secondary$ True"
|
||||
+ "| Amount$ Undaunted | EffectZone$ All | Description$ Undaunted (" + inst.getReminderText() + ")";
|
||||
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
||||
} else if (keyword.equals("Vigilance")) {
|
||||
String effect = "Mode$ AttackVigilance | ValidCard$ Card.Self | Secondary$ True | Description$ Vigilance (" + inst.getReminderText() + ")";
|
||||
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
||||
} else if (keyword.equals("MayFlashSac")) {
|
||||
String effect = "Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | Secondary$ True | MayPlay$ True"
|
||||
+ " | MayPlayNotSorcerySpeed$ True | MayPlayWithFlash$ True | MayPlayText$ Sacrifice at the next cleanup step"
|
||||
|
||||
@@ -246,6 +246,13 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.IsEmblem, c.isEmblem());
|
||||
}
|
||||
|
||||
public boolean isBoon() {
|
||||
return get(TrackableProperty.IsBoon);
|
||||
}
|
||||
public void updateBoon(Card c) {
|
||||
set(TrackableProperty.IsBoon, c.isBoon());
|
||||
}
|
||||
|
||||
public boolean isTokenCard() { return get(TrackableProperty.TokenCard); }
|
||||
void updateTokenCard(Card c) { set(TrackableProperty.TokenCard, c.isTokenCard()); }
|
||||
|
||||
@@ -449,7 +456,7 @@ public class CardView extends GameEntityView {
|
||||
return get(TrackableProperty.Remembered);
|
||||
}
|
||||
void updateRemembered(Card c) {
|
||||
if (c.getRemembered() == null || Iterables.size(c.getRemembered()) == 0) {
|
||||
if (c.getRemembered() == null || Iterables.isEmpty(c.getRemembered())) {
|
||||
set(TrackableProperty.Remembered, null);
|
||||
return;
|
||||
}
|
||||
@@ -1364,6 +1371,7 @@ public class CardView extends GameEntityView {
|
||||
public boolean hasDefender() { return get(TrackableProperty.HasDefender); }
|
||||
public boolean hasDivideDamage() { return get(TrackableProperty.HasDivideDamage); }
|
||||
public boolean hasDoubleStrike() { return get(TrackableProperty.HasDoubleStrike); }
|
||||
public boolean hasDoubleTeam() { return get(TrackableProperty.HasDoubleTeam); }
|
||||
public boolean hasFirstStrike() { return get(TrackableProperty.HasFirstStrike); }
|
||||
public boolean hasFlying() { return get(TrackableProperty.HasFlying); }
|
||||
public boolean hasFear() { return get(TrackableProperty.HasFear); }
|
||||
|
||||
@@ -183,6 +183,8 @@ public enum CounterEnumType {
|
||||
|
||||
INFECTION("INFCT", 0, 230, 66),
|
||||
|
||||
INGENUITY("INGTY", 67, 186, 205),
|
||||
|
||||
INTERVENTION("INTRV", 205, 203, 105),
|
||||
|
||||
INVITATION("INVIT", 205, 0, 26),
|
||||
@@ -265,6 +267,8 @@ public enum CounterEnumType {
|
||||
|
||||
PHYLACTERY("PHYLA", 117, 219, 153),
|
||||
|
||||
PHYRESIS("PHYRE", 125, 97, 128),
|
||||
|
||||
POINT("POINT", 153, 255, 130),
|
||||
|
||||
POLYP("POLYP", 236, 185, 198),
|
||||
|
||||
@@ -341,6 +341,13 @@ public class Cost implements Serializable {
|
||||
return new CostUnattach(splitStr[0], description);
|
||||
}
|
||||
|
||||
if (parse.startsWith("ChooseColor<")) {
|
||||
// ChooseColor<NumToChoose>
|
||||
//TODO expand this to set off different UI for Specialize
|
||||
final String[] splitStr = abCostParse(parse, 1);
|
||||
return new CostChooseColor(splitStr[0]);
|
||||
}
|
||||
|
||||
if (parse.startsWith("ChooseCreatureType<")) {
|
||||
final String[] splitStr = abCostParse(parse, 1);
|
||||
return new CostChooseCreatureType(splitStr[0]);
|
||||
|
||||
@@ -398,7 +398,7 @@ public class CostAdjustment {
|
||||
return Math.min(value, maxReduction);
|
||||
}
|
||||
} else {
|
||||
final String color = staticAbility.getParamOrDefault("Cost", staticAbility.getParam("Color"));
|
||||
final String color = staticAbility.getParamOrDefault("Cost", staticAbility.getParam("Color"));
|
||||
int sumGeneric = 0;
|
||||
// might be problematic for wierd hybrid combinations
|
||||
for (final String cost : color.split(" ")) {
|
||||
@@ -433,10 +433,6 @@ public class CostAdjustment {
|
||||
if (!st.matchesValidParam("Activator", activator)) {
|
||||
return false;
|
||||
}
|
||||
if (st.hasParam("NonActivatorTurn") && (activator == null
|
||||
|| game.getPhaseHandler().isPlayerTurn(activator))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (st.hasParam("Type")) {
|
||||
final String type = st.getParam("Type");
|
||||
@@ -556,4 +552,4 @@ public class CostAdjustment {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.game.cost;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
|
||||
/**
|
||||
* the class CostChooseColor
|
||||
*/
|
||||
public class CostChooseColor extends CostPart {
|
||||
|
||||
/**
|
||||
* Serializables need a version ID.
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Instantiates a new cost choose color.
|
||||
*
|
||||
* @param amount
|
||||
* the amount
|
||||
*/
|
||||
public CostChooseColor(final String amount) {
|
||||
this.setAmount(amount);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility,
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
*/
|
||||
@Override
|
||||
public final boolean canPay(final SpellAbility ability, final Player payer, final boolean effect) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa, final boolean effect) {
|
||||
sa.getHostCard().setChosenColors(pd.colors);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int paymentOrder() { return 8; }
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#toString()
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final Integer i = this.convertAmount();
|
||||
sb.append("Choose ");
|
||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), "color"));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoable() { return true; }
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.card.cost.CostPart#refund(forge.Card)
|
||||
*/
|
||||
@Override
|
||||
public final void refund(final Card source) {
|
||||
source.setChosenColors(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(ICostVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -166,7 +166,9 @@ public class CostDiscard extends CostPartWithList {
|
||||
sameName = true;
|
||||
type = TextUtil.fastReplace(type, "+WithSameName", "");
|
||||
}
|
||||
if (!type.equals("Random") && !type.contains("X")) {
|
||||
if (type.contains("ChosenColor") && !source.hasChosenColor()) {
|
||||
//color hasn't been chosen yet, so skip getValidCards
|
||||
} else if (!type.equals("Random") && !type.contains("X")) {
|
||||
// Knollspine Invocation fails to activate without the above conditional
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,12 @@ package forge.game.cost;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -90,12 +89,7 @@ public class CostReveal extends CostPartWithList {
|
||||
return true;
|
||||
} else if (this.getType().equals("SameColor")) {
|
||||
for (final Card card : handList) {
|
||||
if (CardLists.filter(handList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.sharesColorWith(card);
|
||||
}
|
||||
}).size() >= amount) {
|
||||
if (CardLists.count(handList, CardPredicates.sharesColorWith(card)) >= amount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.game.cost;
|
||||
public interface ICostVisitor<T> {
|
||||
|
||||
T visit(CostGainControl cost);
|
||||
T visit(CostChooseColor cost);
|
||||
T visit(CostChooseCreatureType cost);
|
||||
T visit(CostDiscard cost);
|
||||
T visit(CostDamage cost);
|
||||
@@ -40,6 +41,11 @@ public interface ICostVisitor<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(CostChooseColor cost) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(CostChooseCreatureType cost) {
|
||||
return null;
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.util.TextUtil;
|
||||
public class PaymentDecision {
|
||||
public int c = 0;
|
||||
public String type;
|
||||
public List<String> colors;
|
||||
|
||||
public final CardCollection cards = new CardCollection();
|
||||
public final List<Mana> mana;
|
||||
@@ -48,6 +49,11 @@ public class PaymentDecision {
|
||||
type = choice;
|
||||
}
|
||||
|
||||
public PaymentDecision(List<String> choices) {
|
||||
this(null, null, null, null, null);
|
||||
colors = choices;
|
||||
}
|
||||
|
||||
public static PaymentDecision card(Card chosen) {
|
||||
return new PaymentDecision(chosen);
|
||||
}
|
||||
@@ -88,6 +94,10 @@ public class PaymentDecision {
|
||||
return new PaymentDecision(choice);
|
||||
}
|
||||
|
||||
public static PaymentDecision colors(List<String> choices) {
|
||||
return new PaymentDecision(choices);
|
||||
}
|
||||
|
||||
public static PaymentDecision players(List<Player> players) {
|
||||
return new PaymentDecision(null, null, players, null, null);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public enum Keyword {
|
||||
DEVOID("Devoid", SimpleKeyword.class, true, "This card has no color."),
|
||||
DISTURB("Disturb", KeywordWithCost.class, false, "You may cast this card from your graveyard transformed for its disturb cost."),
|
||||
DOUBLE_STRIKE("Double Strike", SimpleKeyword.class, true, "This creature deals both first-strike and regular combat damage."),
|
||||
DOUBLE_TEAM("Double team", SimpleKeyword.class, true, "When this creature attacks, if it's not a token, conjure a duplicate of it into your hand. Then both cards perpetually lose double team."),
|
||||
DREDGE("Dredge", KeywordWithAmount.class, false, "If you would draw a card, instead you may put exactly {%d:card} from the top of your library into your graveyard. If you do, return this card from your graveyard to your hand. Otherwise, draw a card."),
|
||||
ECHO("Echo", KeywordWithCost.class, false, "At the beginning of your upkeep, if this permanent came under your control since the beginning of your last upkeep, sacrifice it unless you pay %s."),
|
||||
EMBALM("Embalm", KeywordWithCost.class, false, "%s, Exile this card from your graveyard: Create a token that's a copy of this card, except it's white, it has no mana cost, and it's a Zombie in addition to its other types. Embalm only as a sorcery."),
|
||||
@@ -153,6 +154,7 @@ public enum Keyword {
|
||||
SCAVENGE("Scavenge", KeywordWithCost.class, false, "%s, Exile this card from your graveyard: Put a number of +1/+1 counters equal to this card's power on target creature. Scavenge only as a sorcery."),
|
||||
SOULBOND("Soulbond", SimpleKeyword.class, true, "You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them."),
|
||||
SOULSHIFT("Soulshift", KeywordWithAmount.class, false, "When this creature dies, you may return target Spirit card with mana value %d or less from your graveyard to your hand."),
|
||||
SPECIALIZE("Specialize", KeywordWithCost.class, false, "%s, Choose a color, discard a card of that color or associated basic land type: This card perpetually specializes into that color. Activate only as a sorcery."),
|
||||
SPECTACLE("Spectacle", KeywordWithCost.class, false, "You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn."),
|
||||
SPLICE("Splice", KeywordWithCostAndType.class, false, "As you cast an %2$s spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell."),
|
||||
SPLIT_SECOND("Split second", SimpleKeyword.class, true, "As long as this spell is on the stack, players can't cast other spells or activate abilities that aren't mana abilities."),
|
||||
|
||||
@@ -7,7 +7,8 @@ public class KeywordWithCost extends KeywordInstance<KeywordWithCost> {
|
||||
|
||||
@Override
|
||||
protected void parse(String details) {
|
||||
cost = new Cost(details.split("\\|", 2)[0].trim(), false);
|
||||
String[] allDetails = details.split(":");
|
||||
cost = new Cost(allDetails[0].split("\\|", 2)[0].trim(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -300,9 +300,9 @@ public class ManaCostBeingPaid {
|
||||
}
|
||||
int otherSubtract = manaToSubtract;
|
||||
List<ManaCostShard> toRemove = Lists.newArrayList();
|
||||
|
||||
|
||||
//TODO move that for parts into extra function if able
|
||||
|
||||
|
||||
// try to remove multicolored hybrid shards
|
||||
// for that, this shard need to be mono colored
|
||||
if (shard.isMonoColor()) {
|
||||
@@ -387,15 +387,14 @@ public class ManaCostBeingPaid {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unpaidShards.keySet().removeAll(toRemove);
|
||||
//System.out.println("Tried to substract a " + shard.toString() + " shard that is not present in this ManaCostBeingPaid");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int difference = manaToSubtract - sc.totalCount;
|
||||
|
||||
|
||||
int difference = manaToSubtract - sc.totalCount;
|
||||
|
||||
if (manaToSubtract >= sc.totalCount) {
|
||||
sc.xCount = 0;
|
||||
sc.totalCount = 0;
|
||||
|
||||
@@ -52,7 +52,6 @@ import forge.game.event.GameEventTokenStateUpdate;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.event.GameEventTurnEnded;
|
||||
import forge.game.event.GameEventTurnPhase;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementResult;
|
||||
import forge.game.replacement.ReplacementType;
|
||||
@@ -556,8 +555,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
final CardCollection untapFromCancel = new CardCollection();
|
||||
// do a full loop first so attackers can't be used to pay for Propaganda
|
||||
for (final Card attacker : combat.getAttackers()) {
|
||||
final boolean shouldTapForAttack = !attacker.hasKeyword(Keyword.VIGILANCE) && !attacker.hasKeyword("Attacking doesn't cause CARDNAME to tap.");
|
||||
if (shouldTapForAttack) {
|
||||
if (!attacker.attackVigilance()) {
|
||||
// set tapped to true without firing triggers because it may affect propaganda costs
|
||||
attacker.setTapped(true);
|
||||
untapFromCancel.add(attacker);
|
||||
@@ -589,8 +587,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
} while (!success);
|
||||
|
||||
for (final Card attacker : combat.getAttackers()) {
|
||||
final boolean shouldTapForAttack = !attacker.hasKeyword(Keyword.VIGILANCE) && !attacker.hasKeyword("Attacking doesn't cause CARDNAME to tap.");
|
||||
if (shouldTapForAttack) {
|
||||
if (!attacker.attackVigilance()) {
|
||||
attacker.setTapped(false);
|
||||
attacker.tap(true, true);
|
||||
}
|
||||
|
||||
@@ -458,14 +458,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return isOpponentOf(otherPlayer);
|
||||
}
|
||||
|
||||
public final boolean setLife(final int newLife, final Card source) {
|
||||
public final boolean setLife(final int newLife, final SpellAbility sa) {
|
||||
boolean change = false;
|
||||
// rule 119.5
|
||||
if (life > newLife) {
|
||||
change = loseLife(life - newLife, false, false) > 0;
|
||||
}
|
||||
else if (newLife > life) {
|
||||
change = gainLife(newLife - life, source);
|
||||
change = gainLife(newLife - life, sa == null ? null : sa.getHostCard(), sa);
|
||||
}
|
||||
else { // life == newLife
|
||||
change = false;
|
||||
@@ -487,9 +487,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return life;
|
||||
}
|
||||
|
||||
public final boolean gainLife(int lifeGain, final Card source) {
|
||||
return gainLife(lifeGain, source, null);
|
||||
}
|
||||
public final boolean gainLife(int lifeGain, final Card source, final SpellAbility sa) {
|
||||
if (!canGainLife()) {
|
||||
return false;
|
||||
@@ -498,7 +495,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
// Run any applicable replacement effects.
|
||||
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||
repParams.put(AbilityKey.LifeGained, lifeGain);
|
||||
repParams.put(AbilityKey.Source, source);
|
||||
repParams.put(AbilityKey.SourceSA, sa);
|
||||
|
||||
switch (getGame().getReplacementHandler().run(ReplacementType.GainLife, repParams)) {
|
||||
case NotReplaced:
|
||||
@@ -835,7 +832,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) {
|
||||
@Override
|
||||
public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map<AbilityKey, Object> params) {
|
||||
int addAmount = n;
|
||||
if (addAmount <= 0 || !canReceiveCounters(counterType)) {
|
||||
// As per rule 107.1b
|
||||
@@ -849,6 +847,9 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(this);
|
||||
runParams.put(AbilityKey.Source, source);
|
||||
runParams.put(AbilityKey.CounterType, counterType);
|
||||
if (params != null) {
|
||||
runParams.putAll(params);
|
||||
}
|
||||
for (int i = 0; i < addAmount; i++) {
|
||||
runParams.put(AbilityKey.CounterAmount, oldValue + i + 1);
|
||||
getGame().getTriggerHandler().runTrigger(TriggerType.CounterAdded, AbilityKey.newMap(runParams), false);
|
||||
@@ -1604,9 +1605,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
}
|
||||
|
||||
// MilledAll trigger
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(this);
|
||||
runParams.put(AbilityKey.Cards, milled);
|
||||
runParams.put(AbilityKey.Player, this);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.MilledAll, runParams, false);
|
||||
|
||||
return milled;
|
||||
|
||||
@@ -49,11 +49,11 @@ public class PlayerProperty {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("Active")) {
|
||||
if (!player.equals(game.getPhaseHandler().getPlayerTurn())) {
|
||||
if (!game.getPhaseHandler().isPlayerTurn(player)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("NonActive")) {
|
||||
if (player.equals(game.getPhaseHandler().getPlayerTurn())) {
|
||||
if (game.getPhaseHandler().isPlayerTurn(player)) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.equals("OpponentToActive")) {
|
||||
|
||||
@@ -63,7 +63,10 @@ public class RegisteredPlayer {
|
||||
}
|
||||
|
||||
public final void addExtraCardsOnBattlefield(Iterable<IPaperCard> extraCardsonTable) {
|
||||
this.extraCardsOnBattlefield = extraCardsonTable;
|
||||
if (this.extraCardsOnBattlefield == null)
|
||||
this.extraCardsOnBattlefield = extraCardsonTable;
|
||||
else
|
||||
this.extraCardsOnBattlefield = Iterables.concat(this.extraCardsOnBattlefield, extraCardsonTable);
|
||||
}
|
||||
|
||||
public int getStartingHand() {
|
||||
|
||||
@@ -100,7 +100,7 @@ public class ReplaceDamage extends ReplacementEffect {
|
||||
//Lava Burst and Whippoorwill check
|
||||
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||
GameEntity affected = (GameEntity) runParams.get(AbilityKey.Affected);
|
||||
if (((cause != null) && (cause.hasParam("NoRedirection")) || (affected.hasKeyword("Damage that would be dealt to CARDNAME can't be redirected.")))) {
|
||||
if ((cause != null && cause.hasParam("NoRedirection") || affected.hasKeyword("Damage that would be dealt to CARDNAME can't be redirected."))) {
|
||||
return false;
|
||||
}
|
||||
// check for DamageRedirection, the Thing where the damage is redirected to must be a creature or planeswalker or a player
|
||||
|
||||
@@ -50,11 +50,11 @@ public class ReplaceGainLife extends ReplacementEffect {
|
||||
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
|
||||
return false;
|
||||
}
|
||||
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.Source))) {
|
||||
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.SourceSA))) {
|
||||
return false;
|
||||
}
|
||||
if ("True".equals(getParam("SourceController"))) {
|
||||
if (runParams.get(AbilityKey.Source) == null || !runParams.get(AbilityKey.Affected).equals(((Card)runParams.get(AbilityKey.Source)).getController())) {
|
||||
if (runParams.get(AbilityKey.SourceSA) == null || !runParams.get(AbilityKey.Affected).equals(((SpellAbility)runParams.get(AbilityKey.SourceSA)).getActivatingPlayer())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
|
||||
player.getGame().getTriggerHandler().runTrigger(TriggerType.TapsForMana, runParams, false);
|
||||
if (source.isLand() && root.isManaAbility() && root.getPayCosts() != null && root.getPayCosts().hasTapCost()) {
|
||||
player.setTappedLandForManaThisTurn(true);
|
||||
root.getActivatingPlayer().setTappedLandForManaThisTurn(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
private boolean cumulativeupkeep = false;
|
||||
private boolean blessing = false;
|
||||
private Integer chapter = null;
|
||||
private boolean lastChapter = false;
|
||||
|
||||
/** The pay costs. */
|
||||
private Cost payCosts;
|
||||
@@ -1066,6 +1067,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
chapter = val;
|
||||
}
|
||||
|
||||
public boolean isLastChapter() {
|
||||
return lastChapter;
|
||||
}
|
||||
public boolean setLastChapter(boolean value) {
|
||||
return lastChapter = value;
|
||||
}
|
||||
|
||||
public StaticAbility getMayPlay() {
|
||||
return mayPlay;
|
||||
}
|
||||
@@ -1129,6 +1137,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
clone.paidAbilities = Lists.newArrayList();
|
||||
clone.setPaidHash(Maps.newHashMap(getPaidHash()));
|
||||
|
||||
// copy last chapter flag for Trigger
|
||||
clone.lastChapter = this.lastChapter;
|
||||
|
||||
if (usesTargeting()) {
|
||||
// the targets need to be cloned, otherwise they might be cleared
|
||||
clone.targetChosen = getTargets().clone();
|
||||
|
||||
@@ -570,7 +570,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
System.out.println(c.getName() + " Did not have activator set in SpellAbilityRestriction.canPlay()");
|
||||
}
|
||||
|
||||
if (!StaticAbilityCastWithFlash.anyWithFlashNeedsTargeting(sa, c, activator)) {
|
||||
if (!StaticAbilityCastWithFlash.anyWithFlashNeedsInfo(sa, c, activator)) {
|
||||
if (!sa.canCastTiming(c, activator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package forge.game.staticability;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class StaticAbilityAttackVigilance {
|
||||
|
||||
static String MODE = "AttackVigilance";
|
||||
|
||||
public static boolean attackVigilance(final Card card) {
|
||||
final Game game = card.getGame();
|
||||
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
||||
for (final StaticAbility stAb : ca.getStaticAbilities()) {
|
||||
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (applyAttackVigilanceAbility(stAb, card)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean applyAttackVigilanceAbility(final StaticAbility stAb, final Card card) {
|
||||
if (!stAb.matchesValidParam("ValidCard", card)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public class StaticAbilityCastWithFlash {
|
||||
|
||||
static String MODE = "CastWithFlash";
|
||||
|
||||
public static boolean anyWithFlashNeedsTargeting(final SpellAbility sa, final Card card, final Player activator) {
|
||||
public static boolean anyWithFlashNeedsInfo(final SpellAbility sa, final Card card, final Player activator) {
|
||||
final Game game = activator.getGame();
|
||||
final CardCollection allp = new CardCollection(game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES));
|
||||
allp.add(card);
|
||||
@@ -20,7 +20,7 @@ public class StaticAbilityCastWithFlash {
|
||||
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) {
|
||||
continue;
|
||||
}
|
||||
if (applyWithFlashNeedsTargeting(stAb, sa, card, activator)) {
|
||||
if (applyWithFlashNeedsInfo(stAb, sa, card, activator)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -45,13 +45,15 @@ public class StaticAbilityCastWithFlash {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean commonParts(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) {
|
||||
private static boolean commonParts(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator, final boolean skipValidSA) {
|
||||
if (!stAb.matchesValidParam("ValidCard", card)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stAb.matchesValidParam("ValidSA", sa)) {
|
||||
return false;
|
||||
if (!skipValidSA) {
|
||||
if (!stAb.matchesValidParam("ValidSA", sa)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stAb.matchesValidParam("Caster", activator)) {
|
||||
@@ -60,29 +62,24 @@ public class StaticAbilityCastWithFlash {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean applyWithFlashNeedsTargeting(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) {
|
||||
if (!commonParts(stAb, sa, card, activator)) {
|
||||
public static boolean applyWithFlashNeedsInfo(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) {
|
||||
boolean info = false;
|
||||
String validSA = stAb.getParam("ValidSA");
|
||||
if (validSA.contains("IsTargeting") || validSA.contains("XCost")) {
|
||||
info = true;
|
||||
}
|
||||
if (!commonParts(stAb, sa, card, activator, info)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return stAb.hasParam("Targeting");
|
||||
return info;
|
||||
}
|
||||
|
||||
public static boolean applyWithFlashAbility(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) {
|
||||
if (!commonParts(stAb, sa, card, activator)) {
|
||||
if (!commonParts(stAb, sa, card, activator, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stAb.hasParam("Targeting")) {
|
||||
if (!sa.usesTargeting()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stAb.matchesValidParam("Targeting", sa.getTargets())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package forge.game.trigger;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardZoneTable;
|
||||
@@ -54,8 +53,8 @@ public class TriggerAbilityTriggered extends Trigger {
|
||||
return false;
|
||||
}
|
||||
final Card source = spellAbility.getHostCard();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Iterable<Card> causes = (Iterable<Card>) runParams.get(AbilityKey.Cause);
|
||||
final Game game = source.getGame();
|
||||
|
||||
if (hasParam("ValidMode")) {
|
||||
List<String> validModes = Arrays.asList(getParam("ValidMode").split(","));
|
||||
@@ -73,6 +72,10 @@ public class TriggerAbilityTriggered extends Trigger {
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchesValidParam("ValidSpellAbility", spellAbility)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!matchesValidParam("ValidSource", source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package forge.game.trigger;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Localizer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TriggerConjureAll extends Trigger {
|
||||
|
||||
public TriggerConjureAll(Map<String, String> params, Card host, boolean intrinsic) {
|
||||
super(params, host, intrinsic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) {
|
||||
return false;
|
||||
}
|
||||
// currently not used
|
||||
//if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) {
|
||||
// return false;
|
||||
//}
|
||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Cards))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||
CardCollection cards = (CardCollection) runParams.get(AbilityKey.Cards);
|
||||
|
||||
if (hasParam("ValidCard")) {
|
||||
cards = CardLists.getValidCards(cards, getParam("ValidCard"), getHostCard().getController(),
|
||||
getHostCard(), this);
|
||||
}
|
||||
|
||||
sa.setTriggeringObject(AbilityKey.Cards, cards);
|
||||
//sa.setTriggeringObject(AbilityKey.Amount, cards.size()) -- currently don't need
|
||||
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player, AbilityKey.Cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImportantStackObjects(SpellAbility sa) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ");
|
||||
sb.append(sa.getTriggeringObject(AbilityKey.Player));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,19 @@ public class TriggerCounterAdded extends Trigger {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO check CR for Read Ahead when they are out
|
||||
// for now assume it only is about etb counter
|
||||
if (hasParam("Chapter") && runParams.containsKey(AbilityKey.ETB) && true == (boolean)runParams.get(AbilityKey.ETB)) {
|
||||
Card card = (Card)runParams.get(AbilityKey.Card);
|
||||
Integer readAhead = card.getReadAhead();
|
||||
if (readAhead != null) {
|
||||
final int actualAmount = (Integer) runParams.get(AbilityKey.CounterAmount);
|
||||
if (actualAmount < readAhead) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.game.trigger;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Localizer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* TriggerSpecializes class.
|
||||
* </p>
|
||||
*/
|
||||
public class TriggerSpecializes extends Trigger {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for TriggerSpecializes
|
||||
* </p>
|
||||
*
|
||||
* @param params
|
||||
* a {@link java.util.HashMap} object.
|
||||
* @param host
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @param intrinsic
|
||||
* the intrinsic
|
||||
*/
|
||||
public TriggerSpecializes (Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||
super(params, host, intrinsic);
|
||||
}
|
||||
|
||||
/** {@inheritDoc}
|
||||
* @param runParams*/
|
||||
@Override
|
||||
public final boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImportantStackObjects(SpellAbility sa) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Localizer.getInstance().getMessage("lblSpecialized")).append(": ");
|
||||
sb.append(sa.getTriggeringObject(AbilityKey.Card));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ public enum TriggerType {
|
||||
ChangesZoneAll(TriggerChangesZoneAll.class),
|
||||
Clashed(TriggerClashed.class),
|
||||
ClassLevelGained(TriggerClassLevelGained.class),
|
||||
ConjureAll(TriggerConjureAll.class),
|
||||
CounterAdded(TriggerCounterAdded.class),
|
||||
CounterAddedOnce(TriggerCounterAddedOnce.class),
|
||||
CounterPlayerAddedAll(TriggerCounterPlayerAddedAll.class),
|
||||
@@ -102,6 +103,7 @@ public enum TriggerType {
|
||||
SearchedLibrary(TriggerSearchedLibrary.class),
|
||||
SetInMotion(TriggerSetInMotion.class),
|
||||
Shuffled(TriggerShuffled.class),
|
||||
Specializes(TriggerSpecializes.class),
|
||||
SpellAbilityCast(TriggerSpellAbilityCastOrCopy.class),
|
||||
SpellAbilityCopy(TriggerSpellAbilityCastOrCopy.class),
|
||||
SpellCast(TriggerSpellAbilityCastOrCopy.class),
|
||||
|
||||
@@ -286,19 +286,30 @@ public class WrappedAbility extends Ability {
|
||||
return sa.isCycling();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isChapter() {
|
||||
return sa.isChapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getChapter() {
|
||||
return sa.getChapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChapter(int val) {
|
||||
sa.setChapter(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastChapter() {
|
||||
return sa.isLastChapter();
|
||||
}
|
||||
@Override
|
||||
public boolean setLastChapter(boolean value) {
|
||||
return sa.setLastChapter(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlashBackAbility() {
|
||||
return sa.isFlashBackAbility();
|
||||
@@ -566,4 +577,5 @@ public class WrappedAbility extends Ability {
|
||||
public void setChosenList(List<AbilitySub> choices) {
|
||||
sa.setChosenList(choices);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public enum TrackableProperty {
|
||||
|
||||
IsImmutable(TrackableTypes.BooleanType),
|
||||
IsEmblem(TrackableTypes.BooleanType),
|
||||
IsBoon(TrackableTypes.BooleanType),
|
||||
|
||||
Flipped(TrackableTypes.BooleanType),
|
||||
Facedown(TrackableTypes.BooleanType),
|
||||
@@ -138,6 +139,7 @@ public enum TrackableProperty {
|
||||
HasDefender(TrackableTypes.BooleanType),
|
||||
HasDivideDamage(TrackableTypes.BooleanType),
|
||||
HasDoubleStrike(TrackableTypes.BooleanType),
|
||||
HasDoubleTeam(TrackableTypes.BooleanType),
|
||||
HasFirstStrike(TrackableTypes.BooleanType),
|
||||
HasFlying(TrackableTypes.BooleanType),
|
||||
HasFear(TrackableTypes.BooleanType),
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
</resources>
|
||||
<finalName>forge-android-${alpha-version}</finalName>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gdx-nightlies</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
@@ -167,6 +173,12 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
||||
<artifactId>gdx-controllers-android</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
<type>aar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
@@ -401,6 +413,7 @@
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="INSTALLATION.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="ISSUES.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="CHANGES.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="GAMEPAD_README.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/" includes="MANUAL.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui-mobile-dev/" includes="sentry.properties" />
|
||||
<fileset dir="${basedir}/../forge-gui/">
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
|
||||
-keep class io.sentry.android.core.SentryInitProvider
|
||||
-keep class io.sentry.android.core.SentryPerformanceProvider
|
||||
-keep class com.badlogic.gdx.controllers.android.AndroidControllers { *; }
|
||||
-keep class com.github.tommyettinger.textra.** { *; }
|
||||
|
||||
-keep class io.sentry.android.ndk.SentryNdk
|
||||
|
||||
@@ -550,6 +550,7 @@
|
||||
<fileset dir="${basedir}/../forge-gui/" includes="MANUAL.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="CONTRIBUTORS.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="INSTALLATION.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="GAMEPAD_README.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="ISSUES.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="CHANGES.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/">
|
||||
@@ -677,6 +678,7 @@
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="CONTRIBUTORS.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="ISSUES.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="INSTALLATION.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/release-files/" includes="GAMEPAD_README.txt" />
|
||||
<fileset dir="${basedir}/../forge-gui/" includes="MANUAL.txt" />
|
||||
<fileset dir="${basedir}/" includes="sentry.properties" />
|
||||
</copy>
|
||||
|
||||
@@ -230,7 +230,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Card sorin = addCard("Sorin, Solemn Visitor", p);
|
||||
sorin.addCounterInternal(CounterEnumType.LOYALTY, 5, p, false, null);
|
||||
sorin.addCounterInternal(CounterEnumType.LOYALTY, 5, p, false, null, null);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
@@ -275,7 +275,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
String bearCardName = "Runeclaw Bear";
|
||||
addCard(bearCardName, p);
|
||||
Card gideon = addCard("Gideon, Ally of Zendikar", p);
|
||||
gideon.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null);
|
||||
gideon.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null);
|
||||
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
@@ -404,7 +404,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
Game game = initAndCreateGame();
|
||||
Player p = game.getPlayers().get(1);
|
||||
Card sarkhan = addCard(sarkhanCardName, p);
|
||||
sarkhan.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null);
|
||||
sarkhan.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
@@ -439,7 +439,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
addCard(ornithoperCardName, p);
|
||||
addCard(bearCardName, p);
|
||||
Card ajani = addCard(ajaniCardName, p);
|
||||
ajani.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null);
|
||||
ajani.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
@@ -472,7 +472,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
SpellAbility boltSA = boltCard.getFirstSpellAbility();
|
||||
|
||||
Card ajani = addCard(ajaniCardName, p);
|
||||
ajani.addCounterInternal(CounterEnumType.LOYALTY, 8, p, false, null);
|
||||
ajani.addCounterInternal(CounterEnumType.LOYALTY, 8, p, false, null, null);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
|
||||
@@ -523,7 +523,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
addCard("Swamp", p);
|
||||
addCard("Swamp", p);
|
||||
Card depths = addCard("Dark Depths", p);
|
||||
depths.addCounterInternal(CounterEnumType.ICE, 10, p, false, null);
|
||||
depths.addCounterInternal(CounterEnumType.ICE, 10, p, false, null, null);
|
||||
Card thespian = addCard("Thespian's Stage", p);
|
||||
game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p);
|
||||
game.getAction().checkStateEffects(true);
|
||||
@@ -2256,7 +2256,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
Player p = game.getPlayers().get(0);
|
||||
|
||||
Card polukranos = addCard(polukranosCardName, p);
|
||||
polukranos.addCounterInternal(CounterEnumType.P1P1, 6, p, false, null);
|
||||
polukranos.addCounterInternal(CounterEnumType.P1P1, 6, p, false, null, null);
|
||||
addCard(hydraCardName, p);
|
||||
addCard(leylineCardName, p);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
@@ -2301,7 +2301,7 @@ public class GameSimulationTest extends SimulationTest {
|
||||
}
|
||||
|
||||
Card nishoba = addCard(nishobaName, p1);
|
||||
nishoba.addCounterInternal(CounterEnumType.P1P1, 7, p1, false, null);
|
||||
nishoba.addCounterInternal(CounterEnumType.P1P1, 7, p1, false, null, null);
|
||||
addCard(capridorName, p1);
|
||||
Card pridemate = addCard(pridemateName, p1);
|
||||
Card indestructibility = addCard(indestructibilityName, p1);
|
||||
|
||||
@@ -48,7 +48,8 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
|
||||
// Get Card From Editions Test fixtures
|
||||
protected final String originalArtShivanDragonEdition = "LEA";
|
||||
protected final String latestArtShivanDragonEdition = "M20";
|
||||
protected final String latestArtShivanDragonEdition = "P30H";
|
||||
protected final String latestArtShivanDragonEditionNoPromo = "M20";
|
||||
|
||||
protected final String originalArtLightningDragonEdition = "USG";
|
||||
protected final String originalArtLightningDragonEditionNoPromo = "USG";
|
||||
@@ -56,8 +57,8 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
protected final String latestArtLightningDragonEdition = "VMA";
|
||||
protected final String latestArtLightningDragonEditionNoPromo = "USG";
|
||||
|
||||
protected final String latestArtHymnToTourachEdition = "EMA";
|
||||
protected final String latestArtHymnToTourachEditionNoPromo = "EMA";
|
||||
protected final String latestArtHymnToTourachEdition = "PLIST";
|
||||
protected final String latestArtHymnToTourachEditionNoPromo = "PLIST";
|
||||
protected final String originalArtHymnToTourachEdition = "FEM";
|
||||
protected final String originalArtHymnToTourachEditionNoPromo = "FEM";
|
||||
|
||||
@@ -423,7 +424,7 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
|
||||
sdCard = this.cardDb.getCardFromEditions(cardNameShivanDragon, frame);
|
||||
assertEquals(sdCard.getName(), cardNameShivanDragon);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEdition);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEditionNoPromo);
|
||||
|
||||
ldCard = this.cardDb.getCardFromEditions(cardNameLightningDragon, frame);
|
||||
assertEquals(ldCard.getName(), cardNameLightningDragon);
|
||||
@@ -653,7 +654,8 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
nullCard = this.cardDb.getCardFromEditions(null, preference);
|
||||
assertNull(nullCard);
|
||||
|
||||
shivanNotExistingDragon = this.cardDb.getCardFromEditions(cardNameShivanDragon, preference, 2);
|
||||
//P30H Shivan Dragon had 2 treatments, so bumped artIndex to 3
|
||||
shivanNotExistingDragon = this.cardDb.getCardFromEditions(cardNameShivanDragon, preference, 3);
|
||||
assertNull(shivanNotExistingDragon);
|
||||
|
||||
nullCard = this.cardDb.getCardFromEditions(cardNameHymnToTourach, preference, 5);
|
||||
@@ -1138,7 +1140,7 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
sdCard = this.cardDb.getCardFromEditionsReleasedAfter(cardNameShivanDragon, artPreference,
|
||||
tenthEditionReleaseDate);
|
||||
assertEquals(sdCard.getName(), cardNameShivanDragon);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEdition);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEditionNoPromo);
|
||||
|
||||
// foiled card request
|
||||
ldFoilCard = this.cardDb.getCardFromEditionsReleasedAfter(cardNameFoilLightningDragon, artPreference,
|
||||
@@ -1259,7 +1261,7 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
sdCard = this.cardDb.getCardFromEditionsReleasedAfter(cardNameShivanDragon, artPreference, 1,
|
||||
tenthEditionReleaseDate);
|
||||
assertEquals(sdCard.getName(), cardNameShivanDragon);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEdition);
|
||||
assertEquals(sdCard.getEdition(), latestArtShivanDragonEditionNoPromo);
|
||||
assertEquals(sdCard.getArtIndex(), 1);
|
||||
|
||||
// foiled card request
|
||||
@@ -1747,22 +1749,24 @@ public class CardDbCardMockTestCase extends CardMockTestCase {
|
||||
assertEquals(shivanDragon.getName(), cardNameShivanDragon);
|
||||
assertEquals(shivanDragon.getEdition(), latestArtShivanDragonEdition);
|
||||
|
||||
Date alphaRelaseDate = null;
|
||||
Date alphaReleaseDate = null;
|
||||
Date currentDate = Date.from(Instant.now());
|
||||
Date latestShivanDragonReleaseDateToDate = null; // latest print to date for Shivan is in M20
|
||||
Date latestShivanDragonReleaseDateToDate = null; // latest print to date for Shivan is in P30H
|
||||
try {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
alphaRelaseDate = format.parse(alphaEditionReleaseDate);
|
||||
latestShivanDragonReleaseDateToDate = format.parse("2019-07-12");
|
||||
alphaReleaseDate = format.parse(alphaEditionReleaseDate);
|
||||
latestShivanDragonReleaseDateToDate = format.parse("2022-09-09");
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
assertNull(this.cardDb.getCardFromEditionsReleasedBefore(cardNameShivanDragon, alphaRelaseDate));
|
||||
assertNull(this.cardDb.getCardFromEditionsReleasedAfter(cardNameShivanDragon, currentDate));
|
||||
assertNull(this.cardDb.getCardFromEditionsReleasedBefore(cardNameShivanDragon, alphaReleaseDate));
|
||||
assertNull(this.cardDb.getCardFromEditionsReleasedAfter(cardNameShivanDragon,
|
||||
latestShivanDragonReleaseDateToDate));
|
||||
if (currentDate.after(latestShivanDragonReleaseDateToDate)) {
|
||||
assertNull(this.cardDb.getCardFromEditionsReleasedAfter(cardNameShivanDragon, currentDate));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -41,7 +41,7 @@ public class CardEditionCollectionCardMockTestCase extends CardMockTestCase {
|
||||
|
||||
CardDb cardDb = FModel.getMagicDb().getCommonCards();
|
||||
String[] cardNames = { "Shivan Dragon", "Animate Wall", "Balance", "Blessing", "Force of Will" };
|
||||
String[] expectedSets = { "M20", "MED", "SLD", "M14", "DMR" };
|
||||
String[] expectedSets = { "P30H", "MED", "SLD", "M14", "DMR" };
|
||||
List<PaperCard> cards = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
String cardName = cardNames[i];
|
||||
|
||||
@@ -214,7 +214,12 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gdx-nightlies</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
@@ -244,5 +249,10 @@
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
||||
<artifactId>gdx-controllers-desktop</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -23,7 +23,12 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gdx-nightlies</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>forge</groupId>
|
||||
@@ -45,6 +50,11 @@
|
||||
<artifactId>forge-gui</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx-controllers</groupId>
|
||||
<artifactId>gdx-controllers-core</artifactId>
|
||||
<version>2.2.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.badlogicgames.gdx</groupId>
|
||||
<artifactId>gdx</artifactId>
|
||||
|
||||
@@ -5,6 +5,10 @@ import com.badlogic.gdx.ApplicationListener;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.controllers.Controller;
|
||||
import com.badlogic.gdx.controllers.ControllerAdapter;
|
||||
import com.badlogic.gdx.controllers.ControllerListener;
|
||||
import com.badlogic.gdx.controllers.Controllers;
|
||||
import com.badlogic.gdx.graphics.Cursor;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
@@ -18,6 +22,7 @@ import com.badlogic.gdx.utils.Clipboard;
|
||||
import forge.adventure.scene.*;
|
||||
import forge.adventure.stage.MapStage;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.Assets;
|
||||
import forge.assets.AssetsDownloader;
|
||||
@@ -67,6 +72,9 @@ public class Forge implements ApplicationListener {
|
||||
private static Graphics graphics;
|
||||
private static FrameRate frameRate;
|
||||
private static FScreen currentScreen;
|
||||
private static ControllerListener controllerListener;
|
||||
private static boolean hasGamepad = false;
|
||||
public static Texture lastPreview = null;
|
||||
protected static SplashScreen splashScreen;
|
||||
protected static ClosingScreen closingScreen;
|
||||
protected static TransitionScreen transitionScreen;
|
||||
@@ -249,6 +257,13 @@ public class Forge implements ApplicationListener {
|
||||
});
|
||||
});
|
||||
}
|
||||
public static boolean hasGamepad() {
|
||||
//Classic Mode Various Screen GUI are not yet supported, needs control mapping for each screens
|
||||
if (isMobileAdventureMode) {
|
||||
return hasGamepad && Forge.isLandscapeMode(); //portrait is not supported for Gamepad
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static InputProcessor getInputProcessor() {
|
||||
return inputProcessor;
|
||||
@@ -321,6 +336,7 @@ public class Forge implements ApplicationListener {
|
||||
altZoneTabs = true;
|
||||
//pixl cursor for adventure
|
||||
setCursor(null, "0");
|
||||
enableControllerListener();
|
||||
loadAdventureResources(true);
|
||||
}
|
||||
private static void loadAdventureResources(boolean startScene) {
|
||||
@@ -966,6 +982,7 @@ public class Forge implements ApplicationListener {
|
||||
SoundSystem.instance.dispose();
|
||||
try {
|
||||
ExceptionHandler.unregisterErrorHandling();
|
||||
lastPreview.dispose();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
@@ -975,6 +992,10 @@ public class Forge implements ApplicationListener {
|
||||
return ((Forge)Gdx.app.getApplicationListener()).assets;
|
||||
}
|
||||
public static boolean switchScene(Scene newScene) {
|
||||
if (newScene instanceof RewardScene || newScene instanceof SpellSmithScene || newScene instanceof DeckSelectScene || newScene instanceof PlayerStatisticScene) {
|
||||
if (!(currentScene instanceof ForgeScene)) //prevent overwriting the last preview if last scene is instance of ForgeScene
|
||||
WorldSave.getCurrentSave().header.createPreview();
|
||||
}
|
||||
if (currentScene != null) {
|
||||
if (!currentScene.leave())
|
||||
return false;
|
||||
@@ -1352,6 +1373,7 @@ public class Forge implements ApplicationListener {
|
||||
magnify = true;
|
||||
mouseMovedX = screenX;
|
||||
mouseMovedY = screenY;
|
||||
hasGamepad = false; //prevent drawing some panels
|
||||
//todo: mouse listener for android?
|
||||
if (GuiBase.isAndroid())
|
||||
return true;
|
||||
@@ -1388,4 +1410,174 @@ public class Forge implements ApplicationListener {
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
public static void enableControllerListener() {
|
||||
if (controllerListener == null) {
|
||||
controllerListener = new ControllerAdapter() {
|
||||
@Override
|
||||
public void connected(final Controller controller) {
|
||||
Gdx.app.log("Controller", "Controller connected: " + controller.getName()
|
||||
+ "/" + controller.getUniqueId());
|
||||
hasGamepad = true;
|
||||
if (controller.canVibrate())
|
||||
controller.startVibration(200,1);
|
||||
if (Forge.isMobileAdventureMode && Forge.currentScene instanceof UIScene) {
|
||||
((UIScene) Forge.currentScene).selectCurrent();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void disconnected(Controller controller) {
|
||||
Gdx.app.log("Controller", "Controller disconnected: " + controller.getName()
|
||||
+ "/" + controller.getUniqueId());
|
||||
hasGamepad = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonDown(Controller controller, int buttonIndex) {
|
||||
//System.out.println(controller.getName()+"["+controller.getUniqueId()+"]: "+buttonIndex);
|
||||
hasGamepad = true;
|
||||
translateButtons(controller, buttonIndex, true);
|
||||
return super.buttonDown(controller, buttonIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonUp(Controller controller, int buttonIndex) {
|
||||
hasGamepad = true;
|
||||
translateButtons(controller, buttonIndex, false);
|
||||
return super.buttonUp(controller, buttonIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean axisMoved(Controller controller, int axisIndex, float value) {
|
||||
//System.out.println(controller.getName()+"["+controller.getUniqueId()+"]: axis: "+axisIndex+" - "+value);
|
||||
hasGamepad = true;
|
||||
translateAxis(controller, axisIndex, value);//prevent multi press axis
|
||||
return super.axisMoved(controller, axisIndex, value);
|
||||
}
|
||||
private void translateAxis(Controller controller, int axisIndex, float value) {
|
||||
if (!hasGamepad())
|
||||
return;//adventure only
|
||||
FContainer container = FOverlay.getTopOverlay();
|
||||
if (container == null) {
|
||||
container = currentScreen;
|
||||
}
|
||||
if (container != null) {
|
||||
if (currentScreen instanceof MatchScreen) {
|
||||
if (4 == axisIndex && value == 1f) { //others are L2Button if missing this axis
|
||||
container.keyDown(Keys.ENTER);
|
||||
}
|
||||
if (5 == axisIndex && value == 1f) { //others are R2 Button if missing this axis
|
||||
container.keyDown(Keys.ESCAPE);
|
||||
}
|
||||
if (controller.getMapping().axisLeftY == axisIndex) {
|
||||
if (value == 1f)
|
||||
container.keyDown(Keys.PAGE_DOWN);
|
||||
}
|
||||
/*if (controller.getMapping().axisLeftX == axisIndex) {
|
||||
if (value == 1f) {
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
private void translateButtons(Controller controller, int buttonIndex, boolean keyDown) {
|
||||
if (!hasGamepad())
|
||||
return; //adventure only
|
||||
if (!keyDown)
|
||||
return; //prevent keyup on forgescene
|
||||
//overlay shoud have priority
|
||||
FContainer container = FOverlay.getTopOverlay();
|
||||
if (container == null) {
|
||||
container = currentScreen;
|
||||
}
|
||||
if (container != null) {
|
||||
if (currentScreen instanceof MatchScreen) {
|
||||
if (controller.getMapping().buttonL2 == buttonIndex) {//others are axis-4
|
||||
container.keyDown(Keys.ENTER);
|
||||
}
|
||||
if (controller.getMapping().buttonR2 == buttonIndex) {//others are axis-5
|
||||
container.keyDown(Keys.ESCAPE);
|
||||
}
|
||||
if (controller.getMapping().buttonX == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_X);
|
||||
}
|
||||
if (controller.getMapping().buttonY == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_Y);
|
||||
}
|
||||
if (controller.getMapping().buttonR1 == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_R1);
|
||||
}
|
||||
if (controller.getMapping().buttonL1 == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_L1);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadDown == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_DOWN);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadLeft == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_LEFT);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadRight == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_RIGHT);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadUp == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_UP);
|
||||
}
|
||||
if (controller.getMapping().buttonA == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_A);
|
||||
}
|
||||
if (controller.getMapping().buttonB == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_B);
|
||||
}
|
||||
if (controller.getMapping().buttonBack == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_SELECT);
|
||||
}
|
||||
} else {//Others
|
||||
/*if (controller.getMapping().buttonL2 == buttonIndex) {//others are axis-4
|
||||
container.keyDown(Keys.ENTER);
|
||||
}
|
||||
if (controller.getMapping().buttonR2 == buttonIndex) {//others are axis-5
|
||||
container.keyDown(Keys.ESCAPE);
|
||||
}*/
|
||||
if (controller.getMapping().buttonDpadDown == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_DOWN);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadLeft == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_LEFT);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadRight == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_RIGHT);
|
||||
}
|
||||
if (controller.getMapping().buttonDpadUp == buttonIndex) {
|
||||
container.keyDown(Keys.DPAD_UP);
|
||||
}
|
||||
if (controller.getMapping().buttonBack == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_SELECT);
|
||||
}
|
||||
if (controller.getMapping().buttonB == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_B);
|
||||
}
|
||||
if (controller.getMapping().buttonA == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_A);
|
||||
}
|
||||
if (controller.getMapping().buttonX == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_X);
|
||||
}
|
||||
if (controller.getMapping().buttonY == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_Y);
|
||||
}
|
||||
if (controller.getMapping().buttonR1 == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_R1);
|
||||
}
|
||||
if (controller.getMapping().buttonL1 == buttonIndex) {
|
||||
container.keyDown(Keys.BUTTON_L1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Controllers.addListener(controllerListener);
|
||||
if (Controllers.getCurrent() != null)
|
||||
System.out.println("Gamepad: " + Controllers.getCurrent().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,7 +582,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
||||
if(blessing != null) {
|
||||
if(blessing.cardRewardBonus > 0) result += blessing.cardRewardBonus;
|
||||
}
|
||||
return Math.max(result, 3);
|
||||
return Math.min(result, 3);
|
||||
}
|
||||
|
||||
public DifficultyData getDifficulty() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.google.common.base.Function;
|
||||
@@ -41,6 +42,7 @@ import java.util.Map;
|
||||
private static final FLabel lblGold = new FLabel.Builder().text("0").icon(FSkinImage.QUEST_COINSTACK).font(FSkinFont.get(16)).insets(new Vector2(Utils.scale(5), 0)).build();
|
||||
|
||||
private static ItemPool<InventoryItem> decksUsingMyCards=new ItemPool<>(InventoryItem.class);
|
||||
private int selected = 0;
|
||||
public static void leave() {
|
||||
AdventurePlayer.current().getNewCards().clear();
|
||||
Forge.clearCurrentScreen();
|
||||
@@ -97,12 +99,7 @@ import java.util.Map;
|
||||
|
||||
boolean isShop=false;
|
||||
public AdventureDeckEditor(boolean createAsShop) {
|
||||
super(new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
leave();
|
||||
}
|
||||
},getPages());
|
||||
super(e -> leave(),getPages());
|
||||
|
||||
isShop=createAsShop;
|
||||
|
||||
@@ -137,12 +134,7 @@ import java.util.Map;
|
||||
FPopupMenu menu = new FPopupMenu() {
|
||||
@Override
|
||||
protected void buildMenu() {
|
||||
addItem(new FMenuItem(Forge.getLocalizer().getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e1) {
|
||||
FDeckViewer.copyDeckToClipboard(getDeck());
|
||||
}
|
||||
}));
|
||||
addItem(new FMenuItem(Forge.getLocalizer().getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, e1 -> FDeckViewer.copyDeckToClipboard(getDeck())));
|
||||
((DeckEditorPage)getSelectedPage()).buildDeckMenu(this);
|
||||
}
|
||||
};
|
||||
@@ -244,12 +236,7 @@ import java.util.Map;
|
||||
protected CardManagerPage(ItemManagerConfig config0, String caption0, FImage icon0) {
|
||||
super(caption0, icon0);
|
||||
config = config0;
|
||||
cardManager.setItemActivateHandler(new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
CardManagerPage.this.onCardActivated(cardManager.getSelectedItem());
|
||||
}
|
||||
});
|
||||
cardManager.setItemActivateHandler(e -> CardManagerPage.this.onCardActivated(cardManager.getSelectedItem()));
|
||||
cardManager.setContextMenuBuilder(new ItemManager.ContextMenuBuilder<PaperCard>() {
|
||||
@Override
|
||||
public void buildMenu(final FDropDownMenu menu, final PaperCard card) {
|
||||
@@ -257,30 +244,10 @@ import java.util.Map;
|
||||
}
|
||||
});
|
||||
}
|
||||
private final Function<Map.Entry<InventoryItem, Integer>, Comparable<?>> fnNewCompare = new Function<Map.Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(Map.Entry<InventoryItem, Integer> from) {
|
||||
return AdventurePlayer.current().getNewCards().contains(from.getKey()) ? Integer.valueOf(1) : Integer.valueOf(0);
|
||||
}
|
||||
};
|
||||
private final Function<Map.Entry<? extends InventoryItem, Integer>, Object> fnNewGet = new Function<Map.Entry<? extends InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(Map.Entry<? extends InventoryItem, Integer> from) {
|
||||
return AdventurePlayer.current().getNewCards().contains(from.getKey()) ? "NEW" : "";
|
||||
}
|
||||
};
|
||||
public static final Function<Map.Entry<InventoryItem, Integer>, Comparable<?>> fnDeckCompare = new Function<Map.Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(Map.Entry<InventoryItem, Integer> from) {
|
||||
return decksUsingMyCards.count(from.getKey());
|
||||
}
|
||||
};
|
||||
public static final Function<Map.Entry<? extends InventoryItem, Integer>, Object> fnDeckGet = new Function<Map.Entry<? extends InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(Map.Entry<? extends InventoryItem, Integer> from) {
|
||||
return Integer.valueOf(decksUsingMyCards.count(from.getKey())).toString();
|
||||
}
|
||||
};
|
||||
private final Function<Map.Entry<InventoryItem, Integer>, Comparable<?>> fnNewCompare = from -> AdventurePlayer.current().getNewCards().contains(from.getKey()) ? Integer.valueOf(1) : Integer.valueOf(0);
|
||||
private final Function<Map.Entry<? extends InventoryItem, Integer>, Object> fnNewGet = from -> AdventurePlayer.current().getNewCards().contains(from.getKey()) ? "NEW" : "";
|
||||
public static final Function<Map.Entry<InventoryItem, Integer>, Comparable<?>> fnDeckCompare = from -> decksUsingMyCards.count(from.getKey());
|
||||
public static final Function<Map.Entry<? extends InventoryItem, Integer>, Object> fnDeckGet = from -> Integer.valueOf(decksUsingMyCards.count(from.getKey())).toString();
|
||||
|
||||
protected void initialize() {
|
||||
|
||||
@@ -410,14 +377,11 @@ import java.util.Map;
|
||||
if (!StringUtils.isEmpty(dest)) {
|
||||
label += " " + dest;
|
||||
}
|
||||
menu.addItem(new FMenuItem(label, icon, new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
if (max == 1) {
|
||||
callback.run(max);
|
||||
} else {
|
||||
GuiChoose.getInteger(cardManager.getSelectedItem() + " - " + verb + " " + Forge.getLocalizer().getMessage("lblHowMany"), 1, max, 20, callback);
|
||||
}
|
||||
menu.addItem(new FMenuItem(label, icon, e -> {
|
||||
if (max == 1) {
|
||||
callback.run(max);
|
||||
} else {
|
||||
GuiChoose.getInteger(cardManager.getSelectedItem() + " - " + verb + " " + Forge.getLocalizer().getMessage("lblHowMany"), 1, max, 20, callback);
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -535,6 +499,30 @@ import java.util.Map;
|
||||
protected CatalogPage(ItemManagerConfig config, String caption0, FImage icon0) {
|
||||
super(config, caption0, icon0);
|
||||
}
|
||||
private void setNextSelected() {
|
||||
setNextSelected(1);
|
||||
}
|
||||
private void setNextSelected(int val) {
|
||||
if (cardManager.getItemCount() < 1)
|
||||
return;
|
||||
if ((cardManager.getSelectedIndex()+val) < cardManager.getItemCount()) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()+val);
|
||||
} else if ((cardManager.getSelectedIndex()+1) < cardManager.getItemCount()) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()+1);
|
||||
}
|
||||
}
|
||||
private void setPreviousSelected() {
|
||||
setPreviousSelected(1);
|
||||
}
|
||||
private void setPreviousSelected(int val) {
|
||||
if (cardManager.getItemCount() < 1)
|
||||
return;
|
||||
if ((cardManager.getSelectedIndex()-val) > -1) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()-val);
|
||||
} else if ((cardManager.getSelectedIndex()-1) > -1) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()-1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
@@ -660,14 +648,11 @@ import java.util.Map;
|
||||
@Override
|
||||
protected void buildDeckMenu(FPopupMenu menu) {
|
||||
if (cardManager.getConfig().getShowUniqueCardsOption()) {
|
||||
menu.addItem(new FCheckBoxMenuItem(Forge.getLocalizer().getMessage("lblUniqueCardsOnly"), cardManager.getWantUnique(), new FEvent.FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
boolean wantUnique = !cardManager.getWantUnique();
|
||||
cardManager.setWantUnique(wantUnique);
|
||||
CatalogPage.this.refresh();
|
||||
cardManager.getConfig().setUniqueCardsOnly(wantUnique);
|
||||
}
|
||||
menu.addItem(new FCheckBoxMenuItem(Forge.getLocalizer().getMessage("lblUniqueCardsOnly"), cardManager.getWantUnique(), e -> {
|
||||
boolean wantUnique = !cardManager.getWantUnique();
|
||||
cardManager.setWantUnique(wantUnique);
|
||||
CatalogPage.this.refresh();
|
||||
cardManager.getConfig().setUniqueCardsOnly(wantUnique);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -676,6 +661,30 @@ import java.util.Map;
|
||||
protected static class DeckSectionPage extends CardManagerPage {
|
||||
private final String captionPrefix;
|
||||
private final DeckSection deckSection;
|
||||
private void setNextSelected() {
|
||||
setNextSelected(1);
|
||||
}
|
||||
private void setNextSelected(int val) {
|
||||
if (cardManager.getItemCount() < 1)
|
||||
return;
|
||||
if ((cardManager.getSelectedIndex()+val) < cardManager.getItemCount()) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()+val);
|
||||
} else if ((cardManager.getSelectedIndex()+1) < cardManager.getItemCount()) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()+1);
|
||||
}
|
||||
}
|
||||
private void setPreviousSelected() {
|
||||
setPreviousSelected(1);
|
||||
}
|
||||
private void setPreviousSelected(int val) {
|
||||
if (cardManager.getItemCount() < 1)
|
||||
return;
|
||||
if ((cardManager.getSelectedIndex()-val) > -1) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()-val);
|
||||
} else if ((cardManager.getSelectedIndex()-1) > -1) {
|
||||
cardManager.setSelectedIndex(cardManager.getSelectedIndex()-1);
|
||||
}
|
||||
}
|
||||
|
||||
protected DeckSectionPage(DeckSection deckSection0, ItemManagerConfig config) {
|
||||
super(config, null, null);
|
||||
@@ -836,5 +845,150 @@ import java.util.Map;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keyCode) {
|
||||
if (keyCode == Input.Keys.BUTTON_SELECT) {
|
||||
return this.tabHeader.btnBack.trigger();
|
||||
} else if (keyCode == Input.Keys.BUTTON_R1) {
|
||||
if (getSelectedPage() instanceof CatalogPage)
|
||||
((CatalogPage) getSelectedPage()).cardManager.closeMenu();
|
||||
else if (getSelectedPage() instanceof DeckSectionPage)
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.closeMenu();
|
||||
selected++;
|
||||
if (selected > 2)
|
||||
selected = 0;
|
||||
setSelectedPage(tabPages[selected]);
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.getConfig().setPileBy(null);
|
||||
((CatalogPage) getSelectedPage()).cardManager.setHideFilters(true);
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.getConfig().setPileBy(null);
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.setHideFilters(true);
|
||||
}
|
||||
} else if (keyCode == Input.Keys.DPAD_RIGHT) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((CatalogPage) getSelectedPage()).setNextSelected();
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((DeckSectionPage) getSelectedPage()).setNextSelected();
|
||||
}
|
||||
} else if (keyCode == Input.Keys.DPAD_LEFT) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((CatalogPage) getSelectedPage()).setPreviousSelected();
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((DeckSectionPage) getSelectedPage()).setPreviousSelected();
|
||||
}
|
||||
} else if (keyCode == Input.Keys.DPAD_DOWN) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.selectNextContext();
|
||||
} else {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getSelectedIndex() < 0)
|
||||
((CatalogPage) getSelectedPage()).setNextSelected();
|
||||
else if (((CatalogPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((CatalogPage) getSelectedPage()).setNextSelected(((CatalogPage) getSelectedPage()).cardManager.getConfig().getImageColumnCount());
|
||||
else
|
||||
((CatalogPage) getSelectedPage()).setNextSelected();
|
||||
}
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.selectNextContext();
|
||||
} else {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getSelectedIndex() < 0)
|
||||
((DeckSectionPage) getSelectedPage()).setNextSelected();
|
||||
else if (((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((DeckSectionPage) getSelectedPage()).setNextSelected(((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getImageColumnCount());
|
||||
else
|
||||
((DeckSectionPage) getSelectedPage()).setNextSelected();
|
||||
}
|
||||
}
|
||||
} else if (keyCode == Input.Keys.DPAD_UP) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.selectPreviousContext();
|
||||
} else {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getSelectedIndex() < 0)
|
||||
((CatalogPage) getSelectedPage()).setNextSelected();
|
||||
else if (((CatalogPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((CatalogPage) getSelectedPage()).setPreviousSelected(((CatalogPage) getSelectedPage()).cardManager.getConfig().getImageColumnCount());
|
||||
else
|
||||
((CatalogPage) getSelectedPage()).setPreviousSelected();
|
||||
}
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.selectPreviousContext();
|
||||
} else {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getSelectedIndex() < 0)
|
||||
((DeckSectionPage) getSelectedPage()).setNextSelected();
|
||||
else if (((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1)
|
||||
((DeckSectionPage) getSelectedPage()).setPreviousSelected(((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getImageColumnCount());
|
||||
else
|
||||
((DeckSectionPage) getSelectedPage()).setPreviousSelected();
|
||||
}
|
||||
}
|
||||
} else if (keyCode == Input.Keys.BUTTON_A) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.isContextMenuOpen())
|
||||
((CatalogPage) getSelectedPage()).cardManager.activateSelectedContext();
|
||||
else
|
||||
((CatalogPage) getSelectedPage()).cardManager.showMenu(true);
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.isContextMenuOpen() )
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.activateSelectedContext();
|
||||
else
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.showMenu(true);
|
||||
}
|
||||
} else if (keyCode == Input.Keys.BUTTON_B) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.closeMenu();
|
||||
} else
|
||||
return this.tabHeader.btnBack.trigger();
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.closeMenu();
|
||||
} else
|
||||
return this.tabHeader.btnBack.trigger();
|
||||
}
|
||||
} else if (keyCode == Input.Keys.BUTTON_Y) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
if (!((CatalogPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getCurrentView().getSelectionCount() > 0) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.getCurrentView().zoomSelected();
|
||||
}
|
||||
} else {
|
||||
((CatalogPage) getSelectedPage()).cardManager.closeMenu();
|
||||
if (((CatalogPage) getSelectedPage()).cardManager.getCurrentView().getSelectionCount() > 0) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.getCurrentView().zoomSelected();
|
||||
}
|
||||
}
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
if (!((DeckSectionPage) getSelectedPage()).cardManager.isContextMenuOpen()) {
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getCurrentView().getSelectionCount() > 0) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.getCurrentView().zoomSelected();
|
||||
}
|
||||
} else {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.closeMenu();
|
||||
if (((DeckSectionPage) getSelectedPage()).cardManager.getCurrentView().getSelectionCount() > 0) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.getCurrentView().zoomSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (keyCode == Input.Keys.BUTTON_L1) {
|
||||
if (getSelectedPage() instanceof CatalogPage) {
|
||||
((CatalogPage) getSelectedPage()).cardManager.closeMenu();
|
||||
int index = ((CatalogPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1 ? 0 : 1;
|
||||
((CatalogPage) getSelectedPage()).cardManager.setViewIndex(index);
|
||||
} else if (getSelectedPage() instanceof DeckSectionPage) {
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.closeMenu();
|
||||
int index = ((DeckSectionPage) getSelectedPage()).cardManager.getConfig().getViewIndex() == 1 ? 0 : 1;
|
||||
((DeckSectionPage) getSelectedPage()).cardManager.setViewIndex(index);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@ public class DeckSelectScene extends UIScene {
|
||||
TextField textInput;
|
||||
Table layout;
|
||||
Label header;
|
||||
TextButton back, edit, rename;
|
||||
TextButton back, edit, rename, dialogRenameBtn, dialogAbortBtn;
|
||||
int currentSlot = 0;
|
||||
ScrollPane scrollPane;
|
||||
|
||||
private DeckSelectScene() {
|
||||
public DeckSelectScene() {
|
||||
super(Forge.isLandscapeMode() ? "ui/deck_selector.json" : "ui/deck_selector_portrait.json");
|
||||
|
||||
layout = new Table();
|
||||
@@ -41,8 +42,12 @@ public class DeckSelectScene extends UIScene {
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblName")+": ")).align(Align.left);
|
||||
dialog.getButtonTable().add(textInput).fillX().expandX();
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblRename"), () -> DeckSelectScene.this.rename())).align(Align.left);
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblAbort"), () -> dialog.hide())).align(Align.left);
|
||||
dialogRenameBtn = Controls.newTextButton(Forge.getLocalizer().getMessage("lblRename"), () -> DeckSelectScene.this.rename());
|
||||
dialog.getButtonTable().add(dialogRenameBtn).align(Align.left).padLeft(15);
|
||||
dialogAbortBtn = Controls.newTextButton(Forge.getLocalizer().getMessage("lblAbort"), () -> dialog.hide());
|
||||
dialog.getButtonTable().add(dialogAbortBtn).align(Align.right).padRight(15);
|
||||
dialog.getColor().a = 0f;
|
||||
dialog.hide();
|
||||
|
||||
back = ui.findActor("return");
|
||||
back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
|
||||
@@ -55,23 +60,14 @@ public class DeckSelectScene extends UIScene {
|
||||
ui.onButtonPress("rename", () -> {
|
||||
textInput.setText(Current.player().getSelectedDeck().getName());
|
||||
dialog.show(stage);
|
||||
stage.setKeyboardFocus(textInput);
|
||||
selectActor(textInput, false);
|
||||
});
|
||||
defColor = ui.findActor("return").getColor();
|
||||
|
||||
ScrollPane scrollPane = ui.findActor("deckSlots");
|
||||
scrollPane = ui.findActor("deckSlots");
|
||||
scrollPane.setActor(layout);
|
||||
}
|
||||
|
||||
private static DeckSelectScene object;
|
||||
|
||||
public static DeckSelectScene instance() {
|
||||
if(object==null)
|
||||
object=new DeckSelectScene();
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
private TextButton addDeckSlot(String name, int i) {
|
||||
TextButton button = Controls.newTextButton("-");
|
||||
button.addListener(new ClickListener() {
|
||||
@@ -123,15 +119,64 @@ public class DeckSelectScene extends UIScene {
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
select(Current.player().getSelectedDeckIndex());
|
||||
clearActorObjects();
|
||||
for (int i = 0; i < AdventurePlayer.NUMBER_OF_DECKS; i++) {
|
||||
if (buttons.containsKey(i)) {
|
||||
buttons.get(i).setText(Current.player().getDeck(i).getName());
|
||||
addActorObject(buttons.get(i));
|
||||
}
|
||||
}
|
||||
addActorObject(back);
|
||||
addActorObject(rename);
|
||||
addActorObject(edit);
|
||||
addActorObject(textInput);
|
||||
addActorObject(dialogRenameBtn);
|
||||
addActorObject(dialogAbortBtn);
|
||||
select(Current.player().getSelectedDeckIndex());
|
||||
super.enter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
layout = new Table();
|
||||
stage.addActor(layout);
|
||||
|
||||
header = Controls.newLabel(Forge.getLocalizer().getMessage("lblSelectYourDeck"));
|
||||
layout.add(header).colspan(2).align(Align.center).pad(2, 5, 2, 5);
|
||||
layout.row();
|
||||
for (int i = 0; i < AdventurePlayer.NUMBER_OF_DECKS; i++)
|
||||
addDeckSlot(Forge.getLocalizer().getMessage("lblDeck")+": " + (i + 1), i);
|
||||
|
||||
dialog = Controls.newDialog(Forge.getLocalizer().getMessage("lblSave"));
|
||||
textInput = Controls.newTextField("");
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblNameYourSaveFile"))).colspan(2);
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblName")+": ")).align(Align.left);
|
||||
dialog.getButtonTable().add(textInput).fillX().expandX();
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblRename"), () -> DeckSelectScene.this.rename())).align(Align.left);
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblAbort"), () -> dialog.hide())).align(Align.left);
|
||||
|
||||
back = ui.findActor("return");
|
||||
back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
|
||||
edit = ui.findActor("edit");
|
||||
edit.getLabel().setText(Forge.getLocalizer().getMessage("lblEdit"));
|
||||
rename = ui.findActor("rename");
|
||||
rename.getLabel().setText(Forge.getLocalizer().getMessage("lblRename"));
|
||||
ui.onButtonPress("return", () -> DeckSelectScene.this.back());
|
||||
ui.onButtonPress("edit", () -> DeckSelectScene.this.edit());
|
||||
ui.onButtonPress("rename", () -> {
|
||||
textInput.setText(Current.player().getSelectedDeck().getName());
|
||||
dialog.show(stage);
|
||||
stage.setKeyboardFocus(textInput);
|
||||
});
|
||||
defColor = ui.findActor("return").getColor();
|
||||
|
||||
ScrollPane scrollPane = ui.findActor("deckSlots");
|
||||
scrollPane.setActor(layout);
|
||||
|
||||
}
|
||||
|
||||
private void rename() {
|
||||
dialog.hide();
|
||||
@@ -141,6 +186,6 @@ public class DeckSelectScene extends UIScene {
|
||||
}
|
||||
|
||||
private void edit() {
|
||||
Forge.switchScene(DeckEditScene.instance());
|
||||
Forge.switchScene(SceneType.DeckEditScene.instance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public class DuelScene extends ForgeScene {
|
||||
changeStartCards += data.changeStartCards;
|
||||
startCards.addAll(data.startBattleWithCards());
|
||||
}
|
||||
player.setCardsOnBattlefield(startCards);
|
||||
player.addExtraCardsOnBattlefield(startCards);
|
||||
player.setStartingLife(Math.max(1, lifeMod + player.getStartingLife()));
|
||||
player.setStartingHand(player.getStartingHand() + changeStartCards);
|
||||
}
|
||||
@@ -291,6 +291,7 @@ public class DuelScene extends ForgeScene {
|
||||
rules.setMatchAnteRarity(true);
|
||||
rules.setGamesPerMatch(1);
|
||||
rules.setManaBurn(false);
|
||||
rules.setWarnAboutAICards(false);
|
||||
|
||||
hostedMatch.setEndGameHook(() -> DuelScene.this.GameEnd());
|
||||
hostedMatch.startMatch(rules, appliedVariants, players, guiMap);
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.stage.GameStage;
|
||||
import forge.adventure.stage.IAfterMatch;
|
||||
|
||||
/**
|
||||
* Hud base scene
|
||||
@@ -55,7 +54,11 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int keycode) {
|
||||
|
||||
if (Forge.hasGamepad()) {
|
||||
if (MapStage.getInstance().isDialogOnlyInput()) {
|
||||
return MapStage.getInstance().buttonPress(keycode);
|
||||
}
|
||||
}
|
||||
if (hud.keyDown(keycode))
|
||||
return true;
|
||||
if(isInHudOnlyMode())
|
||||
|
||||
@@ -92,6 +92,10 @@ public class InnScene extends UIScene {
|
||||
tempHitPointCost = ui.findActor("tempHitPointCost");
|
||||
tempHitPointCost.setDisabled(!purchaseable);
|
||||
tempHitPointCost.getLabel().setText("$" + tempHealthCost);
|
||||
clearActorObjects();
|
||||
addActorObject(tempHitPointCost);
|
||||
addActorObject(sell);
|
||||
addActorObject(leave);
|
||||
}
|
||||
|
||||
private void sell() {
|
||||
@@ -103,6 +107,24 @@ public class InnScene extends UIScene {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
done();
|
||||
}
|
||||
if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
if (selectedActor == null)
|
||||
selectActor(tempHitPointCost, false);
|
||||
else
|
||||
selectNextActor(false);
|
||||
} else if ( keycode == Input.Keys.DPAD_LEFT) {
|
||||
if (selectedActor == null)
|
||||
selectActor(leave, false);
|
||||
else
|
||||
selectPreviousActor(false);
|
||||
|
||||
} else if (keycode == Input.Keys.BUTTON_B) {
|
||||
performTouch(leave);
|
||||
|
||||
} else if (keycode == Input.Keys.BUTTON_A) {
|
||||
performTouch(selectedActor);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
import forge.Forge;
|
||||
import forge.adventure.data.ItemData;
|
||||
import forge.adventure.stage.ConsoleCommandInterpreter;
|
||||
@@ -261,6 +262,7 @@ public class InventoryScene extends UIScene {
|
||||
}
|
||||
|
||||
private void updateInventory() {
|
||||
clearActorObjects();
|
||||
inventoryButtons.clear();
|
||||
inventory.clear();
|
||||
for(int i=0;i<Current.player().getItems().size;i++) {
|
||||
@@ -302,6 +304,7 @@ public class InventoryScene extends UIScene {
|
||||
}
|
||||
}
|
||||
});
|
||||
addActorObject(newActor);
|
||||
}
|
||||
for(Map.Entry<String, Button> slot :equipmentSlots.entrySet()) {
|
||||
if(slot.getValue().getChildren().size>=2)
|
||||
@@ -337,6 +340,27 @@ public class InventoryScene extends UIScene {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
done();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_SELECT)
|
||||
performTouch(ui.findActor("return"));
|
||||
else if (keycode == Input.Keys.BUTTON_B)
|
||||
performTouch(ui.findActor("return"));
|
||||
else if (keycode == Input.Keys.BUTTON_A) {
|
||||
if (selectedActor instanceof ImageButton) {
|
||||
performTouch(equipButton);
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
selectCurrent();
|
||||
}
|
||||
}, 0.25f);
|
||||
|
||||
} else {
|
||||
performTouch(selectedActor);
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_RIGHT || keycode == Input.Keys.DPAD_DOWN)
|
||||
selectNextActor(false);
|
||||
else if (keycode == Input.Keys.DPAD_LEFT || keycode == Input.Keys.DPAD_UP)
|
||||
selectPreviousActor(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package forge.adventure.scene;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
@@ -16,6 +18,7 @@ import forge.adventure.util.UIActor;
|
||||
import forge.adventure.world.WorldSave;
|
||||
import forge.card.ColorSet;
|
||||
import forge.deck.DeckProxy;
|
||||
import forge.gui.GuiBase;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
@@ -39,6 +42,7 @@ public class NewGameScene extends UIScene {
|
||||
private Selector difficulty;
|
||||
private Array<String> stringList, random, custom;
|
||||
private Label colorLabel;
|
||||
private int selected = -1;
|
||||
|
||||
private NewGameScene() {
|
||||
|
||||
@@ -46,6 +50,16 @@ public class NewGameScene extends UIScene {
|
||||
|
||||
selectedName = ui.findActor("nameField");
|
||||
selectedName.setText(NameGenerator.getRandomName("Any", "Any", ""));
|
||||
selectedName.addListener(new InputListener() {
|
||||
@Override
|
||||
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
|
||||
if (!GuiBase.isAndroid() && showGamepadSelector) {
|
||||
//show onscreen keyboard
|
||||
return true;
|
||||
}
|
||||
return super.touchDown(event, x, y, pointer, button);
|
||||
}
|
||||
});
|
||||
avatarImage = ui.findActor("avatarPreview");
|
||||
gender = ui.findActor("gender");
|
||||
mode = ui.findActor("mode");
|
||||
@@ -182,12 +196,153 @@ public class NewGameScene extends UIScene {
|
||||
GamePlayerUtil.getGuiPlayer().setName(selectedName.getText());
|
||||
Forge.switchScene(GameScene.instance());
|
||||
}
|
||||
clearActorObjects();
|
||||
addActorObject(selectedName);
|
||||
addActorObject(race);
|
||||
addActorObject(gender);
|
||||
addActorObject(difficulty);
|
||||
addActorObject(colorId);
|
||||
addActorObject(mode);
|
||||
addActorObject(ui.findActor("back"));
|
||||
addActorObject(ui.findActor("start"));
|
||||
unselectActors();
|
||||
}
|
||||
@Override
|
||||
public boolean pointerMoved(int screenX, int screenY) {
|
||||
ui.screenToLocalCoordinates(pointer.set(screenX,screenY));
|
||||
if (showGamepadSelector) {
|
||||
unselectActors();
|
||||
showGamepadSelector = false;
|
||||
}
|
||||
if (kbVisible)
|
||||
return super.pointerMoved(screenX, screenY);
|
||||
updateHovered();
|
||||
return super.pointerMoved(screenX, screenY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keycode) {
|
||||
if (Forge.hasGamepad())
|
||||
showGamepadSelector = true;
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
back();
|
||||
if(!kbVisible)
|
||||
back();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_SELECT) {
|
||||
if (showGamepadSelector) {
|
||||
if(!kbVisible)
|
||||
performTouch(ui.findActor("back"));
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_START) {
|
||||
if (showGamepadSelector) {
|
||||
if(kbVisible)
|
||||
keyOK();
|
||||
else
|
||||
performTouch(ui.findActor("start"));
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_L2) {
|
||||
if(!kbVisible)
|
||||
selectedName.setText(NameGenerator.getRandomName("Female", "Any", selectedName.getText()));
|
||||
} else if (keycode == Input.Keys.BUTTON_R2) {
|
||||
if(!kbVisible)
|
||||
selectedName.setText(NameGenerator.getRandomName("Male", "Any", selectedName.getText()));
|
||||
} else if (keycode == Input.Keys.BUTTON_L1) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible)
|
||||
toggleShiftOrBackspace(true);
|
||||
else
|
||||
performTouch(ui.findActor("leftAvatar"));
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_R1) {
|
||||
if (showGamepadSelector) {
|
||||
if(kbVisible)
|
||||
toggleShiftOrBackspace(false);
|
||||
else
|
||||
performTouch(ui.findActor("rightAvatar"));
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_DOWN) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
setSelectedKey(keycode);
|
||||
} else {
|
||||
if (selectedActor == mode)
|
||||
selectActor(selectedName, false);
|
||||
else if (selectedActor == ui.findActor("back"))
|
||||
selectActor(ui.findActor("start"), false);
|
||||
else if (selectedActor == ui.findActor("start"))
|
||||
selectActor(ui.findActor("back"), false);
|
||||
else
|
||||
selectNextActor(false);
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_UP) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
setSelectedKey(keycode);
|
||||
} else {
|
||||
if (selectedActor == selectedName)
|
||||
selectActor(mode, false);
|
||||
else if (selectedActor == ui.findActor("start"))
|
||||
selectActor(ui.findActor("back"), false);
|
||||
else if (selectedActor == ui.findActor("back"))
|
||||
selectActor(ui.findActor("start"), false);
|
||||
else
|
||||
selectPreviousActor(false);
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
setSelectedKey(keycode);
|
||||
} else {
|
||||
if (selectedActor == ui.findActor("back") || selectedActor == ui.findActor("start"))
|
||||
selectActor(mode, false);
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
setSelectedKey(keycode);
|
||||
} else {
|
||||
if (!(selectedActor == ui.findActor("back") || selectedActor == ui.findActor("start")))
|
||||
selectActor(ui.findActor("start"), false);
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_A) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
if (selectedKey != null)
|
||||
performTouch(selectedKey);
|
||||
} else {
|
||||
if (selectedActor != null) {
|
||||
if (selectedActor instanceof TextButton)
|
||||
performTouch(selectedActor);
|
||||
else if (selectedActor instanceof TextField && !kbVisible) {
|
||||
lastInputField = selectedActor;
|
||||
showOnScreenKeyboard("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_B) {
|
||||
if (showGamepadSelector) {
|
||||
if (kbVisible) {
|
||||
hideOnScreenKeyboard();
|
||||
} else {
|
||||
performTouch(ui.findActor("back"));
|
||||
}
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_X) {
|
||||
if (showGamepadSelector) {
|
||||
if(!kbVisible)
|
||||
if (selectedActor != null && selectedActor instanceof Selector)
|
||||
performTouch(((Selector) selectedActor).getLeftArrow());
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_Y) {
|
||||
if (showGamepadSelector) {
|
||||
if(!kbVisible)
|
||||
if (selectedActor != null && selectedActor instanceof Selector)
|
||||
performTouch(((Selector) selectedActor).getRightArrow());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class PlayerStatisticScene extends UIScene {
|
||||
TextButton back;
|
||||
private Table enemiesGroup;
|
||||
Label blessingScroll;
|
||||
ScrollPane scrollPane, blessing;
|
||||
|
||||
private PlayerStatisticScene() {
|
||||
super(Forge.isLandscapeMode() ? "ui/statistic.json" : "ui/statistic_portrait.json");
|
||||
@@ -98,6 +99,16 @@ public class PlayerStatisticScene extends UIScene {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
back();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_B)
|
||||
performTouch(ui.findActor("return"));
|
||||
else if (keycode == Input.Keys.BUTTON_A)
|
||||
performTouch(selectedActor);
|
||||
else if (keycode == Input.Keys.BUTTON_L1 || keycode == Input.Keys.DPAD_UP) {
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
} else if (keycode == Input.Keys.BUTTON_R1 || keycode == Input.Keys.DPAD_DOWN) {
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT || keycode == Input.Keys.DPAD_RIGHT || keycode == Input.Keys.DPAD_UP || keycode == Input.Keys.DPAD_DOWN)
|
||||
selectActor(back, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -140,20 +151,10 @@ public class PlayerStatisticScene extends UIScene {
|
||||
avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar()));
|
||||
}
|
||||
if (life != null) {
|
||||
AdventurePlayer.current().onLifeChange(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
life.setText(AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife());
|
||||
}
|
||||
});
|
||||
AdventurePlayer.current().onLifeChange(() -> life.setText(AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()));
|
||||
}
|
||||
if (money != null) {
|
||||
WorldSave.getCurrentSave().getPlayer().onGoldChange(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
money.setText(String.valueOf(AdventurePlayer.current().getGold()));
|
||||
}
|
||||
});
|
||||
WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText(String.valueOf(AdventurePlayer.current().getGold())));
|
||||
}
|
||||
if (totalWins != null) {
|
||||
totalWins.setText(Current.player().getStatistic().totalWins());
|
||||
@@ -193,6 +194,42 @@ public class PlayerStatisticScene extends UIScene {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
enemiesGroup = new Table(Controls.GetSkin());
|
||||
enemiesGroup.row();
|
||||
blessingScroll = Controls.newLabel("");
|
||||
blessingScroll.setStyle(new Label.LabelStyle(Controls.getBitmapFont("default"), Color.BLACK));
|
||||
blessingScroll.setAlignment(Align.topLeft);
|
||||
blessingScroll.setWrap(true);
|
||||
ui.onButtonPress("return", () -> PlayerStatisticScene.this.back());
|
||||
|
||||
avatar = ui.findActor("avatar");
|
||||
avatarBorder = ui.findActor("avatarBorder");
|
||||
playerName = ui.findActor("playerName");
|
||||
life = ui.findActor("lifePoints");
|
||||
money = ui.findActor("money");
|
||||
lifeIcon = ui.findActor("lifeIcon");
|
||||
goldIcon = ui.findActor("goldIcon");
|
||||
wins = ui.findActor("wins");
|
||||
colorFrame = ui.findActor("colorFrame");
|
||||
wins.setText(Forge.getLocalizer().getMessage("lblWinProper")+":");
|
||||
totalWins = ui.findActor("totalWins");
|
||||
loss = ui.findActor("loss");
|
||||
loss.setText(Forge.getLocalizer().getMessage("lblLossProper")+":");
|
||||
totalLoss = ui.findActor("totalLoss");
|
||||
winloss = ui.findActor("winloss");
|
||||
winloss.setText(Forge.getLocalizer().getMessage("lblWinProper")+"/"+Forge.getLocalizer().getMessage("lblLossProper"));
|
||||
lossWinRatio = ui.findActor("lossWinRatio");
|
||||
back = ui.findActor("return");
|
||||
back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
|
||||
scrollPane = ui.findActor("enemies");
|
||||
scrollPane.setActor(enemiesGroup);
|
||||
blessing = ui.findActor("blessingInfo");
|
||||
blessing.setActor(blessingScroll);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
|
||||
@@ -34,6 +34,7 @@ public class RewardScene extends UIScene {
|
||||
return object;
|
||||
}
|
||||
|
||||
private boolean showTooltips = false;
|
||||
public enum Type {
|
||||
Shop,
|
||||
Loot
|
||||
@@ -54,7 +55,7 @@ public class RewardScene extends UIScene {
|
||||
doneButton = ui.findActor("done");
|
||||
}
|
||||
|
||||
boolean doneClicked = false;
|
||||
boolean doneClicked = false, shown = false;
|
||||
float flipCountDown = 1.0f;
|
||||
float exitCountDown = 0.0f; //Serves as additional check for when scene is exiting, so you can't double tap too fast.
|
||||
|
||||
@@ -144,11 +145,91 @@ public class RewardScene extends UIScene {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
done();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_B || keycode == Input.Keys.BUTTON_START)
|
||||
showLootOrDone();
|
||||
else if (keycode == Input.Keys.BUTTON_A)
|
||||
performTouch(selectedActor);
|
||||
else if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
hideTooltips();
|
||||
selectNextActor(false);
|
||||
if (selectedActor != null && Type.Loot == type) {
|
||||
selectedActor.fire(eventEnter);
|
||||
}
|
||||
showHideTooltips();
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT) {
|
||||
hideTooltips();
|
||||
selectPreviousActor(false);
|
||||
if (selectedActor != null && Type.Loot == type) {
|
||||
selectedActor.fire(eventEnter);
|
||||
}
|
||||
showHideTooltips();
|
||||
} else if (keycode == Input.Keys.BUTTON_Y) {
|
||||
showTooltips = !showTooltips;
|
||||
showHideTooltips();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private void showHideTooltips() {
|
||||
if (selectedActor instanceof RewardActor) {
|
||||
if (showTooltips) {
|
||||
if (((RewardActor) selectedActor).isFlipped())
|
||||
((RewardActor) selectedActor).showTooltip();
|
||||
} else {
|
||||
((RewardActor) selectedActor).hideTooltip();
|
||||
}
|
||||
} else if (selectedActor instanceof BuyButton) {
|
||||
if (showTooltips)
|
||||
((BuyButton) selectedActor).reward.showTooltip();
|
||||
else
|
||||
((BuyButton) selectedActor).reward.hideTooltip();
|
||||
}
|
||||
}
|
||||
private void hideTooltips() {
|
||||
if (selectedActor instanceof RewardActor) {
|
||||
((RewardActor) selectedActor).hideTooltip();
|
||||
} else if (selectedActor instanceof BuyButton) {
|
||||
((BuyButton) selectedActor).reward.hideTooltip();
|
||||
}
|
||||
}
|
||||
private void showLootOrDone() {
|
||||
boolean exit = true;
|
||||
for (Actor actor : new Array.ArrayIterator<>(generated)) {
|
||||
if (!(actor instanceof RewardActor)) {
|
||||
continue;
|
||||
}
|
||||
RewardActor reward = (RewardActor) actor;
|
||||
if (!reward.isFlipped()) {
|
||||
exit = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exit)
|
||||
performTouch(doneButton);
|
||||
else if (type == Type.Loot && !shown) {
|
||||
shown = true;
|
||||
for (Actor actor : new Array.ArrayIterator<>(generated)) {
|
||||
if (!(actor instanceof RewardActor)) {
|
||||
continue;
|
||||
}
|
||||
RewardActor reward = (RewardActor) actor;
|
||||
AdventurePlayer.current().addReward(reward.getReward());
|
||||
if (!reward.isFlipped()) {
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
reward.flip();
|
||||
}
|
||||
}, 0.09f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
performTouch(doneButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void loadRewards(Array<Reward> newRewards, Type type, ShopActor shopActor) {
|
||||
clearActorObjects();
|
||||
this.type = type;
|
||||
doneClicked = false;
|
||||
for (Actor actor : new Array.ArrayIterator<>(generated)) {
|
||||
@@ -283,7 +364,10 @@ public class RewardScene extends UIScene {
|
||||
generated.add(buyCardButton);
|
||||
if (!skipCard) {
|
||||
stage.addActor(buyCardButton);
|
||||
addActorObject(buyCardButton);
|
||||
}
|
||||
} else {
|
||||
addActorObject(actor);
|
||||
}
|
||||
generated.add(actor);
|
||||
if (!skipCard) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package forge.adventure.scene;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
@@ -43,10 +44,10 @@ public class SaveLoadScene extends UIScene {
|
||||
Image previewImage;
|
||||
Label previewDate;
|
||||
Image previewBorder;
|
||||
TextButton saveLoadButton, back;
|
||||
TextButton quickSave;
|
||||
TextButton autoSave;
|
||||
TextButton saveLoadButton, back, quickSave, autoSave, dialogSaveBtn, dialogAbortBtn;
|
||||
Actor lastHighlightedSave;
|
||||
SelectBox difficulty;
|
||||
ScrollPane scrollPane;
|
||||
|
||||
private SaveLoadScene() {
|
||||
super(Forge.isLandscapeMode() ? "ui/save_load.json" : "ui/save_load_portrait.json");
|
||||
@@ -160,7 +161,7 @@ public class SaveLoadScene extends UIScene {
|
||||
previewImage.setVisible(true);
|
||||
previewDate.setVisible(true);
|
||||
if (header.saveDate != null)
|
||||
previewDate.setText(DateFormat.getDateInstance().format(header.saveDate)+"\n"+DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate));
|
||||
previewDate.setText(DateFormat.getDateInstance().format(header.saveDate) + "\n" + DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate));
|
||||
else
|
||||
previewDate.setText("");
|
||||
}
|
||||
@@ -176,6 +177,7 @@ public class SaveLoadScene extends UIScene {
|
||||
if (buttons.containsKey(slot)) {
|
||||
TextButton button = buttons.get(slot);
|
||||
button.setColor(Color.RED);
|
||||
selectActor(button, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -188,6 +190,7 @@ public class SaveLoadScene extends UIScene {
|
||||
//prevent NPE, allowed saveslot is 1 to 10..
|
||||
textInput.setText(buttons.get(currentSlot).getText().toString());
|
||||
dialog.show(stage);
|
||||
selectActor(textInput, false);
|
||||
stage.setKeyboardFocus(textInput);
|
||||
}
|
||||
break;
|
||||
@@ -228,7 +231,6 @@ public class SaveLoadScene extends UIScene {
|
||||
}
|
||||
|
||||
public boolean saveAbort() {
|
||||
|
||||
dialog.hide();
|
||||
return true;
|
||||
}
|
||||
@@ -238,6 +240,124 @@ public class SaveLoadScene extends UIScene {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
back();
|
||||
}
|
||||
if (kbVisible) {
|
||||
if (keycode == Input.Keys.BUTTON_START)
|
||||
keyOK();
|
||||
else if (keycode == Input.Keys.BUTTON_L1)
|
||||
toggleShiftOrBackspace(true);
|
||||
else if (keycode == Input.Keys.BUTTON_R1)
|
||||
toggleShiftOrBackspace(false);
|
||||
else if (keycode == Input.Keys.BUTTON_B)
|
||||
hideOnScreenKeyboard();
|
||||
else if (keycode == Input.Keys.BUTTON_A) {
|
||||
if (selectedKey != null)
|
||||
performTouch(selectedKey);
|
||||
} else if (keycode == Input.Keys.DPAD_UP || keycode == Input.Keys.DPAD_DOWN || keycode == Input.Keys.DPAD_LEFT || keycode == Input.Keys.DPAD_RIGHT)
|
||||
setSelectedKey(keycode);
|
||||
} else if (dialog.getColor().a != 0f) {
|
||||
if (keycode == Input.Keys.BUTTON_A) {
|
||||
if (selectedActor == textInput) {
|
||||
lastInputField = textInput;
|
||||
showOnScreenKeyboard(textInput.getText());
|
||||
} else if (selectedActor == dialogAbortBtn || selectedActor == dialogSaveBtn) {
|
||||
performTouch(selectedActor);
|
||||
if (lastSelectedSlot > 0)
|
||||
select(lastSelectedSlot);
|
||||
else
|
||||
select(-3);
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_B) {
|
||||
performTouch(dialogAbortBtn);
|
||||
if (lastSelectedSlot > 0)
|
||||
select(lastSelectedSlot);
|
||||
else
|
||||
select(-3);
|
||||
}
|
||||
else if (keycode == Input.Keys.DPAD_DOWN) {
|
||||
if (selectedActor == null) {
|
||||
selectActor(textInput, false);
|
||||
} else if (selectedActor == textInput)
|
||||
selectActor(dialogSaveBtn, false);
|
||||
} else if (keycode == Input.Keys.DPAD_UP) {
|
||||
if (selectedActor == null)
|
||||
selectActor(dialogSaveBtn, false);
|
||||
else if (selectedActor == dialogSaveBtn || selectedActor == dialogAbortBtn) {
|
||||
selectActor(textInput, false);
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT) {
|
||||
if (selectedActor == dialogAbortBtn)
|
||||
selectActor(dialogSaveBtn, false);
|
||||
} else if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
if (selectedActor == dialogSaveBtn)
|
||||
selectActor(dialogAbortBtn, false);
|
||||
}
|
||||
} else {
|
||||
if (keycode == Input.Keys.BUTTON_B)
|
||||
performTouch(back);
|
||||
else if (keycode == Input.Keys.BUTTON_Y) {
|
||||
if (difficulty != null && difficulty.isVisible()) {
|
||||
int index = difficulty.getSelectedIndex()-1;
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
difficulty.setSelectedIndex(index);
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_X) {
|
||||
if (difficulty != null && difficulty.isVisible()) {
|
||||
int index = difficulty.getSelectedIndex()+1;
|
||||
if (index >= 2)
|
||||
index = 2;
|
||||
difficulty.setSelectedIndex(index);
|
||||
}
|
||||
} else if (keycode == Input.Keys.BUTTON_L1) {
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
} else if (keycode == Input.Keys.BUTTON_R1) {
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
} else if (keycode == Input.Keys.BUTTON_A) {
|
||||
performTouch(selectedActor);
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT) {
|
||||
if (selectedActor == back || selectedActor == saveLoadButton) {
|
||||
if (lastHighlightedSave != null)
|
||||
selectActor(lastHighlightedSave, false);
|
||||
else
|
||||
selectActor(actorObjectMap.get(0), false);
|
||||
lastHighlightedSave = selectedActor;
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
if (!(selectedActor == back || selectedActor == saveLoadButton)) {
|
||||
lastHighlightedSave = selectedActor;
|
||||
selectActor(saveLoadButton, false);
|
||||
}
|
||||
} else if (keycode == Input.Keys.DPAD_DOWN) {
|
||||
int index = mode == Modes.Save ? 9 : 11;
|
||||
if (selectedActor == back)
|
||||
selectActor(saveLoadButton, false);
|
||||
else if (selectedActorIndex == index) {
|
||||
selectActor(actorObjectMap.get(0), false);
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
} else {
|
||||
selectNextActor(false);
|
||||
}
|
||||
if (selectedActorIndex == 6)
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
if (!(selectedActor == back || selectedActor == saveLoadButton))
|
||||
lastHighlightedSave = selectedActor;
|
||||
} else if (keycode == Input.Keys.DPAD_UP) {
|
||||
if (selectedActor == saveLoadButton)
|
||||
selectActor(back, false);
|
||||
else if (selectedActorIndex == 0) {
|
||||
selectActor(buttons.get(10), false);
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
} else {
|
||||
selectPreviousActor(false);
|
||||
}
|
||||
if (selectedActorIndex == 5)
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
if (!(selectedActor == back || selectedActor == saveLoadButton))
|
||||
lastHighlightedSave = selectedActor;
|
||||
} else if (keycode == Input.Keys.BUTTON_START) {
|
||||
performTouch(saveLoadButton);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -310,7 +430,7 @@ public class SaveLoadScene extends UIScene {
|
||||
saveLoadButton.setText(Forge.getLocalizer().getMessage("lblLoad"));
|
||||
break;
|
||||
case NewGamePlus:
|
||||
header.setText(Forge.getLocalizer().getMessage("lblNewGame")+"+");
|
||||
header.setText(Forge.getLocalizer().getMessage("lblNewGame") + "+");
|
||||
saveLoadButton.setText(Forge.getLocalizer().getMessage("lblStart"));
|
||||
break;
|
||||
}
|
||||
@@ -321,6 +441,8 @@ public class SaveLoadScene extends UIScene {
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
unselectActors();
|
||||
clearActorObjects();
|
||||
if (lastSelectedSlot > 0)
|
||||
select(lastSelectedSlot);
|
||||
else
|
||||
@@ -338,7 +460,95 @@ public class SaveLoadScene extends UIScene {
|
||||
difficulty.setVisible(false);
|
||||
}
|
||||
}
|
||||
if (!autoSave.isDisabled())
|
||||
addActorObject(autoSave);
|
||||
if (!quickSave.isDisabled())
|
||||
addActorObject(quickSave);
|
||||
for (int i=0; i <= 10; i++) {
|
||||
if (buttons.containsKey(i))
|
||||
addActorObject(buttons.get(i));
|
||||
}
|
||||
addActorObject(textInput);
|
||||
addActorObject(dialogSaveBtn);
|
||||
addActorObject(dialogAbortBtn);
|
||||
addActorObject(back);
|
||||
addActorObject(saveLoadButton);
|
||||
if (scrollPane != null) {
|
||||
if (lastSelectedSlot >= 6) {
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
selectActor(buttons.get(lastSelectedSlot), false);
|
||||
} else if (lastSelectedSlot > 0 && lastSelectedSlot < 6) {
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
selectActor(buttons.get(lastSelectedSlot), false);
|
||||
}
|
||||
}
|
||||
super.enter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
layout = new Table();
|
||||
stage.addActor(layout);
|
||||
dialog = Controls.newDialog(Forge.getLocalizer().getMessage("lblSave"));
|
||||
textInput = Controls.newTextField("");
|
||||
int c = 0;
|
||||
String[] diffList = new String[Config.instance().getConfigData().difficulties.length];
|
||||
for (DifficultyData diff : Config.instance().getConfigData().difficulties) {
|
||||
diffList[c] = diff.name;
|
||||
c++;
|
||||
}
|
||||
;
|
||||
|
||||
difficulty = Controls.newComboBox(diffList, null, o -> {
|
||||
//DifficultyData difficulty1 = Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()];
|
||||
return null;
|
||||
});
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblNameYourSaveFile"))).colspan(2).pad(2, 15, 2, 15);
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblName") + ": ")).align(Align.left).pad(2, 15, 2, 2);
|
||||
dialog.getButtonTable().add(textInput).fillX().expandX().padRight(15);
|
||||
dialog.getButtonTable().row();
|
||||
dialogSaveBtn = Controls.newTextButton(Forge.getLocalizer().getMessage("lblSave"), () -> SaveLoadScene.this.save());
|
||||
dialog.getButtonTable().add(dialogSaveBtn).align(Align.left).padLeft(15);
|
||||
dialogAbortBtn = Controls.newTextButton(Forge.getLocalizer().getMessage("lblAbort"), () -> SaveLoadScene.this.saveAbort());
|
||||
dialog.getButtonTable().add(dialogAbortBtn).align(Align.right).padRight(15);
|
||||
|
||||
//makes dialog hidden immediately when you open saveload scene..
|
||||
dialog.getColor().a = 0;
|
||||
dialog.hide();
|
||||
previewImage = ui.findActor("preview");
|
||||
previewDate = ui.findActor("saveDate");
|
||||
header = Controls.newLabel(Forge.getLocalizer().getMessage("lblSave"));
|
||||
header.setAlignment(Align.center);
|
||||
layout.add(header).pad(2).colspan(4).align(Align.center).expandX();
|
||||
layout.row();
|
||||
autoSave = addSaveSlot(Forge.getLocalizer().getMessage("lblAutoSave"), WorldSave.AUTO_SAVE_SLOT);
|
||||
quickSave = addSaveSlot(Forge.getLocalizer().getMessage("lblQuickSave"), WorldSave.QUICK_SAVE_SLOT);
|
||||
for (int i = 1; i < 11; i++)
|
||||
addSaveSlot(Forge.getLocalizer().getMessage("lblSlot") + ": " + i, i);
|
||||
|
||||
saveLoadButton = ui.findActor("save");
|
||||
saveLoadButton.getLabel().setText(Forge.getLocalizer().getMessage("lblSave"));
|
||||
ui.onButtonPress("save", () -> SaveLoadScene.this.loadSave());
|
||||
back = ui.findActor("return");
|
||||
back.getLabel().setText(Forge.getLocalizer().getMessage("lblBack"));
|
||||
ui.onButtonPress("return", () -> SaveLoadScene.this.back());
|
||||
|
||||
defColor = saveLoadButton.getColor();
|
||||
|
||||
scrollPane = ui.findActor("saveSlots");
|
||||
scrollPane.setActor(layout);
|
||||
ui.addActor(difficulty);
|
||||
difficulty.setSelectedIndex(1);
|
||||
difficulty.setAlignment(Align.center);
|
||||
difficulty.getStyle().fontColor = Color.GOLD;
|
||||
if (Forge.isLandscapeMode()) {
|
||||
difficulty.setX(280);
|
||||
difficulty.setY(220);
|
||||
} else {
|
||||
difficulty.setX(190);
|
||||
difficulty.setY(336);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,122 @@ public class SettingsScene extends UIScene {
|
||||
Texture Background;
|
||||
private Table settingGroup;
|
||||
TextButton back;
|
||||
ScrollPane scrollPane;
|
||||
|
||||
private SettingsScene() {
|
||||
|
||||
super(Forge.isLandscapeMode() ? "ui/settings.json" : "ui/settings_portrait.json");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (stage != null)
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
public void renderAct(float delta) {
|
||||
Gdx.gl.glClearColor(1, 0, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.getBatch().begin();
|
||||
stage.getBatch().disableBlending();
|
||||
stage.getBatch().draw(Background, 0, 0, getIntendedWidth(), getIntendedHeight());
|
||||
stage.getBatch().enableBlending();
|
||||
stage.getBatch().end();
|
||||
stage.act(delta);
|
||||
stage.draw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keycode) {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
back();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_B)
|
||||
performTouch(back);
|
||||
else if (keycode == Input.Keys.BUTTON_L1) {
|
||||
scrollPane.fling(1f, 0, -300);
|
||||
} else if (keycode == Input.Keys.BUTTON_R1) {
|
||||
scrollPane.fling(1f, 0, +300);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean back() {
|
||||
Forge.switchToLast();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addInputField(String name, ForgePreferences.FPref pref) {
|
||||
TextField box = Controls.newTextField("");
|
||||
box.setText(Preference.getPref(pref));
|
||||
box.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Preference.setPref(pref, ((TextField) actor).getText());
|
||||
Preference.save();
|
||||
}
|
||||
});
|
||||
|
||||
addLabel(name);
|
||||
settingGroup.add(box).align(Align.right);
|
||||
}
|
||||
|
||||
private void addCheckBox(String name, ForgePreferences.FPref pref) {
|
||||
CheckBox box = Controls.newCheckBox("");
|
||||
box.setChecked(Preference.getPrefBoolean(pref));
|
||||
box.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Preference.setPref(pref, ((CheckBox) actor).isChecked());
|
||||
Preference.save();
|
||||
}
|
||||
});
|
||||
|
||||
addLabel(name);
|
||||
settingGroup.add(box).align(Align.right);
|
||||
}
|
||||
|
||||
private void addSettingSlider(String name, ForgePreferences.FPref pref, int min, int max) {
|
||||
Slider slide = Controls.newSlider(min, max, 1, false);
|
||||
slide.setValue(Preference.getPrefInt(pref));
|
||||
slide.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Preference.setPref(pref, String.valueOf((int) ((Slider) actor).getValue()));
|
||||
Preference.save();
|
||||
}
|
||||
});
|
||||
addLabel(name);
|
||||
settingGroup.add(slide).align(Align.right);
|
||||
}
|
||||
|
||||
private void addSettingField(String name, boolean value, ChangeListener change) {
|
||||
CheckBox box = Controls.newCheckBox("");
|
||||
box.setChecked(value);
|
||||
box.addListener(change);
|
||||
addLabel(name);
|
||||
settingGroup.add(box).align(Align.right);
|
||||
}
|
||||
|
||||
private void addSettingField(String name, int value, ChangeListener change) {
|
||||
TextField text = Controls.newTextField(String.valueOf(value));
|
||||
text.setTextFieldFilter((textField, c) -> Character.isDigit(c));
|
||||
text.addListener(change);
|
||||
addLabel(name);
|
||||
settingGroup.add(text).align(Align.right);
|
||||
}
|
||||
|
||||
void addLabel(String name) {
|
||||
Label label = Controls.newLabel(name);
|
||||
label.setWrap(true);
|
||||
settingGroup.row().space(5);
|
||||
int w = Forge.isLandscapeMode() ? 160 : 80;
|
||||
settingGroup.add(label).align(Align.left).pad(2, 2, 2, 5).width(w).expand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resLoaded() {
|
||||
super.resLoaded();
|
||||
settingGroup = new Table();
|
||||
if (Preference == null) {
|
||||
Preference = new ForgePreferences();
|
||||
|
||||
@@ -23,7 +23,7 @@ public class StartScene extends UIScene {
|
||||
TextButton saveButton, resumeButton, continueButton, newGameButton, newGameButtonPlus, loadButton, settingsButton, exitButton, switchButton;
|
||||
Dialog dialog;
|
||||
|
||||
private StartScene() {
|
||||
public StartScene() {
|
||||
super(Forge.isLandscapeMode() ? "ui/start_menu.json" : "ui/start_menu_portrait.json");
|
||||
ui.onButtonPress("Start", () -> StartScene.this.NewGame());
|
||||
ui.onButtonPress("Start+", () -> NewGamePlus());
|
||||
@@ -59,19 +59,14 @@ public class StartScene extends UIScene {
|
||||
dialog = Controls.newDialog(Forge.getLocalizer().getMessage("lblExitForge"));
|
||||
dialog.getButtonTable().add(Controls.newLabel(Forge.getLocalizer().getMessage("lblAreYouSureYouWishExitForge"))).colspan(2).pad(2, 15, 2, 15);
|
||||
dialog.getButtonTable().row();
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblExit"), () -> Forge.exit(true))).width(60).align(Align.left).padLeft(15);
|
||||
dialog.getButtonTable().add(Controls.newTextButton(Forge.getLocalizer().getMessage("lblCancel"), () -> dialog.hide())).width(60).align(Align.right).padRight(15);
|
||||
dialogOk = Controls.newTextButton(Forge.getLocalizer().getMessage("lblExit"), () -> Forge.exit(true));
|
||||
dialogButtonSelected = dialogOk;
|
||||
dialog.getButtonTable().add(dialogOk).width(60).align(Align.left).padLeft(15);
|
||||
dialogCancel = Controls.newTextButton(Forge.getLocalizer().getMessage("lblCancel"), () -> dialog.hide());
|
||||
dialog.getButtonTable().add(dialogCancel).width(60).align(Align.right).padRight(15);
|
||||
dialog.getColor().a = 0;
|
||||
}
|
||||
|
||||
|
||||
private static StartScene object;
|
||||
|
||||
public static StartScene instance() {
|
||||
if(object==null)
|
||||
object=new StartScene();
|
||||
return object;
|
||||
}
|
||||
public boolean NewGame() {
|
||||
Forge.switchScene(NewGameScene.instance());
|
||||
return true;
|
||||
@@ -169,13 +164,213 @@ public class StartScene extends UIScene {
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keycode) {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
if (WorldSave.getCurrentSave().getWorld().getData() != null)
|
||||
Resume();
|
||||
if (Forge.hasGamepad())
|
||||
showGamepadSelector = true;
|
||||
if (dialog.getColor().a != 1) {
|
||||
if (keycode == Input.Keys.ESCAPE || keycode == Input.Keys.BACK) {
|
||||
if (WorldSave.getCurrentSave().getWorld().getData() != null) {
|
||||
if (showGamepadSelector)
|
||||
performTouch(resumeButton);
|
||||
else
|
||||
Resume();
|
||||
}
|
||||
}
|
||||
if (keycode == Input.Keys.DPAD_DOWN) {
|
||||
selected++;
|
||||
if (selected == 1 && Forge.isLandscapeMode())
|
||||
selected++;
|
||||
if (!saveButton.isVisible() && selected == 3)
|
||||
selected++;
|
||||
if (!resumeButton.isVisible() && selected == 4)
|
||||
selected++;
|
||||
if (!continueButton.isVisible() && selected == 5)
|
||||
selected++;
|
||||
if (selected > 7 && Forge.isLandscapeMode())
|
||||
selected = 0;
|
||||
if (selected > 8 && !Forge.isLandscapeMode())
|
||||
selected = 8;
|
||||
setSelected(selected, false);
|
||||
} else if (keycode == Input.Keys.DPAD_UP) {
|
||||
selected--;
|
||||
if (selected == 7 && Forge.isLandscapeMode())
|
||||
selected--;
|
||||
if (!continueButton.isVisible() && selected == 5)
|
||||
selected--;
|
||||
if (!resumeButton.isVisible() && selected == 4)
|
||||
selected--;
|
||||
if (!saveButton.isVisible() && selected == 3)
|
||||
selected--;
|
||||
if (selected == 1 && Forge.isLandscapeMode())
|
||||
selected--;
|
||||
if (selected < 0)
|
||||
selected = Forge.isLandscapeMode() ? 7 : 0;
|
||||
setSelected(selected, false);
|
||||
} else if (keycode == Input.Keys.DPAD_RIGHT && Forge.isLandscapeMode()) {
|
||||
if (selected == 0 || selected == 7)
|
||||
selected++;
|
||||
if (selected > 8)
|
||||
selected = 8;
|
||||
setSelected(selected, false);
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT && Forge.isLandscapeMode()) {
|
||||
if (selected == 1 || selected == 8)
|
||||
selected--;
|
||||
if (selected < 0)
|
||||
selected = 0;
|
||||
setSelected(selected, false);
|
||||
} else if (keycode == Input.Keys.BUTTON_A)
|
||||
setSelected(selected, true);
|
||||
} else {
|
||||
if (keycode == Input.Keys.DPAD_RIGHT) {
|
||||
dialogOk.fire(eventExit);
|
||||
dialogCancel.fire(eventEnter);
|
||||
dialogButtonSelected = dialogCancel;
|
||||
} else if (keycode == Input.Keys.DPAD_LEFT) {
|
||||
dialogOk.fire(eventEnter);
|
||||
dialogCancel.fire(eventExit);
|
||||
dialogButtonSelected = dialogOk;
|
||||
} else if (keycode == Input.Keys.BUTTON_A) {
|
||||
dialogOk.fire(eventExit);
|
||||
dialogCancel.fire(eventExit);
|
||||
performTouch(dialogButtonSelected);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setSelected(int select, boolean press) {
|
||||
if (!showGamepadSelector)
|
||||
return;
|
||||
unSelectAll();
|
||||
switch (select) {
|
||||
case 0:
|
||||
newGameButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(newGameButton);
|
||||
break;
|
||||
case 1:
|
||||
newGameButtonPlus.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(newGameButtonPlus);
|
||||
break;
|
||||
case 2:
|
||||
loadButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(loadButton);
|
||||
break;
|
||||
case 3:
|
||||
saveButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(saveButton);
|
||||
break;
|
||||
case 4:
|
||||
resumeButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(resumeButton);
|
||||
break;
|
||||
case 5:
|
||||
continueButton.fire(eventEnter);
|
||||
if (press) {
|
||||
performTouch(continueButton);
|
||||
setSelected(4, false);
|
||||
selected = 4;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
settingsButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(settingsButton);
|
||||
break;
|
||||
case 7:
|
||||
if (Forge.isLandscapeMode()) {
|
||||
exitButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(exitButton);
|
||||
} else {
|
||||
switchButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(switchButton);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (Forge.isLandscapeMode()) {
|
||||
switchButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(switchButton);
|
||||
} else {
|
||||
exitButton.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(exitButton);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void unSelectAll() {
|
||||
if (!showGamepadSelector)
|
||||
return;
|
||||
newGameButton.fire(eventExit);
|
||||
newGameButtonPlus.fire(eventExit);
|
||||
loadButton.fire(eventExit);
|
||||
saveButton.fire(eventExit);
|
||||
resumeButton.fire(eventExit);
|
||||
continueButton.fire(eventExit);
|
||||
settingsButton.fire(eventExit);
|
||||
exitButton.fire(eventExit);
|
||||
switchButton.fire(eventExit);
|
||||
dialogOk.fire(eventExit);
|
||||
dialogCancel.fire(eventExit);
|
||||
}
|
||||
private void updateSelected() {
|
||||
if (dialog.getColor().a == 1) {
|
||||
if (Controls.actorContainsVector(dialogOk, pointer)) {
|
||||
dialogCancel.fire(eventExit);
|
||||
dialogOk.fire(eventEnter);
|
||||
dialogButtonSelected = dialogOk;
|
||||
}
|
||||
if (Controls.actorContainsVector(dialogCancel, pointer)) {
|
||||
dialogOk.fire(eventExit);
|
||||
dialogCancel.fire(eventEnter);
|
||||
dialogButtonSelected = dialogCancel;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Controls.actorContainsVector(newGameButton, pointer)) {
|
||||
newGameButton.fire(eventEnter);
|
||||
selected = 0;
|
||||
}
|
||||
if (Controls.actorContainsVector(newGameButtonPlus, pointer)) {
|
||||
newGameButtonPlus.fire(eventEnter);
|
||||
selected = 1;
|
||||
}
|
||||
if (Controls.actorContainsVector(loadButton, pointer)) {
|
||||
loadButton.fire(eventEnter);
|
||||
selected = 2;
|
||||
}
|
||||
if (Controls.actorContainsVector(saveButton, pointer)) {
|
||||
saveButton.fire(eventEnter);
|
||||
selected = 3;
|
||||
}
|
||||
if (Controls.actorContainsVector(resumeButton, pointer)) {
|
||||
resumeButton.fire(eventEnter);
|
||||
selected = 4;
|
||||
}
|
||||
if (Controls.actorContainsVector(continueButton, pointer)) {
|
||||
continueButton.fire(eventEnter);
|
||||
selected = 5;
|
||||
}
|
||||
if (Controls.actorContainsVector(settingsButton, pointer)) {
|
||||
settingsButton.fire(eventEnter);
|
||||
selected = 6;
|
||||
}
|
||||
if (Controls.actorContainsVector(exitButton, pointer)) {
|
||||
exitButton.fire(eventEnter);
|
||||
selected = Forge.isLandscapeMode() ? 7 : 8;
|
||||
}
|
||||
if (Controls.actorContainsVector(switchButton, pointer)) {
|
||||
switchButton.fire(eventEnter);
|
||||
selected = Forge.isLandscapeMode() ? 8 : 7;
|
||||
}
|
||||
}
|
||||
|
||||
private void NewGamePlus() {
|
||||
SaveLoadScene.instance().setMode(SaveLoadScene.Modes.NewGamePlus);
|
||||
|
||||
@@ -1,39 +1,191 @@
|
||||
package forge.adventure.scene;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.Scaling;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
import com.badlogic.gdx.utils.viewport.ScalingViewport;
|
||||
import forge.Forge;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.util.Selector;
|
||||
import forge.adventure.util.UIActor;
|
||||
|
||||
/**
|
||||
* Base class for an GUI scene where the elements are loaded from a json file
|
||||
*/
|
||||
public class UIScene extends Scene {
|
||||
|
||||
protected UIActor ui;
|
||||
Stage stage;
|
||||
|
||||
String uiFile;
|
||||
private Dialog keyboardDialog;
|
||||
private Label kbLabel;
|
||||
private TextButton keyA, keyB, keyC, keyD, keyE, keyF, keyG, keyH, keyI, keyJ, keyK, keyL, keyM, keyN, keyO, keyP,
|
||||
keyQ, keyR, keyS, keyT, keyU, keyV, keyW, keyX, keyY, keyZ, key1, key2, key3, key4, key5, key6, key7, key8,
|
||||
key9, key0, keyDot, keyComma, keyShift, keyBackspace, keySpace, keyOK;
|
||||
public Actor lastInputField;
|
||||
public boolean showGamepadSelector = false, lowercaseKey = true, kbVisible=false;
|
||||
|
||||
protected UIScene(String uiFilePath) {
|
||||
public InputEvent eventEnter, eventExit, eventTouchDown, eventTouchUp;
|
||||
|
||||
public Vector2 pointer = new Vector2();
|
||||
public ObjectMap<Integer, Actor> actorObjectMap;
|
||||
public Actor selectedActor, selectedKey, lastSelectedKey;
|
||||
public int selectedActorIndex = 0;
|
||||
|
||||
public UIScene(String uiFilePath) {
|
||||
|
||||
uiFile = uiFilePath;
|
||||
stage = new Stage(new ScalingViewport(Scaling.stretch, getIntendedWidth(), getIntendedHeight())) {
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int keycode) {
|
||||
if (Forge.hasGamepad())
|
||||
return false;
|
||||
return keyPressed(keycode);
|
||||
}
|
||||
@Override
|
||||
public boolean keyDown(int keyCode) {
|
||||
if (!Forge.hasGamepad())
|
||||
return false;
|
||||
return keyPressed(keyCode);
|
||||
}
|
||||
@Override
|
||||
public boolean mouseMoved(int screenX, int screenY) {
|
||||
pointerMoved(screenX, screenY);
|
||||
return super.mouseMoved(screenX, screenY);
|
||||
}
|
||||
};
|
||||
ui = new UIActor(Config.instance().getFile(uiFile=uiFilePath));
|
||||
ui = new UIActor(Config.instance().getFile(uiFile));
|
||||
screenImage = ui.findActor("lastScreen");
|
||||
stage.addActor(ui);
|
||||
|
||||
eventTouchDown = new InputEvent();
|
||||
eventTouchDown.setPointer(-1);
|
||||
eventTouchDown.setType(InputEvent.Type.touchDown);
|
||||
eventTouchUp = new InputEvent();
|
||||
eventTouchUp.setPointer(-1);
|
||||
eventTouchUp.setType(InputEvent.Type.touchUp);
|
||||
eventEnter = new InputEvent();
|
||||
eventEnter.setPointer(-1);
|
||||
eventEnter.setType(InputEvent.Type.enter);
|
||||
eventExit = new InputEvent();
|
||||
eventExit.setPointer(-1);
|
||||
eventExit.setType(InputEvent.Type.exit);
|
||||
actorObjectMap = new ObjectMap<>();
|
||||
keyboardDialog = Controls.newDialog("");
|
||||
kbLabel = Controls.newLabel("");
|
||||
kbLabel.setAlignment(Align.center);
|
||||
kbLabel.setColor(Color.CYAN);
|
||||
kbLabel.setFontScale(1.5f,1.5f);
|
||||
keyA = Controls.newTextButton("A", () -> kbLabel.setText(kbLabel.getText()+transformKey("A")));
|
||||
keyB = Controls.newTextButton("B", () -> kbLabel.setText(kbLabel.getText()+transformKey("B")));
|
||||
keyC = Controls.newTextButton("C", () -> kbLabel.setText(kbLabel.getText()+transformKey("C")));
|
||||
keyD = Controls.newTextButton("D", () -> kbLabel.setText(kbLabel.getText()+transformKey("D")));
|
||||
keyE = Controls.newTextButton("E", () -> kbLabel.setText(kbLabel.getText()+transformKey("E")));
|
||||
keyF = Controls.newTextButton("F", () -> kbLabel.setText(kbLabel.getText()+transformKey("F")));
|
||||
keyG = Controls.newTextButton("G", () -> kbLabel.setText(kbLabel.getText()+transformKey("G")));
|
||||
keyH = Controls.newTextButton("H", () -> kbLabel.setText(kbLabel.getText()+transformKey("H")));
|
||||
keyI = Controls.newTextButton("I", () -> kbLabel.setText(kbLabel.getText()+transformKey("I")));
|
||||
keyJ = Controls.newTextButton("J", () -> kbLabel.setText(kbLabel.getText()+transformKey("J")));
|
||||
keyK = Controls.newTextButton("K", () -> kbLabel.setText(kbLabel.getText()+transformKey("K")));
|
||||
keyL = Controls.newTextButton("L", () -> kbLabel.setText(kbLabel.getText()+transformKey("L")));
|
||||
keyM = Controls.newTextButton("M", () -> kbLabel.setText(kbLabel.getText()+transformKey("M")));
|
||||
keyN = Controls.newTextButton("N", () -> kbLabel.setText(kbLabel.getText()+transformKey("N")));
|
||||
keyO = Controls.newTextButton("O", () -> kbLabel.setText(kbLabel.getText()+transformKey("O")));
|
||||
keyP = Controls.newTextButton("P", () -> kbLabel.setText(kbLabel.getText()+transformKey("P")));
|
||||
keyQ = Controls.newTextButton("Q", () -> kbLabel.setText(kbLabel.getText()+transformKey("Q")));
|
||||
keyR = Controls.newTextButton("R", () -> kbLabel.setText(kbLabel.getText()+transformKey("R")));
|
||||
keyS = Controls.newTextButton("S", () -> kbLabel.setText(kbLabel.getText()+transformKey("S")));
|
||||
keyT = Controls.newTextButton("T", () -> kbLabel.setText(kbLabel.getText()+transformKey("T")));
|
||||
keyU = Controls.newTextButton("U", () -> kbLabel.setText(kbLabel.getText()+transformKey("U")));
|
||||
keyV = Controls.newTextButton("V", () -> kbLabel.setText(kbLabel.getText()+transformKey("V")));
|
||||
keyW = Controls.newTextButton("W", () -> kbLabel.setText(kbLabel.getText()+transformKey("W")));
|
||||
keyX = Controls.newTextButton("X", () -> kbLabel.setText(kbLabel.getText()+transformKey("X")));
|
||||
keyY = Controls.newTextButton("Y", () -> kbLabel.setText(kbLabel.getText()+transformKey("Y")));
|
||||
keyZ = Controls.newTextButton("Z", () -> kbLabel.setText(kbLabel.getText()+transformKey("Z")));
|
||||
key1 = Controls.newTextButton("1", () -> kbLabel.setText(kbLabel.getText()+"1"));
|
||||
key2 = Controls.newTextButton("2", () -> kbLabel.setText(kbLabel.getText()+"2"));
|
||||
key3 = Controls.newTextButton("3", () -> kbLabel.setText(kbLabel.getText()+"3"));
|
||||
key4 = Controls.newTextButton("4", () -> kbLabel.setText(kbLabel.getText()+"4"));
|
||||
key5 = Controls.newTextButton("5", () -> kbLabel.setText(kbLabel.getText()+"5"));
|
||||
key6 = Controls.newTextButton("6", () -> kbLabel.setText(kbLabel.getText()+"6"));
|
||||
key7 = Controls.newTextButton("7", () -> kbLabel.setText(kbLabel.getText()+"7"));
|
||||
key8 = Controls.newTextButton("8", () -> kbLabel.setText(kbLabel.getText()+"8"));
|
||||
key9 = Controls.newTextButton("9", () -> kbLabel.setText(kbLabel.getText()+"9"));
|
||||
key0 = Controls.newTextButton("0", () -> kbLabel.setText(kbLabel.getText()+"0"));
|
||||
keyDot = Controls.newTextButton(".", () -> kbLabel.setText(kbLabel.getText()+"."));
|
||||
keyComma = Controls.newTextButton(",", () -> kbLabel.setText(kbLabel.getText()+","));
|
||||
keyShift = Controls.newTextButton("Aa", () -> shiftKey());
|
||||
keyBackspace = Controls.newTextButton("<<", () -> kbLabel.setText(removeLastChar(String.valueOf(kbLabel.getText()))));
|
||||
keySpace = Controls.newTextButton("SPACE", () -> kbLabel.setText(kbLabel.getText()+" "));
|
||||
keyOK = Controls.newTextButton("OK", () -> setKeyboardDialogText());
|
||||
keyboardDialog.getContentTable().add(kbLabel).width(220).height(20).colspan(10).expandX().align(Align.center);
|
||||
keyboardDialog.getButtonTable().row();
|
||||
keyboardDialog.getButtonTable().add(key1).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key2).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key3).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key4).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key5).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key6).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key7).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key8).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key9).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(key0).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().row();
|
||||
keyboardDialog.getButtonTable().add(keyQ).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyW).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyE).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyR).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyT).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyY).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyU).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyI).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyO).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyP).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().row();
|
||||
keyboardDialog.getButtonTable().add(keyA).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyS).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyD).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyF).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyG).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyH).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyJ).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyK).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyL).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyBackspace).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().row();
|
||||
keyboardDialog.getButtonTable().add(keyShift).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyZ).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyX).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyC).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyV).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyB).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyN).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyM).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyDot).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().add(keyComma).width(20).height(20);
|
||||
keyboardDialog.getButtonTable().row();
|
||||
keyboardDialog.getButtonTable().add(keySpace).width(150).height(20).colspan(6);
|
||||
keyboardDialog.getButtonTable().add(keyOK).width(100).height(20).colspan(4);
|
||||
keyboardDialog.setKeepWithinStage(true);
|
||||
keyboardDialog.setResizable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,32 +214,531 @@ public class UIScene extends Scene {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean pointerMoved(int screenX, int screenY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void performTouch(Actor actor) {
|
||||
if (actor == null)
|
||||
return;
|
||||
actor.fire(eventTouchDown);
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
actor.fire(eventTouchUp);
|
||||
}
|
||||
}, 0.10f);
|
||||
}
|
||||
|
||||
private String transformKey(String c) {
|
||||
return lowercaseKey ? c.toLowerCase() : c.toUpperCase();
|
||||
}
|
||||
public void toggleShiftOrBackspace(boolean shift) {
|
||||
if (shift)
|
||||
performTouch(keyShift);
|
||||
else
|
||||
performTouch(keyBackspace);
|
||||
}
|
||||
public void hideOnScreenKeyboard() {
|
||||
kbVisible = false;
|
||||
keyboardDialog.hide();
|
||||
selectedActor = lastInputField;
|
||||
}
|
||||
private void shiftKey() {
|
||||
lowercaseKey = !lowercaseKey;
|
||||
keyShift.getLabel().setColor(lowercaseKey ? Color.WHITE : Color.CYAN);
|
||||
keyA.getLabel().setText(lowercaseKey ? "a" : "A");
|
||||
keyB.getLabel().setText(lowercaseKey ? "b" : "B");
|
||||
keyC.getLabel().setText(lowercaseKey ? "c" : "C");
|
||||
keyD.getLabel().setText(lowercaseKey ? "d" : "D");
|
||||
keyE.getLabel().setText(lowercaseKey ? "e" : "E");
|
||||
keyF.getLabel().setText(lowercaseKey ? "f" : "F");
|
||||
keyG.getLabel().setText(lowercaseKey ? "g" : "G");
|
||||
keyH.getLabel().setText(lowercaseKey ? "h" : "H");
|
||||
keyI.getLabel().setText(lowercaseKey ? "i" : "I");
|
||||
keyJ.getLabel().setText(lowercaseKey ? "j" : "J");
|
||||
keyK.getLabel().setText(lowercaseKey ? "k" : "K");
|
||||
keyL.getLabel().setText(lowercaseKey ? "l" : "L");
|
||||
keyM.getLabel().setText(lowercaseKey ? "m" : "M");
|
||||
keyN.getLabel().setText(lowercaseKey ? "n" : "N");
|
||||
keyO.getLabel().setText(lowercaseKey ? "o" : "O");
|
||||
keyP.getLabel().setText(lowercaseKey ? "p" : "P");
|
||||
keyQ.getLabel().setText(lowercaseKey ? "q" : "Q");
|
||||
keyR.getLabel().setText(lowercaseKey ? "r" : "R");
|
||||
keyS.getLabel().setText(lowercaseKey ? "s" : "S");
|
||||
keyT.getLabel().setText(lowercaseKey ? "t" : "T");
|
||||
keyU.getLabel().setText(lowercaseKey ? "u" : "U");
|
||||
keyV.getLabel().setText(lowercaseKey ? "v" : "V");
|
||||
keyW.getLabel().setText(lowercaseKey ? "w" : "W");
|
||||
keyX.getLabel().setText(lowercaseKey ? "x" : "X");
|
||||
keyY.getLabel().setText(lowercaseKey ? "y" : "Y");
|
||||
keyZ.getLabel().setText(lowercaseKey ? "z" : "Z");
|
||||
}
|
||||
public void setSelectedKey(int keyCode) {
|
||||
switch(keyCode) {
|
||||
case Input.Keys.DPAD_DOWN:
|
||||
if (selectedKey == null)
|
||||
selectActor(key1, false);
|
||||
else if (selectedKey == key1)
|
||||
selectActor(keyQ, false);
|
||||
else if (selectedKey == keyQ)
|
||||
selectActor(keyA, false);
|
||||
else if (selectedKey == keyA)
|
||||
selectActor(keyShift, false);
|
||||
else if (selectedKey == keyShift)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key2)
|
||||
selectActor(keyW, false);
|
||||
else if (selectedKey == keyW)
|
||||
selectActor(keyS, false);
|
||||
else if (selectedKey == keyS)
|
||||
selectActor(keyZ, false);
|
||||
else if (selectedKey == keyZ)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key3)
|
||||
selectActor(keyE, false);
|
||||
else if (selectedKey == keyE)
|
||||
selectActor(keyD, false);
|
||||
else if (selectedKey == keyD)
|
||||
selectActor(keyX, false);
|
||||
else if (selectedKey == keyX)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key4)
|
||||
selectActor(keyR, false);
|
||||
else if (selectedKey == keyR)
|
||||
selectActor(keyF, false);
|
||||
else if (selectedKey == keyF)
|
||||
selectActor(keyC, false);
|
||||
else if (selectedKey == keyC)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key5)
|
||||
selectActor(keyT, false);
|
||||
else if (selectedKey == keyT)
|
||||
selectActor(keyG, false);
|
||||
else if (selectedKey == keyG)
|
||||
selectActor(keyV, false);
|
||||
else if (selectedKey == keyV)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key6)
|
||||
selectActor(keyY, false);
|
||||
else if (selectedKey == keyY)
|
||||
selectActor(keyH, false);
|
||||
else if (selectedKey == keyH)
|
||||
selectActor(keyB, false);
|
||||
else if (selectedKey == keyB)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == key7)
|
||||
selectActor(keyU, false);
|
||||
else if (selectedKey == keyU)
|
||||
selectActor(keyJ, false);
|
||||
else if (selectedKey == keyJ)
|
||||
selectActor(keyN, false);
|
||||
else if (selectedKey == keyN)
|
||||
selectActor(keyOK, false);
|
||||
else if (selectedKey == key8)
|
||||
selectActor(keyI, false);
|
||||
else if (selectedKey == keyI)
|
||||
selectActor(keyK, false);
|
||||
else if (selectedKey == keyK)
|
||||
selectActor(keyM, false);
|
||||
else if (selectedKey == keyM)
|
||||
selectActor(keyOK, false);
|
||||
else if (selectedKey == key9)
|
||||
selectActor(keyO, false);
|
||||
else if (selectedKey == keyO)
|
||||
selectActor(keyL, false);
|
||||
else if (selectedKey == keyL)
|
||||
selectActor(keyDot, false);
|
||||
else if (selectedKey == keyDot)
|
||||
selectActor(keyOK, false);
|
||||
else if (selectedKey == key0)
|
||||
selectActor(keyP, false);
|
||||
else if (selectedKey == keyP)
|
||||
selectActor(keyBackspace, false);
|
||||
else if (selectedKey == keyBackspace)
|
||||
selectActor(keyComma, false);
|
||||
else if (selectedKey == keyComma)
|
||||
selectActor(keyOK, false);
|
||||
break;
|
||||
case Input.Keys.DPAD_UP:
|
||||
if (selectedKey == null)
|
||||
selectActor(key1, false);
|
||||
else if (selectedKey == keySpace || selectedKey == keyOK)
|
||||
selectActor(lastSelectedKey, false);
|
||||
else if (selectedKey == keyShift)
|
||||
selectActor(keyA, false);
|
||||
else if (selectedKey == keyA)
|
||||
selectActor(keyQ, false);
|
||||
else if (selectedKey == keyQ)
|
||||
selectActor(key1, false);
|
||||
else if (selectedKey == keyZ)
|
||||
selectActor(keyS, false);
|
||||
else if (selectedKey == keyS)
|
||||
selectActor(keyW, false);
|
||||
else if (selectedKey == keyW)
|
||||
selectActor(key2, false);
|
||||
else if (selectedKey == keyX)
|
||||
selectActor(keyD, false);
|
||||
else if (selectedKey == keyD)
|
||||
selectActor(keyE, false);
|
||||
else if (selectedKey == keyE)
|
||||
selectActor(key3, false);
|
||||
else if (selectedKey == keyC)
|
||||
selectActor(keyF, false);
|
||||
else if (selectedKey == keyF)
|
||||
selectActor(keyR, false);
|
||||
else if (selectedKey == keyR)
|
||||
selectActor(key4, false);
|
||||
else if (selectedKey == keyV)
|
||||
selectActor(keyG, false);
|
||||
else if (selectedKey == keyG)
|
||||
selectActor(keyT, false);
|
||||
else if (selectedKey == keyT)
|
||||
selectActor(key5, false);
|
||||
else if (selectedKey == keyB)
|
||||
selectActor(keyH, false);
|
||||
else if (selectedKey == keyH)
|
||||
selectActor(keyY, false);
|
||||
else if (selectedKey == keyY)
|
||||
selectActor(key6, false);
|
||||
else if (selectedKey == keyN)
|
||||
selectActor(keyJ, false);
|
||||
else if (selectedKey == keyJ)
|
||||
selectActor(keyU, false);
|
||||
else if (selectedKey == keyU)
|
||||
selectActor(key7, false);
|
||||
else if (selectedKey == keyM)
|
||||
selectActor(keyK, false);
|
||||
else if (selectedKey == keyK)
|
||||
selectActor(keyI, false);
|
||||
else if (selectedKey == keyI)
|
||||
selectActor(key8, false);
|
||||
else if (selectedKey == keyDot)
|
||||
selectActor(keyL, false);
|
||||
else if (selectedKey == keyL)
|
||||
selectActor(keyO, false);
|
||||
else if (selectedKey == keyO)
|
||||
selectActor(key9, false);
|
||||
else if (selectedKey == keyComma)
|
||||
selectActor(keyBackspace, false);
|
||||
else if (selectedKey == keyBackspace)
|
||||
selectActor(keyP, false);
|
||||
else if (selectedKey == keyP)
|
||||
selectActor(key0, false);
|
||||
break;
|
||||
case Input.Keys.DPAD_LEFT:
|
||||
if (selectedKey == null)
|
||||
selectActor(key1, false);
|
||||
else if (selectedKey == keyOK)
|
||||
selectActor(keySpace, false);
|
||||
else if (selectedKey == keyComma)
|
||||
selectActor(keyDot, false);
|
||||
else if (selectedKey == keyDot)
|
||||
selectActor(keyM, false);
|
||||
else if (selectedKey == keyM)
|
||||
selectActor(keyN, false);
|
||||
else if (selectedKey == keyN)
|
||||
selectActor(keyB, false);
|
||||
else if (selectedKey == keyB)
|
||||
selectActor(keyV, false);
|
||||
else if (selectedKey == keyV)
|
||||
selectActor(keyC, false);
|
||||
else if (selectedKey == keyC)
|
||||
selectActor(keyX, false);
|
||||
else if (selectedKey == keyX)
|
||||
selectActor(keyZ, false);
|
||||
else if (selectedKey == keyZ)
|
||||
selectActor(keyShift, false);
|
||||
else if (selectedKey == keyBackspace)
|
||||
selectActor(keyL, false);
|
||||
else if (selectedKey == keyL)
|
||||
selectActor(keyK, false);
|
||||
else if (selectedKey == keyK)
|
||||
selectActor(keyJ, false);
|
||||
else if (selectedKey == keyJ)
|
||||
selectActor(keyH, false);
|
||||
else if (selectedKey == keyH)
|
||||
selectActor(keyG, false);
|
||||
else if (selectedKey == keyG)
|
||||
selectActor(keyF, false);
|
||||
else if (selectedKey == keyF)
|
||||
selectActor(keyD, false);
|
||||
else if (selectedKey == keyD)
|
||||
selectActor(keyS, false);
|
||||
else if (selectedKey == keyS)
|
||||
selectActor(keyA, false);
|
||||
else if (selectedKey == keyP)
|
||||
selectActor(keyO, false);
|
||||
else if (selectedKey == keyO)
|
||||
selectActor(keyI, false);
|
||||
else if (selectedKey == keyI)
|
||||
selectActor(keyU, false);
|
||||
else if (selectedKey == keyU)
|
||||
selectActor(keyY, false);
|
||||
else if (selectedKey == keyY)
|
||||
selectActor(keyT, false);
|
||||
else if (selectedKey == keyT)
|
||||
selectActor(keyR, false);
|
||||
else if (selectedKey == keyR)
|
||||
selectActor(keyE, false);
|
||||
else if (selectedKey == keyE)
|
||||
selectActor(keyW, false);
|
||||
else if (selectedKey == keyW)
|
||||
selectActor(keyQ, false);
|
||||
else if (selectedKey == key0)
|
||||
selectActor(key9, false);
|
||||
else if (selectedKey == key9)
|
||||
selectActor(key8, false);
|
||||
else if (selectedKey == key8)
|
||||
selectActor(key7, false);
|
||||
else if (selectedKey == key7)
|
||||
selectActor(key6, false);
|
||||
else if (selectedKey == key6)
|
||||
selectActor(key5, false);
|
||||
else if (selectedKey == key5)
|
||||
selectActor(key4, false);
|
||||
else if (selectedKey == key4)
|
||||
selectActor(key3, false);
|
||||
else if (selectedKey == key3)
|
||||
selectActor(key2, false);
|
||||
else if (selectedKey == key2)
|
||||
selectActor(key1, false);
|
||||
break;
|
||||
case Input.Keys.DPAD_RIGHT:
|
||||
if (selectedKey == null)
|
||||
selectActor(key1, false);
|
||||
else if (selectedKey == key1)
|
||||
selectActor(key2, false);
|
||||
else if (selectedKey == key2)
|
||||
selectActor(key3, false);
|
||||
else if (selectedKey == key3)
|
||||
selectActor(key4, false);
|
||||
else if (selectedKey == key4)
|
||||
selectActor(key5, false);
|
||||
else if (selectedKey == key5)
|
||||
selectActor(key6, false);
|
||||
else if (selectedKey == key6)
|
||||
selectActor(key7, false);
|
||||
else if (selectedKey == key7)
|
||||
selectActor(key8, false);
|
||||
else if (selectedKey == key8)
|
||||
selectActor(key9, false);
|
||||
else if (selectedKey == key9)
|
||||
selectActor(key0, false);
|
||||
else if (selectedKey == keyQ)
|
||||
selectActor(keyW, false);
|
||||
else if (selectedKey == keyW)
|
||||
selectActor(keyE, false);
|
||||
else if (selectedKey == keyE)
|
||||
selectActor(keyR, false);
|
||||
else if (selectedKey == keyR)
|
||||
selectActor(keyT, false);
|
||||
else if (selectedKey == keyT)
|
||||
selectActor(keyY, false);
|
||||
else if (selectedKey == keyY)
|
||||
selectActor(keyU, false);
|
||||
else if (selectedKey == keyU)
|
||||
selectActor(keyI, false);
|
||||
else if (selectedKey == keyI)
|
||||
selectActor(keyO, false);
|
||||
else if (selectedKey == keyO)
|
||||
selectActor(keyP, false);
|
||||
else if (selectedKey == keyA)
|
||||
selectActor(keyS, false);
|
||||
else if (selectedKey == keyS)
|
||||
selectActor(keyD, false);
|
||||
else if (selectedKey == keyD)
|
||||
selectActor(keyF, false);
|
||||
else if (selectedKey == keyF)
|
||||
selectActor(keyG, false);
|
||||
else if (selectedKey == keyG)
|
||||
selectActor(keyH, false);
|
||||
else if (selectedKey == keyH)
|
||||
selectActor(keyJ, false);
|
||||
else if (selectedKey == keyJ)
|
||||
selectActor(keyK, false);
|
||||
else if (selectedKey == keyK)
|
||||
selectActor(keyL, false);
|
||||
else if (selectedKey == keyL)
|
||||
selectActor(keyBackspace, false);
|
||||
else if (selectedKey == keyShift)
|
||||
selectActor(keyZ, false);
|
||||
else if (selectedKey == keyZ)
|
||||
selectActor(keyX, false);
|
||||
else if (selectedKey == keyX)
|
||||
selectActor(keyC, false);
|
||||
else if (selectedKey == keyC)
|
||||
selectActor(keyV, false);
|
||||
else if (selectedKey == keyV)
|
||||
selectActor(keyB, false);
|
||||
else if (selectedKey == keyB)
|
||||
selectActor(keyN, false);
|
||||
else if (selectedKey == keyN)
|
||||
selectActor(keyM, false);
|
||||
else if (selectedKey == keyM)
|
||||
selectActor(keyDot, false);
|
||||
else if (selectedKey == keyDot)
|
||||
selectActor(keyComma, false);
|
||||
else if (selectedKey == keySpace)
|
||||
selectActor(keyOK, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private String removeLastChar(String s) {
|
||||
return (s == null || s.length() == 0)
|
||||
? ""
|
||||
: (s.substring(0, s.length() - 1));
|
||||
}
|
||||
private void setKeyboardDialogText() {
|
||||
if (lastInputField == null)
|
||||
return;
|
||||
if (lastInputField instanceof TextField) {
|
||||
if (!kbLabel.getText().isEmpty()) {
|
||||
((TextField) lastInputField).setText(String.valueOf(kbLabel.getText()));
|
||||
kbLabel.setText("");
|
||||
}
|
||||
}
|
||||
kbVisible = false;
|
||||
keyboardDialog.hide();
|
||||
selectActor(lastInputField, false);
|
||||
}
|
||||
public void showOnScreenKeyboard(String text) {
|
||||
kbVisible = true;
|
||||
if (lowercaseKey)
|
||||
shiftKey();
|
||||
kbLabel.setText(text);
|
||||
keyboardDialog.show(stage);
|
||||
selectActor(key1, false);
|
||||
}
|
||||
public void keyOK() {
|
||||
selectActor(keyOK, false);
|
||||
}
|
||||
|
||||
public void clearActorObjects() {
|
||||
actorObjectMap.clear();
|
||||
selectedActor = null;
|
||||
}
|
||||
public void addActorObject(Actor actor) {
|
||||
int index = actorObjectMap.size;
|
||||
actorObjectMap.put(index, actor);
|
||||
}
|
||||
public void unselectActors() {
|
||||
if (actorObjectMap.isEmpty())
|
||||
return;
|
||||
for (Actor actor : actorObjectMap.values()) {
|
||||
if (actor != null) {
|
||||
if (actor instanceof TextButton)
|
||||
((TextButton) actor).fire(eventExit);
|
||||
else if (actor instanceof Selector)
|
||||
((Selector) actor).getLabel().fire(eventExit);
|
||||
else if (actor instanceof TextField) {
|
||||
if (stage.getKeyboardFocus() == actor)
|
||||
stage.setKeyboardFocus(null);
|
||||
} else if (actor instanceof ImageButton) {
|
||||
((ImageButton) actor).setChecked(false);
|
||||
} else {
|
||||
actor.fire(eventExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void selectNextActor(boolean press) {
|
||||
if (actorObjectMap.isEmpty())
|
||||
return;
|
||||
if (selectedActor == null) {
|
||||
selectActor(actorObjectMap.get(0), press);
|
||||
} else {
|
||||
selectActor(actorObjectMap.get(selectedActorIndex+1), press);
|
||||
}
|
||||
}
|
||||
public void selectPreviousActor(boolean press) {
|
||||
if (actorObjectMap.isEmpty())
|
||||
return;
|
||||
if (selectedActor == null) {
|
||||
selectActor(actorObjectMap.get(0), press);
|
||||
} else {
|
||||
selectActor(actorObjectMap.get(selectedActorIndex-1), press);
|
||||
}
|
||||
}
|
||||
public void selectActor(Actor actor, boolean press) {
|
||||
if (actor == null)
|
||||
return;
|
||||
if (kbVisible) {
|
||||
if (selectedKey != null) {
|
||||
selectedKey.fire(eventExit);
|
||||
if (selectedKey instanceof TextButton)
|
||||
if (!(((TextButton) selectedKey) == keyOK || ((TextButton) selectedKey) == keySpace))
|
||||
lastSelectedKey = selectedKey;
|
||||
}
|
||||
selectedKey = actor;
|
||||
selectedKey.fire(eventEnter);
|
||||
if (press)
|
||||
performTouch(selectedKey);
|
||||
} else {
|
||||
unselectActors();
|
||||
if (actorObjectMap.isEmpty())
|
||||
return;
|
||||
Integer key = actorObjectMap.findKey(actor, true);
|
||||
if (key == null)
|
||||
return;
|
||||
Actor a = actorObjectMap.get(key);
|
||||
if (a != null) {
|
||||
if (a instanceof TextButton)
|
||||
((TextButton) a).fire(eventEnter);
|
||||
else if (a instanceof Selector)
|
||||
((Selector) a).getLabel().fire(eventEnter);
|
||||
else if (a instanceof TextField) {
|
||||
stage.setKeyboardFocus(a);
|
||||
} else if (a instanceof ImageButton) {
|
||||
((ImageButton) a).setChecked(true);
|
||||
}
|
||||
selectedActor = a;
|
||||
selectedActorIndex = key;
|
||||
if (press)
|
||||
performTouch(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void selectCurrent() {
|
||||
Actor current = actorObjectMap.get(selectedActorIndex);
|
||||
if (current == null)
|
||||
current = actorObjectMap.get(0);
|
||||
selectActor(current, false);
|
||||
}
|
||||
public void updateHovered() {
|
||||
for (Actor a : actorObjectMap.values()) {
|
||||
if (a != null && Controls.actorContainsVector(a, pointer)) {
|
||||
selectActor(a, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image screenImage;
|
||||
TextureRegion backgroundTexture;
|
||||
TextureRegion market, tavern;
|
||||
|
||||
@Override
|
||||
public void enter() {
|
||||
|
||||
if (screenImage != null) {
|
||||
if (backgroundTexture != null)
|
||||
backgroundTexture.getTexture().dispose();
|
||||
|
||||
final Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
final Pixmap potPixmap = new Pixmap(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), Pixmap.Format.RGBA8888);
|
||||
potPixmap.setBlending(Pixmap.Blending.SourceOver);
|
||||
potPixmap.drawPixmap(pixmap, 0, 0);
|
||||
potPixmap.setColor(0, 0, 0, 0.75f);
|
||||
potPixmap.fillRectangle(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
backgroundTexture = new TextureRegion(new Texture(potPixmap), 0, Gdx.graphics.getHeight(), Gdx.graphics.getWidth(), -Gdx.graphics.getHeight());
|
||||
screenImage.setDrawable(new TextureRegionDrawable(backgroundTexture));
|
||||
pixmap.dispose();
|
||||
potPixmap.dispose();
|
||||
//create from lastPreview from header...
|
||||
try {
|
||||
backgroundTexture = new TextureRegion(Forge.lastPreview);
|
||||
backgroundTexture.flip(false, true);
|
||||
screenImage.setDrawable(new TextureRegionDrawable(backgroundTexture));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
|
||||
super.enter();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean leave() {
|
||||
clearActorObjects();
|
||||
selectedActor = null;
|
||||
return super.leave();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,18 +10,17 @@ import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Scaling;
|
||||
import com.badlogic.gdx.utils.viewport.ScalingViewport;
|
||||
import forge.Forge;
|
||||
import forge.adventure.player.AdventurePlayer;
|
||||
import forge.adventure.scene.*;
|
||||
import forge.adventure.scene.Scene;
|
||||
import forge.adventure.scene.SceneType;
|
||||
import forge.adventure.util.Config;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.util.Current;
|
||||
@@ -121,12 +120,14 @@ public class GameHUD extends Stage {
|
||||
avatarborder.addListener(new ConsoleToggleListener());
|
||||
gamehud.addListener(new ConsoleToggleListener());
|
||||
}
|
||||
WorldSave.getCurrentSave().onLoad(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GameHUD.this.enter();
|
||||
}
|
||||
});
|
||||
WorldSave.getCurrentSave().onLoad(() -> GameHUD.this.enter());
|
||||
eventTouchDown = new InputEvent();
|
||||
eventTouchDown.setPointer(-1);
|
||||
eventTouchDown.setType(InputEvent.Type.touchDown);
|
||||
eventTouchUp = new InputEvent();
|
||||
eventTouchUp.setPointer(-1);
|
||||
eventTouchUp.setType(InputEvent.Type.touchUp);
|
||||
Controllers.addListener(this);
|
||||
}
|
||||
|
||||
private void openMap() {
|
||||
@@ -317,8 +318,31 @@ public class GameHUD extends Stage {
|
||||
showButtons();
|
||||
}
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_B) {
|
||||
performTouch(statsActor);
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_Y) {
|
||||
performTouch(inventoryActor);
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_X) {
|
||||
performTouch(deckActor);
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_A) {
|
||||
performTouch(menuActor);
|
||||
}
|
||||
return super.keyDown(keycode);
|
||||
}
|
||||
public void performTouch(Actor actor) {
|
||||
if (actor == null)
|
||||
return;
|
||||
actor.fire(eventTouchDown);
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
actor.fire(eventTouchUp);
|
||||
}
|
||||
}, 0.10f);
|
||||
}
|
||||
public void hideButtons() {
|
||||
if (isShowing)
|
||||
return;
|
||||
@@ -345,6 +369,123 @@ public class GameHUD extends Stage {
|
||||
deckActor.addAction(Actions.sequence(Actions.delay(0.25f), Actions.parallel(Actions.show(), Actions.alpha(opacity,0.1f), Actions.moveTo(referenceX, deckActor.getY(), 0.25f))));
|
||||
FThreads.delayInEDT(300, () -> isShowing = false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(Controller controller) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(Controller controller) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonDown(Controller controller, int buttonIndex) {
|
||||
if (Forge.getCurrentScene() instanceof HudScene) {
|
||||
if (controller.getMapping().buttonA == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.BUTTON_A);
|
||||
if (controller.getMapping().buttonB == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.BUTTON_B);
|
||||
if (controller.getMapping().buttonX == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.BUTTON_X);
|
||||
if (controller.getMapping().buttonY == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.BUTTON_Y);
|
||||
if (controller.getMapping().buttonDpadUp == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_UP);
|
||||
if (controller.getMapping().buttonDpadRight == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_RIGHT);
|
||||
if (controller.getMapping().buttonDpadDown == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_DOWN);
|
||||
if (controller.getMapping().buttonDpadLeft == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_LEFT);
|
||||
} else if (Forge.getCurrentScene() instanceof UIScene) {
|
||||
if (controller.getMapping().buttonDpadUp == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.DPAD_UP);
|
||||
if (controller.getMapping().buttonDpadRight == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.DPAD_RIGHT);
|
||||
if (controller.getMapping().buttonDpadDown == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.DPAD_DOWN);
|
||||
if (controller.getMapping().buttonDpadLeft == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.DPAD_LEFT);
|
||||
if (controller.getMapping().buttonA == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_A);
|
||||
if (controller.getMapping().buttonB == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_B);
|
||||
if (controller.getMapping().buttonX == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_X);
|
||||
if (controller.getMapping().buttonY == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_Y);
|
||||
if (controller.getMapping().buttonR1 == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_R1);
|
||||
if (controller.getMapping().buttonL1 == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_L1);
|
||||
if (controller.getMapping().buttonR2 == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_R2);
|
||||
if (controller.getMapping().buttonL2 == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_L2);
|
||||
if (controller.getMapping().buttonBack == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_SELECT);
|
||||
if (controller.getMapping().buttonStart == buttonIndex)
|
||||
return ((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_START);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean buttonUp(Controller controller, int buttonIndex) {
|
||||
if (Forge.getCurrentScene() instanceof HudScene) {
|
||||
if (controller.getMapping().buttonA == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.BUTTON_A);
|
||||
if (controller.getMapping().buttonB == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.BUTTON_B);
|
||||
if (controller.getMapping().buttonX == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.BUTTON_X);
|
||||
if (controller.getMapping().buttonY == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.BUTTON_Y);
|
||||
if (controller.getMapping().buttonDpadUp == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_UP);
|
||||
if (controller.getMapping().buttonDpadRight == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_RIGHT);
|
||||
if (controller.getMapping().buttonDpadDown == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_DOWN);
|
||||
if (controller.getMapping().buttonDpadLeft == buttonIndex)
|
||||
return ((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_LEFT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean axisMoved(Controller controller, int axisIndex, float value) {
|
||||
if (Forge.hasGamepad()) {
|
||||
if (Forge.getCurrentScene() instanceof HudScene) {
|
||||
if (controller.getAxis(controller.getMapping().axisLeftX) > 0.5f) {
|
||||
((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_RIGHT);
|
||||
} else if (controller.getAxis(controller.getMapping().axisLeftX) < -0.5f) {
|
||||
((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_LEFT);
|
||||
} else {
|
||||
((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_LEFT);
|
||||
((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_RIGHT);
|
||||
}
|
||||
if (controller.getAxis(controller.getMapping().axisLeftY) > 0.5f) {
|
||||
((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_DOWN);
|
||||
} else if (controller.getAxis(controller.getMapping().axisLeftY) < -0.5f) {
|
||||
((HudScene) Forge.getCurrentScene()).keyDown(Input.Keys.DPAD_UP);
|
||||
} else {
|
||||
((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_UP);
|
||||
((HudScene) Forge.getCurrentScene()).keyUp(Input.Keys.DPAD_DOWN);
|
||||
}
|
||||
} else if (Forge.getCurrentScene() instanceof UIScene) {
|
||||
if (controller.getAxis(4) == 1f) //L2
|
||||
((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_L2);
|
||||
if (controller.getAxis(5) == 1f) //R2
|
||||
((UIScene) Forge.getCurrentScene()).keyPressed(Input.Keys.BUTTON_R2);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class ConsoleToggleListener extends ActorGestureListener {
|
||||
public ConsoleToggleListener() {
|
||||
getGestureDetector().setLongPressSeconds(0.6f);
|
||||
|
||||
@@ -98,7 +98,7 @@ public abstract class GameStage extends Stage {
|
||||
return;
|
||||
foregroundSprites.removeActor(player);
|
||||
player = null;
|
||||
GameStage.this.getPlayerSprite();
|
||||
GameStage.this.GetPlayer();
|
||||
}
|
||||
});
|
||||
camera = (OrthographicCamera) getCamera();
|
||||
@@ -211,19 +211,19 @@ public abstract class GameStage extends Stage {
|
||||
@Override
|
||||
public boolean keyDown(int keycode) {
|
||||
super.keyDown(keycode);
|
||||
if (keycode == Input.Keys.LEFT || keycode == Input.Keys.A)//todo config
|
||||
if (keycode == Input.Keys.LEFT || keycode == Input.Keys.A || keycode == Input.Keys.DPAD_LEFT)//todo config
|
||||
{
|
||||
player.getMovementDirection().x = -1;
|
||||
}
|
||||
if (keycode == Input.Keys.RIGHT || keycode == Input.Keys.D)//todo config
|
||||
if (keycode == Input.Keys.RIGHT || keycode == Input.Keys.D || keycode == Input.Keys.DPAD_RIGHT)//todo config
|
||||
{
|
||||
player.getMovementDirection().x = +1;
|
||||
}
|
||||
if (keycode == Input.Keys.UP || keycode == Input.Keys.W)//todo config
|
||||
if (keycode == Input.Keys.UP || keycode == Input.Keys.W || keycode == Input.Keys.DPAD_UP)//todo config
|
||||
{
|
||||
player.getMovementDirection().y = +1;
|
||||
}
|
||||
if (keycode == Input.Keys.DOWN || keycode == Input.Keys.S)//todo config
|
||||
if (keycode == Input.Keys.DOWN || keycode == Input.Keys.S || keycode == Input.Keys.DPAD_DOWN)//todo config
|
||||
{
|
||||
player.getMovementDirection().y = -1;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.badlogic.gdx.maps.tiled.objects.TiledMapTileMapObject;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||
@@ -79,7 +80,10 @@ public class MapStage extends GameStage {
|
||||
//These maps are defined as embedded properties within the Tiled maps.
|
||||
private EffectData effect; //"Dungeon Effect": Character Effect applied to all adversaries within the map.
|
||||
private boolean preventEscape = false; //Prevents player from escaping the dungeon by any means that aren't an exit.
|
||||
private boolean foundPlayerSpawn;
|
||||
private ObjectMap<Integer, TextButton> dialogButtonMap;
|
||||
private int selected = 0;
|
||||
public InputEvent eventEnter, eventExit, eventTouchDown, eventTouchUp;
|
||||
TextButton selectedKey;
|
||||
|
||||
|
||||
public boolean getDialogOnlyInput() {
|
||||
@@ -120,12 +124,23 @@ public class MapStage extends GameStage {
|
||||
private MapStage()
|
||||
{
|
||||
dialog = Controls.newDialog("");
|
||||
eventTouchDown = new InputEvent();
|
||||
eventTouchDown.setPointer(-1);
|
||||
eventTouchDown.setType(InputEvent.Type.touchDown);
|
||||
eventTouchUp = new InputEvent();
|
||||
eventTouchUp.setPointer(-1);
|
||||
eventTouchUp.setType(InputEvent.Type.touchUp);
|
||||
eventEnter = new InputEvent();
|
||||
eventEnter.setPointer(-1);
|
||||
eventEnter.setType(InputEvent.Type.enter);
|
||||
eventExit = new InputEvent();
|
||||
eventExit.setPointer(-1);
|
||||
eventExit.setType(InputEvent.Type.exit);
|
||||
}
|
||||
public static MapStage getInstance() {
|
||||
return instance == null ? instance = new MapStage() : instance;
|
||||
}
|
||||
|
||||
|
||||
public void addMapActor(MapObject obj, MapActor newActor) {
|
||||
newActor.setWidth(Float.parseFloat(obj.getProperties().get("width").toString()));
|
||||
newActor.setHeight(Float.parseFloat(obj.getProperties().get("height").toString()));
|
||||
@@ -421,7 +436,7 @@ public class MapStage extends GameStage {
|
||||
float y = Float.parseFloat(prop.get("y").toString());
|
||||
float w = Float.parseFloat(prop.get("width").toString());
|
||||
float h = Float.parseFloat(prop.get("height").toString());
|
||||
|
||||
|
||||
String targetMap=prop.get("teleport").toString();
|
||||
boolean spawnPlayerThere=(targetMap==null||targetMap.isEmpty()&&sourceMap.isEmpty())||//if target is null and "from world"
|
||||
!sourceMap.isEmpty()&&targetMap.equals(sourceMap);
|
||||
@@ -669,6 +684,8 @@ public class MapStage extends GameStage {
|
||||
break;
|
||||
} else if (actor instanceof RewardSprite) {
|
||||
Gdx.input.vibrate(50);
|
||||
if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate())
|
||||
Controllers.getCurrent().startVibration(100,1);
|
||||
startPause(0.1f, () -> { //Switch to item pickup scene.
|
||||
RewardSprite RS = (RewardSprite) actor;
|
||||
RewardScene.instance().loadRewards(RS.getRewards(), RewardScene.Type.Loot, null);
|
||||
@@ -690,6 +707,9 @@ public class MapStage extends GameStage {
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
SoundSystem.instance.play(SoundEffectType.Block, false);
|
||||
Gdx.input.vibrate(50);
|
||||
int duration = mob.getData().boss ? 400 : 200;
|
||||
if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate())
|
||||
Controllers.getCurrent().startVibration(duration,1);
|
||||
startPause(0.8f, () -> {
|
||||
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
|
||||
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
|
||||
@@ -717,16 +737,30 @@ public class MapStage extends GameStage {
|
||||
public boolean isInMap() {
|
||||
return isInMap;
|
||||
}
|
||||
public boolean isDialogOnlyInput() {
|
||||
return dialogOnlyInput;
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
if (dialogButtonMap == null)
|
||||
dialogButtonMap = new ObjectMap<>();
|
||||
else
|
||||
dialogButtonMap.clear();
|
||||
for (int i = 0; i < dialog.getButtonTable().getCells().size; i++) {
|
||||
dialogButtonMap.put(i, (TextButton) dialog.getButtonTable().getCells().get(i).getActor());
|
||||
}
|
||||
dialog.show(dialogStage, Actions.show());
|
||||
dialog.setPosition((dialogStage.getWidth() - dialog.getWidth()) / 2, (dialogStage.getHeight() - dialog.getHeight()) / 2);
|
||||
dialogOnlyInput = true;
|
||||
if (Forge.hasGamepad())
|
||||
selectDialogButton(dialogButtonMap.get(0), false);
|
||||
}
|
||||
|
||||
public void hideDialog() {
|
||||
dialog.hide(Actions.sequence(Actions.sizeTo(dialog.getOriginX(), dialog.getOriginY(), 0.3f), Actions.hide()));
|
||||
dialogOnlyInput = false;
|
||||
selected = 0;
|
||||
selectedKey = null;
|
||||
}
|
||||
|
||||
public void setDialogStage(Stage dialogStage) {
|
||||
@@ -762,4 +796,62 @@ public class MapStage extends GameStage {
|
||||
public void resetQuestFlags() {
|
||||
changes.getMapFlags().clear();
|
||||
}
|
||||
|
||||
public boolean buttonPress(int keycode) {
|
||||
if (dialogOnlyInput) {
|
||||
if (keycode == Input.Keys.DPAD_UP) {
|
||||
selectPreviousDialogButton();
|
||||
}
|
||||
if (keycode == Input.Keys.DPAD_DOWN) {
|
||||
selectNextDialogButton();
|
||||
}
|
||||
if (keycode == Input.Keys.BUTTON_A) {
|
||||
selectDialogButton(selectedKey, true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void selectDialogButton(TextButton dialogButton, boolean press) {
|
||||
if (dialogOnlyInput) {
|
||||
if (selectedKey != null)
|
||||
selectedKey.fire(eventExit);
|
||||
if (dialogButton != null && dialogButton.isVisible()) {
|
||||
dialogButton.fire(eventEnter);
|
||||
selectedKey = dialogButton;
|
||||
selected = getButtonIndexKey(dialogButton);
|
||||
if (press)
|
||||
performTouch(dialogButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void performTouch(Actor actor) {
|
||||
if (actor == null)
|
||||
return;
|
||||
actor.fire(eventTouchDown);
|
||||
Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
actor.fire(eventTouchUp);
|
||||
}
|
||||
}, 0.10f);
|
||||
}
|
||||
private int getButtonIndexKey(TextButton dialogbutton) {
|
||||
if (dialogButtonMap.isEmpty())
|
||||
return 0;
|
||||
Integer key = dialogButtonMap.findKey(dialogbutton, true);
|
||||
if (key == null)
|
||||
return 0;
|
||||
return key;
|
||||
}
|
||||
private void selectNextDialogButton() {
|
||||
if (dialogButtonMap.size < 2)
|
||||
return;
|
||||
selectDialogButton(dialogButtonMap.get(selected+1), false);
|
||||
}
|
||||
private void selectPreviousDialogButton() {
|
||||
if (dialogButtonMap.size < 2)
|
||||
return;
|
||||
selectDialogButton(dialogButtonMap.get(selected-1), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package forge.adventure.stage;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.controllers.Controllers;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
@@ -115,6 +115,9 @@ public class WorldStage extends GameStage implements SaveFileContent {
|
||||
mob.setAnimation(CharacterSprite.AnimationTypes.Attack);
|
||||
SoundSystem.instance.play(SoundEffectType.Block, false);
|
||||
Gdx.input.vibrate(50);
|
||||
int duration = mob.getData().boss ? 400 : 200;
|
||||
if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate())
|
||||
Controllers.getCurrent().startVibration(duration,1);
|
||||
startPause(0.8f, () -> {
|
||||
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
|
||||
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user