mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Adventure tavern events initial implementation
This commit is contained in:
@@ -106,6 +106,7 @@ public enum DeckFormat {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
PlanarConquest ( Range.between(40, Integer.MAX_VALUE), Range.is(0), 1),
|
PlanarConquest ( Range.between(40, Integer.MAX_VALUE), Range.is(0), 1),
|
||||||
|
Adventure ( Range.between(40, Integer.MAX_VALUE), Range.between(0, 15), 4),
|
||||||
Vanguard ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
Vanguard ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
||||||
Planechase ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
Planechase ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
||||||
Archenemy ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
Archenemy ( Range.between(60, Integer.MAX_VALUE), Range.is(0), 4),
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public enum GameType {
|
|||||||
Quest (DeckFormat.QuestDeck, true, true, false, "lblQuest", ""),
|
Quest (DeckFormat.QuestDeck, true, true, false, "lblQuest", ""),
|
||||||
QuestDraft (DeckFormat.Limited, true, true, true, "lblQuestDraft", ""),
|
QuestDraft (DeckFormat.Limited, true, true, true, "lblQuestDraft", ""),
|
||||||
PlanarConquest (DeckFormat.PlanarConquest, true, false, false, "lblPlanarConquest", ""),
|
PlanarConquest (DeckFormat.PlanarConquest, true, false, false, "lblPlanarConquest", ""),
|
||||||
|
Adventure (DeckFormat.Adventure, true, false, false, "lblAdventure", ""),
|
||||||
|
AdventureEvent (DeckFormat.Limited, true, true, true, "lblAdventure", ""),
|
||||||
Puzzle (DeckFormat.Puzzle, false, false, false, "lblPuzzle", "lblPuzzleDesc"),
|
Puzzle (DeckFormat.Puzzle, false, false, false, "lblPuzzle", "lblPuzzleDesc"),
|
||||||
Constructed (DeckFormat.Constructed, false, true, true, "lblConstructed", ""),
|
Constructed (DeckFormat.Constructed, false, true, true, "lblConstructed", ""),
|
||||||
DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""),
|
DeckManager (DeckFormat.Constructed, false, true, true, "lblDeckManager", ""),
|
||||||
|
|||||||
@@ -0,0 +1,526 @@
|
|||||||
|
package forge.adventure.data;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.adventure.character.EnemySprite;
|
||||||
|
import forge.adventure.scene.RewardScene;
|
||||||
|
import forge.adventure.util.AdventureEventController;
|
||||||
|
import forge.adventure.util.Config;
|
||||||
|
import forge.adventure.util.Current;
|
||||||
|
import forge.adventure.util.Reward;
|
||||||
|
import forge.card.CardEdition;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.game.GameType;
|
||||||
|
import forge.gamemodes.limited.BoosterDraft;
|
||||||
|
import forge.gamemodes.limited.LimitedPoolType;
|
||||||
|
import forge.model.CardBlock;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.util.Aggregates;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public class AdventureEventData implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public transient BoosterDraft draft;
|
||||||
|
public AdventureEventParticipant[] participants;
|
||||||
|
public int rounds;
|
||||||
|
public int currentRound;
|
||||||
|
public AdventureEventRules eventRules = new AdventureEventRules();
|
||||||
|
public AdventureEventReward[] rewards;
|
||||||
|
|
||||||
|
public int eventOrigin;
|
||||||
|
public String sourceID;
|
||||||
|
|
||||||
|
public long eventSeed;
|
||||||
|
public AdventureEventController.EventStyle style;
|
||||||
|
public AdventureEventController.EventStatus eventStatus;
|
||||||
|
public AdventureEventController.EventFormat format;
|
||||||
|
private transient final Random random = new Random();
|
||||||
|
public Deck registeredDeck;
|
||||||
|
public Deck draftedDeck; //Copy of registered before basic lands are added for event reward purposes
|
||||||
|
public boolean isDraftComplete = false;
|
||||||
|
public String description = "";
|
||||||
|
public String[] packConfiguration = new String[0];
|
||||||
|
public transient CardBlock cardBlock;
|
||||||
|
public String cardBlockName;
|
||||||
|
public boolean playerWon;
|
||||||
|
public int matchesWon, matchesLost;
|
||||||
|
private Deck[] rewardPacks;
|
||||||
|
|
||||||
|
public AdventureEventData(AdventureEventData other){
|
||||||
|
participants = other.participants.clone();
|
||||||
|
rounds = other.rounds;
|
||||||
|
eventRules = other.eventRules;
|
||||||
|
rewards = other.rewards.clone();
|
||||||
|
eventOrigin = other.eventOrigin;
|
||||||
|
sourceID = other.sourceID;
|
||||||
|
eventSeed = other.eventSeed;
|
||||||
|
style = other.style;
|
||||||
|
random.setSeed(eventSeed);
|
||||||
|
eventStatus = other.eventStatus;
|
||||||
|
registeredDeck = other.registeredDeck;
|
||||||
|
isDraftComplete = other.isDraftComplete;
|
||||||
|
description = other.description;
|
||||||
|
cardBlockName = other.cardBlockName;
|
||||||
|
packConfiguration = other.packConfiguration;
|
||||||
|
playerWon = other.playerWon;
|
||||||
|
matchesWon = other.matchesWon;
|
||||||
|
matchesLost = other.matchesLost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Deck[] getRewardPacks(int count) {
|
||||||
|
Deck[] ret = new Deck[count];
|
||||||
|
for (int i = 0; i < count; i++){
|
||||||
|
ret[i] = AdventureEventController.instance().generateBooster(Aggregates.random(cardBlock.getSets()).getCode());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AdventureEventData(Long seed){
|
||||||
|
setEventSeed(seed);
|
||||||
|
|
||||||
|
random.setSeed(eventSeed);
|
||||||
|
eventStatus = AdventureEventController.EventStatus.Available;
|
||||||
|
registeredDeck = new Deck();
|
||||||
|
cardBlock = pickWeightedCardBlock();
|
||||||
|
if (cardBlock == null)
|
||||||
|
return;
|
||||||
|
cardBlockName = cardBlock.getName();
|
||||||
|
|
||||||
|
//Below all to be fully generated in later release
|
||||||
|
rewardPacks = getRewardPacks(3);
|
||||||
|
generateParticipants(7);
|
||||||
|
format = AdventureEventController.EventFormat.Draft;
|
||||||
|
if (cardBlock != null){
|
||||||
|
packConfiguration = getBoosterConfiguration(cardBlock);
|
||||||
|
|
||||||
|
rewards = new AdventureEventData.AdventureEventReward[4];
|
||||||
|
AdventureEventData.AdventureEventReward r0 = new AdventureEventData.AdventureEventReward();
|
||||||
|
AdventureEventData.AdventureEventReward r1 = new AdventureEventData.AdventureEventReward();
|
||||||
|
AdventureEventData.AdventureEventReward r2 = new AdventureEventData.AdventureEventReward();
|
||||||
|
AdventureEventData.AdventureEventReward r3 = new AdventureEventData.AdventureEventReward();
|
||||||
|
r0.minWins = 0;
|
||||||
|
r0.maxWins = 0;
|
||||||
|
r0.cardRewards = new Deck[]{rewardPacks[0]};
|
||||||
|
rewards[0] = r0;
|
||||||
|
r1.minWins = 1;
|
||||||
|
r1.maxWins = 3;
|
||||||
|
r1.cardRewards = new Deck[]{rewardPacks[1], rewardPacks[2]};
|
||||||
|
rewards[1] = r1;
|
||||||
|
r2.minWins = 2;
|
||||||
|
r2.maxWins = 3;
|
||||||
|
r2.itemRewards = new String[]{"Challenge Coin"};
|
||||||
|
rewards[2] = r2;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventSeed(long seed){
|
||||||
|
random.setSeed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardBlock getCardBlock() {
|
||||||
|
if (cardBlock == null){
|
||||||
|
cardBlock = FModel.getBlocks().get(cardBlockName);
|
||||||
|
}
|
||||||
|
return cardBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoosterDraft getDraft(){
|
||||||
|
Random placeholder = MyRandom.getRandom();
|
||||||
|
MyRandom.setRandom(random);
|
||||||
|
if (draft == null && (eventStatus == AdventureEventController.EventStatus.Available || eventStatus == AdventureEventController.EventStatus.Entered)){
|
||||||
|
draft = BoosterDraft.createDraft(LimitedPoolType.Block, getCardBlock(), packConfiguration);
|
||||||
|
}
|
||||||
|
if (packConfiguration == null){
|
||||||
|
packConfiguration = getBoosterConfiguration(cardBlock);
|
||||||
|
}
|
||||||
|
MyRandom.setRandom(random);
|
||||||
|
return draft;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Predicate<CardEdition> filterPioneer = FModel.getFormats().getPioneer().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterModern= FModel.getFormats().getModern().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterVintage = FModel.getFormats().getVintage().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterStandard = FModel.getFormats().getStandard().editionLegalPredicate;
|
||||||
|
|
||||||
|
public static Predicate<CardEdition> selectSetPool() {
|
||||||
|
final int rollD100 = MyRandom.getRandom().nextInt(100);
|
||||||
|
|
||||||
|
Predicate<CardEdition> rolledFilter;
|
||||||
|
|
||||||
|
if (rollD100 < 40) {
|
||||||
|
rolledFilter = filterStandard;
|
||||||
|
} else if (rollD100 < 70) {
|
||||||
|
rolledFilter = filterPioneer;
|
||||||
|
} else if (rollD100 < 90) {
|
||||||
|
rolledFilter = filterModern;
|
||||||
|
} else {
|
||||||
|
rolledFilter = filterVintage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rolledFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private CardBlock pickWeightedCardBlock() {
|
||||||
|
FModel.getMagicDb().getEditions();
|
||||||
|
Iterable<CardBlock> src = FModel.getBlocks(); //all blocks
|
||||||
|
Predicate<CardEdition> filter = Predicates.and(CardEdition.Predicates.CAN_MAKE_BOOSTER, selectSetPool());
|
||||||
|
List<CardEdition> allEditions = new ArrayList<>();
|
||||||
|
StreamSupport.stream(FModel.getMagicDb().getEditions().spliterator(), false).filter(filter::apply).filter(CardEdition::hasBoosterTemplate).collect(Collectors.toList()).iterator().forEachRemaining(allEditions::add);
|
||||||
|
List<CardBlock> legalBlocks = new ArrayList<>();
|
||||||
|
|
||||||
|
for (CardBlock b : src) { // for each block
|
||||||
|
boolean isOkay = !b.getSets().isEmpty();
|
||||||
|
for (CardEdition c : b.getSets()) {
|
||||||
|
if (!allEditions.contains(c)) {
|
||||||
|
isOkay = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!c.hasBoosterTemplate()) {
|
||||||
|
isOkay = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final List<Pair<String, Integer>> slots = c.getBoosterTemplate().getSlots();
|
||||||
|
int boosterSize = 0;
|
||||||
|
for (Pair<String, Integer> slot : slots) {
|
||||||
|
boosterSize += slot.getRight();
|
||||||
|
}
|
||||||
|
isOkay = boosterSize == 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isOkay)
|
||||||
|
legalBlocks.add(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String restricted : Config.instance().getConfigData().restrictedEditions){
|
||||||
|
legalBlocks.removeIf(q -> q.getName().equals(restricted));
|
||||||
|
}
|
||||||
|
return legalBlocks.isEmpty()?null:Aggregates.random(legalBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default filter that only allows actual sets that were printed as 15-card boosters
|
||||||
|
*/
|
||||||
|
private static final Predicate<CardEdition> DEFAULT_FILTER = new Predicate<CardEdition>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final CardEdition cardEdition) {
|
||||||
|
boolean isExpansion = cardEdition.getType().equals(CardEdition.Type.EXPANSION);
|
||||||
|
boolean isCoreSet = cardEdition.getType().equals(CardEdition.Type.CORE);
|
||||||
|
boolean isReprintSet = cardEdition.getType().equals(CardEdition.Type.REPRINT);
|
||||||
|
if (isExpansion || isCoreSet || isReprintSet) {
|
||||||
|
// Only allow sets with 15 cards in booster packs
|
||||||
|
if (cardEdition.hasBoosterTemplate()) {
|
||||||
|
final List<Pair<String, Integer>> slots = cardEdition.getBoosterTemplate().getSlots();
|
||||||
|
int boosterSize = 0;
|
||||||
|
for (Pair<String, Integer> slot : slots) {
|
||||||
|
boosterSize += slot.getRight();
|
||||||
|
}
|
||||||
|
return boosterSize == 15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public String[] getBoosterConfiguration(CardBlock selectedBlock) {
|
||||||
|
Random placeholder = MyRandom.getRandom();
|
||||||
|
MyRandom.setRandom(random);
|
||||||
|
String[] ret = new String[selectedBlock.getCntBoostersDraft()];
|
||||||
|
|
||||||
|
for (int i = 0; i < selectedBlock.getCntBoostersDraft(); i++) {
|
||||||
|
if (i < selectedBlock.getNumberSets())
|
||||||
|
ret[i] = selectedBlock.getSets().get(i).getCode();
|
||||||
|
else
|
||||||
|
ret[i] = Aggregates.random(selectedBlock.getSets()).getCode();
|
||||||
|
}
|
||||||
|
MyRandom.setRandom(placeholder);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startEvent(){
|
||||||
|
if (eventStatus == AdventureEventController.EventStatus.Ready){
|
||||||
|
currentRound = 1;
|
||||||
|
eventStatus = AdventureEventController.EventStatus.Started;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateParticipants(int numberOfOpponents){
|
||||||
|
participants = new AdventureEventParticipant[numberOfOpponents+1];
|
||||||
|
List<EnemyData> data = Aggregates.random(WorldData.getAllEnemies(),numberOfOpponents);
|
||||||
|
for (int i = 0; i < numberOfOpponents; i++){
|
||||||
|
participants[i] = new AdventureEventParticipant().generate(data.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
participants[numberOfOpponents] = getHumanPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private transient AdventureEventHuman humanPlayerInstance;
|
||||||
|
public AdventureEventHuman getHumanPlayer(){
|
||||||
|
if (humanPlayerInstance == null){
|
||||||
|
for (AdventureEventParticipant p: participants){
|
||||||
|
if (p instanceof AdventureEventHuman) {
|
||||||
|
humanPlayerInstance = (AdventureEventHuman) p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
humanPlayerInstance = new AdventureEventHuman();
|
||||||
|
}
|
||||||
|
return humanPlayerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdventureEventParticipant nextOpponent = null;
|
||||||
|
|
||||||
|
public List<AdventureEventMatch> getMatches(int round){
|
||||||
|
if (matches.containsKey(round)){
|
||||||
|
return matches.get(round);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AdventureEventParticipant> activePlayers = new ArrayList<>();
|
||||||
|
if (style == AdventureEventController.EventStyle.Bracket){
|
||||||
|
if (round == 1){
|
||||||
|
activePlayers = Arrays.stream(participants).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (matches.get(round-1) ==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < matches.get(round-1).size(); i++){
|
||||||
|
AdventureEventParticipant w = matches.get(round-1).get(i).winner;
|
||||||
|
if (w == null)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
activePlayers.add(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matches.put(round, new ArrayList<>());
|
||||||
|
while (!activePlayers.isEmpty()){
|
||||||
|
AdventureEventMatch match = new AdventureEventMatch();
|
||||||
|
match.p1 = activePlayers.remove(MyRandom.getRandom().nextInt(activePlayers.size()));
|
||||||
|
if (!activePlayers.isEmpty()) {
|
||||||
|
match.p2 = activePlayers.remove(MyRandom.getRandom().nextInt(activePlayers.size()));
|
||||||
|
}
|
||||||
|
matches.get(round).add(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches.get(currentRound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, List<AdventureEventMatch>> matches = new HashMap<>();
|
||||||
|
|
||||||
|
public void giveRewards(){
|
||||||
|
int wins = getHumanPlayer().wins;
|
||||||
|
Array<Reward> ret = new Array<>();
|
||||||
|
|
||||||
|
//Todo: this should be automatic... "somehow"
|
||||||
|
rewards[3] = new AdventureEventReward();
|
||||||
|
rewards[3].minWins = 3;
|
||||||
|
rewards[3].maxWins = 3;
|
||||||
|
draftedDeck.setName("Drafted Deck");
|
||||||
|
draftedDeck.setComment("Prize for placing 1st overall in draft event");
|
||||||
|
rewards[3].cardRewards = new Deck[]{draftedDeck};
|
||||||
|
//end todo
|
||||||
|
|
||||||
|
|
||||||
|
for (AdventureEventReward r : rewards){
|
||||||
|
if (r.minWins > wins || r.maxWins < wins) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Deck pack : r.cardRewards) {
|
||||||
|
RewardData data = new RewardData();
|
||||||
|
data.type = "cardPack";
|
||||||
|
data.count = 1;
|
||||||
|
data.cardPack = pack;
|
||||||
|
ret.addAll(data.generate(false, true));
|
||||||
|
}
|
||||||
|
for (String item : (r.itemRewards)) {
|
||||||
|
RewardData data = new RewardData();
|
||||||
|
data.type = "item";
|
||||||
|
data.count = 1;
|
||||||
|
data.itemName = item;
|
||||||
|
ret.addAll(data.generate(false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ret.size > 0){
|
||||||
|
RewardScene.instance().loadRewards(ret, RewardScene.Type.Loot, null);
|
||||||
|
Forge.switchScene(RewardScene.instance());
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo: more robust logic for event types that can be won without perfect record (Swiss w/cut, round robin)
|
||||||
|
if (matchesLost == 0 || matchesWon == rounds){
|
||||||
|
playerWon = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
playerWon = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
eventStatus = AdventureEventController.EventStatus.Awarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPairingDescription(){
|
||||||
|
switch (eventRules.pairingStyle){
|
||||||
|
case Swiss:
|
||||||
|
return "swiss";
|
||||||
|
case SwissWithCut:
|
||||||
|
return "swiss (with cut)";
|
||||||
|
case RoundRobin:
|
||||||
|
return "round robin";
|
||||||
|
case SingleElimination:
|
||||||
|
return "single elimination";
|
||||||
|
case DoubleElimination:
|
||||||
|
return "double elimination";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getDescription(){
|
||||||
|
description = "Event Type: Booster Draft\n";
|
||||||
|
description += "Block: " + cardBlock + "\n";
|
||||||
|
description += "Boosters: " + String.join(", ", packConfiguration) + "\n";
|
||||||
|
description += "Competition Style: " + participants.length + " players, matches played as best of " + eventRules.gamesPerMatch + ", " + (getPairingDescription()) + "\n\n";
|
||||||
|
description += String.format("Entry Fee (incl. reputation)\nGold %d[][+Gold][BLACK]\nMana Shards %d[][+Shards][BLACK]\n\n",eventRules.goldToEnter,eventRules.shardsToEnter);
|
||||||
|
description += String.format("Prizes\nChampion: Keep drafted deck\n2+ round wins: Challenge Coin \n1+ round wins: %s Booster, %s Booster\n0 round wins: %s Booster", rewardPacks[0].getComment(),rewardPacks[1].getComment(),rewardPacks[2].getComment());
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class AdventureEventParticipant implements Serializable, Comparable<AdventureEventParticipant> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private transient EnemySprite sprite;
|
||||||
|
String enemyDataName;
|
||||||
|
Deck registeredDeck;
|
||||||
|
|
||||||
|
public int wins;
|
||||||
|
public int losses;
|
||||||
|
|
||||||
|
public AdventureEventParticipant generate(EnemyData data){
|
||||||
|
AdventureEventParticipant ret = new AdventureEventParticipant();
|
||||||
|
ret.enemyDataName = data.getName();
|
||||||
|
ret.sprite = new EnemySprite(data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecord(){
|
||||||
|
return String.format("%d-%d", wins, losses);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private AdventureEventParticipant(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Deck getDeck(){
|
||||||
|
return registeredDeck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(){
|
||||||
|
return enemyDataName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image getAvatar(){
|
||||||
|
if (sprite == null){
|
||||||
|
sprite = new EnemySprite(WorldData.getEnemy(enemyDataName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprite == null?new Image():new Image(sprite.getAvatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAtlasPath(){
|
||||||
|
return sprite == null?"":sprite.getAtlasPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnemySprite getSprite(){
|
||||||
|
if (sprite == null){
|
||||||
|
sprite = new EnemySprite(WorldData.getEnemy(enemyDataName));
|
||||||
|
}
|
||||||
|
return sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int compareTo(AdventureEventParticipant other)
|
||||||
|
{
|
||||||
|
if (this.wins != other.wins)
|
||||||
|
return other.wins - this.wins;
|
||||||
|
else
|
||||||
|
return this.losses - other.losses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeck(Deck deck) {
|
||||||
|
registeredDeck = deck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdventureEventHuman extends AdventureEventParticipant {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Deck getDeck(){
|
||||||
|
return registeredDeck == null?Current.player().getSelectedDeck():registeredDeck;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName(){
|
||||||
|
return Current.player().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image getAvatar(){
|
||||||
|
return new Image(Current.player().avatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdventureEventRules implements Serializable {
|
||||||
|
private static final long SerialVersionUID = 1L;
|
||||||
|
|
||||||
|
public int goldToEnter;
|
||||||
|
public int shardsToEnter;
|
||||||
|
public boolean acceptsChallengeCoin;
|
||||||
|
public GameType gameType = GameType.AdventureEvent;
|
||||||
|
public int startingLife = 20;
|
||||||
|
public boolean allowsShards = false;
|
||||||
|
public boolean allowsItems = false;
|
||||||
|
public boolean allowsBlessings = false;
|
||||||
|
public boolean allowsAddBasicLands = true;
|
||||||
|
public int gamesPerMatch = 3;
|
||||||
|
|
||||||
|
public PairingStyle pairingStyle = PairingStyle.SingleElimination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdventureEventMatch implements Serializable {
|
||||||
|
private static final long SerialVersionUID = 1L;
|
||||||
|
public AdventureEventParticipant p1;
|
||||||
|
public AdventureEventParticipant p2;
|
||||||
|
public AdventureEventParticipant winner;
|
||||||
|
public int round;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AdventureEventReward implements Serializable{
|
||||||
|
public int minWins = -1;
|
||||||
|
public int maxWins = -1;
|
||||||
|
public Deck[] cardRewards = new Deck[0];
|
||||||
|
public String[] itemRewards = new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PairingStyle {
|
||||||
|
SingleElimination,
|
||||||
|
DoubleElimination,
|
||||||
|
Swiss,
|
||||||
|
SwissWithCut,
|
||||||
|
RoundRobin
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -411,6 +411,17 @@ public class AdventureQuestData implements Serializable {
|
|||||||
updateStatus();
|
updateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateEventComplete(AdventureEventData completedEvent) {
|
||||||
|
for (AdventureQuestStage stage: stages) {
|
||||||
|
if(failed)
|
||||||
|
break;
|
||||||
|
stage.updateEventComplete(completedEvent);
|
||||||
|
failed = failed || stage.getStatus() == AdventureQuestController.QuestStatus.Failed;
|
||||||
|
}
|
||||||
|
if (!failed)
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateStatus(){
|
public void updateStatus(){
|
||||||
for (AdventureQuestStage stage: stages) {
|
for (AdventureQuestStage stage: stages) {
|
||||||
switch (stage.getStatus()) {
|
switch (stage.getStatus()) {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class AdventureQuestStage implements Serializable {
|
|||||||
count2 = (count2 * candidates.size()) / 100;
|
count2 = (count2 * candidates.size()) / 100;
|
||||||
int targetIndex = Math.max(0, (int) (count1 - count2 + (new Random().nextFloat() * count2 * 2)));
|
int targetIndex = Math.max(0, (int) (count1 - count2 + (new Random().nextFloat() * count2 * 2)));
|
||||||
|
|
||||||
if (targetIndex < candidates.size() && targetIndex > 0 && count1 > 0) {
|
if (targetIndex < candidates.size() && targetIndex >= 0) {
|
||||||
candidates.sort(new AdventureQuestController.DistanceSort());
|
candidates.sort(new AdventureQuestController.DistanceSort());
|
||||||
setTargetPOI(candidates.get(targetIndex));
|
setTargetPOI(candidates.get(targetIndex));
|
||||||
} else {
|
} else {
|
||||||
@@ -297,6 +297,49 @@ public class AdventureQuestStage implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateEventComplete(AdventureEventData completedEvent) {
|
||||||
|
if (this.objective == AdventureQuestController.ObjectiveTypes.EventFinish) {
|
||||||
|
if (inTargetLocation) {
|
||||||
|
if (++progress1 >= count1) {
|
||||||
|
status = AdventureQuestController.QuestStatus.Complete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.objective == AdventureQuestController.ObjectiveTypes.EventWinMatches) {
|
||||||
|
if (inTargetLocation) {
|
||||||
|
progress1 += completedEvent.matchesWon;
|
||||||
|
progress2 += completedEvent.matchesLost;
|
||||||
|
|
||||||
|
|
||||||
|
if (status == AdventureQuestController.QuestStatus.Active && ++progress2 >= count2 && count2 > 0) {
|
||||||
|
status = AdventureQuestController.QuestStatus.Failed;
|
||||||
|
}
|
||||||
|
else if (++progress1 >= count1) {
|
||||||
|
status = AdventureQuestController.QuestStatus.Complete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.objective == AdventureQuestController.ObjectiveTypes.EventWin) {
|
||||||
|
if (inTargetLocation) {
|
||||||
|
|
||||||
|
if (completedEvent.playerWon){
|
||||||
|
progress1++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
progress2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (status == AdventureQuestController.QuestStatus.Active && ++progress2 >= count2 && count2 > 0) {
|
||||||
|
status = AdventureQuestController.QuestStatus.Failed;
|
||||||
|
}
|
||||||
|
else if (++progress1 >= count1) {
|
||||||
|
status = AdventureQuestController.QuestStatus.Complete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AdventureQuestStage() {
|
public AdventureQuestStage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -336,4 +379,6 @@ public class AdventureQuestStage implements Serializable {
|
|||||||
// if (this.stageID == null)
|
// if (this.stageID == null)
|
||||||
// this.stageID = other.stageID;
|
// this.stageID = other.stageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package forge.adventure.data;
|
package forge.adventure.data;
|
||||||
|
|
||||||
|
import forge.util.Callback;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -9,6 +11,8 @@ import java.util.List;
|
|||||||
* Carries all text, branches and effects of dialogs.
|
* Carries all text, branches and effects of dialogs.
|
||||||
*/
|
*/
|
||||||
public class DialogData implements Serializable {
|
public class DialogData implements Serializable {
|
||||||
|
//private static final long SerialVersionUID = 1; // TODO: set to current value
|
||||||
|
|
||||||
public ActionData[] action = new ActionData[0]; //List of effects to cause when the dialog shows.
|
public ActionData[] action = new ActionData[0]; //List of effects to cause when the dialog shows.
|
||||||
public ConditionData[] condition = new ConditionData[0]; //List of conditions for the action to show.
|
public ConditionData[] condition = new ConditionData[0]; //List of conditions for the action to show.
|
||||||
public String name = ""; //Text to display when action is listed as a button.
|
public String name = ""; //Text to display when action is listed as a button.
|
||||||
@@ -17,6 +21,8 @@ public class DialogData implements Serializable {
|
|||||||
public String loctext= ""; //References a localized string for the text body.
|
public String loctext= ""; //References a localized string for the text body.
|
||||||
public DialogData[] options = new DialogData[0]; //List of sub-dialogs. Show up as options in the current one.
|
public DialogData[] options = new DialogData[0]; //List of sub-dialogs. Show up as options in the current one.
|
||||||
|
|
||||||
|
public transient Callback callback;
|
||||||
|
|
||||||
public DialogData(){}
|
public DialogData(){}
|
||||||
public DialogData(DialogData other){
|
public DialogData(DialogData other){
|
||||||
if (other == null)
|
if (other == null)
|
||||||
@@ -53,6 +59,7 @@ public class DialogData implements Serializable {
|
|||||||
public String addItem; //Add item name to inventory.
|
public String addItem; //Add item name to inventory.
|
||||||
public int addLife = 0; //Gives the player X health. Negative to take.
|
public int addLife = 0; //Gives the player X health. Negative to take.
|
||||||
public int addGold = 0; //Gives the player X gold. Negative to take.
|
public int addGold = 0; //Gives the player X gold. Negative to take.
|
||||||
|
public int addShards = 0; //Gives the player X shards. Negative to take.
|
||||||
|
|
||||||
public int deleteMapObject = 0; //Remove ID from the map. -1 for self.
|
public int deleteMapObject = 0; //Remove ID from the map. -1 for self.
|
||||||
public int activateMapObject = 0; //Remove inactive state from ID.
|
public int activateMapObject = 0; //Remove inactive state from ID.
|
||||||
@@ -78,6 +85,7 @@ public class DialogData implements Serializable {
|
|||||||
addItem = other.removeItem;
|
addItem = other.removeItem;
|
||||||
addLife = other.addLife;
|
addLife = other.addLife;
|
||||||
addGold = other.addGold;
|
addGold = other.addGold;
|
||||||
|
addShards = other.addShards;
|
||||||
deleteMapObject = other.deleteMapObject;
|
deleteMapObject = other.deleteMapObject;
|
||||||
activateMapObject = other.activateMapObject;
|
activateMapObject = other.activateMapObject;
|
||||||
battleWithActorID = other.battleWithActorID;
|
battleWithActorID = other.battleWithActorID;
|
||||||
@@ -103,7 +111,8 @@ public class DialogData implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public class ConditionData {
|
static public class ConditionData implements Serializable {
|
||||||
|
private static final long SerialVersionUID = 1L; // TODO: set to current value?
|
||||||
static public class QueryQuestFlag{
|
static public class QueryQuestFlag{
|
||||||
public String key;
|
public String key;
|
||||||
public String op;
|
public String op;
|
||||||
@@ -113,6 +122,7 @@ public class DialogData implements Serializable {
|
|||||||
public int actorID = 0; //Check for an actor ID.
|
public int actorID = 0; //Check for an actor ID.
|
||||||
public String hasBlessing = null; //Check for specific blessing, if named.
|
public String hasBlessing = null; //Check for specific blessing, if named.
|
||||||
public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X.
|
public int hasGold = 0; //Check for player gold. True if gold is equal or higher than X.
|
||||||
|
public int hasShards = 0; //Check player's mana shards. True if equal or higher than X.
|
||||||
public int hasMapReputation = Integer.MIN_VALUE; //Check for player reputation in this POI. True if reputation is equal or higher than X.
|
public int hasMapReputation = Integer.MIN_VALUE; //Check for player reputation in this POI. True if reputation is equal or higher than X.
|
||||||
public int hasLife = 0; //Check for player life. True if life is equal or higher than X.
|
public int hasLife = 0; //Check for player life. True if life is equal or higher than X.
|
||||||
public String colorIdentity = null; //Check for player's current color identity.
|
public String colorIdentity = null; //Check for player's current color identity.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import forge.adventure.util.Config;
|
|||||||
import forge.adventure.util.Current;
|
import forge.adventure.util.Current;
|
||||||
import forge.adventure.util.Reward;
|
import forge.adventure.util.Reward;
|
||||||
import forge.adventure.world.WorldSave;
|
import forge.adventure.world.WorldSave;
|
||||||
|
import forge.deck.Deck;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ public class RewardData implements Serializable {
|
|||||||
public RewardData[] cardUnion;
|
public RewardData[] cardUnion;
|
||||||
public String[] deckNeeds;
|
public String[] deckNeeds;
|
||||||
public RewardData[] rotation;
|
public RewardData[] rotation;
|
||||||
|
public Deck cardPack;
|
||||||
|
|
||||||
public RewardData() { }
|
public RewardData() { }
|
||||||
|
|
||||||
@@ -74,6 +76,7 @@ public class RewardData implements Serializable {
|
|||||||
cardUnion =rewardData.cardUnion==null?null:rewardData.cardUnion.clone();
|
cardUnion =rewardData.cardUnion==null?null:rewardData.cardUnion.clone();
|
||||||
rotation =rewardData.rotation==null?null:rewardData.rotation.clone();
|
rotation =rewardData.rotation==null?null:rewardData.rotation.clone();
|
||||||
deckNeeds =rewardData.deckNeeds==null?null:rewardData.deckNeeds.clone();
|
deckNeeds =rewardData.deckNeeds==null?null:rewardData.deckNeeds.clone();
|
||||||
|
cardPack = rewardData.cardPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Iterable<PaperCard> allCards;
|
private static Iterable<PaperCard> allCards;
|
||||||
@@ -174,6 +177,12 @@ public class RewardData implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "cardPack":
|
||||||
|
if(cardPack!=null)
|
||||||
|
{
|
||||||
|
ret.add(new Reward(cardPack));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "deckCard":
|
case "deckCard":
|
||||||
if(cards == null) return ret;
|
if(cards == null) return ret;
|
||||||
for(PaperCard card: CardUtil.generateCards(cards,this, count + addedCount + Current.player().bonusDeckCards() ,rewardRandom)) {
|
for(PaperCard card: CardUtil.generateCards(cards,this, count + addedCount + Current.player().bonusDeckCards() ,rewardRandom)) {
|
||||||
|
|||||||
@@ -53,8 +53,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
private final Map<String, Byte> questFlags = new HashMap<>();
|
private final Map<String, Byte> questFlags = new HashMap<>();
|
||||||
|
|
||||||
private final Array<String> inventoryItems = new Array<>();
|
private final Array<String> inventoryItems = new Array<>();
|
||||||
|
private final Array<Deck> boostersOwned = new Array<>();
|
||||||
private final HashMap<String, String> equippedItems = new HashMap<>();
|
private final HashMap<String, String> equippedItems = new HashMap<>();
|
||||||
private final List<AdventureQuestData> quests = new ArrayList<>();
|
private final List<AdventureQuestData> quests = new ArrayList<>();
|
||||||
|
private final List<AdventureEventData> events = new ArrayList<>();
|
||||||
|
|
||||||
// Fantasy/Chaos mode settings.
|
// Fantasy/Chaos mode settings.
|
||||||
private boolean fantasyMode = false;
|
private boolean fantasyMode = false;
|
||||||
@@ -97,12 +99,16 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
shards = 0;
|
shards = 0;
|
||||||
clearDecks();
|
clearDecks();
|
||||||
inventoryItems.clear();
|
inventoryItems.clear();
|
||||||
|
boostersOwned.clear();
|
||||||
equippedItems.clear();
|
equippedItems.clear();
|
||||||
questFlags.clear();
|
questFlags.clear();
|
||||||
quests.clear();
|
quests.clear();
|
||||||
|
events.clear();
|
||||||
cards.clear();
|
cards.clear();
|
||||||
statistic.clear();
|
statistic.clear();
|
||||||
newCards.clear();
|
newCards.clear();
|
||||||
|
AdventureEventController.clear();
|
||||||
|
AdventureQuestController.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -184,6 +190,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
return inventoryItems;
|
return inventoryItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Array<Deck> getBoostersOwned(){
|
||||||
|
return boostersOwned;
|
||||||
|
}
|
||||||
|
|
||||||
public Deck getDeck(int index) {
|
public Deck getDeck(int index) {
|
||||||
return decks[index];
|
return decks[index];
|
||||||
}
|
}
|
||||||
@@ -322,6 +332,18 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (data.containsKey("boosters")) {
|
||||||
|
Deck[] decks = (Deck[]) data.readObject("boosters");
|
||||||
|
for (Deck d : decks){
|
||||||
|
if (d != null && !d.isEmpty()){
|
||||||
|
boostersOwned.add(d);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
System.err.printf("Null or empty booster %s\n", d);
|
||||||
|
System.out.println("You have an empty booster pack in your inventory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
deck = new Deck(data.readString("deckName"));
|
deck = new Deck(data.readString("deckName"));
|
||||||
deck.getMain().addAll(CardPool.fromCardList(Lists.newArrayList((String[]) data.readObject("deckCards"))));
|
deck.getMain().addAll(CardPool.fromCardList(Lists.newArrayList((String[]) data.readObject("deckCards"))));
|
||||||
@@ -344,6 +366,15 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
quests.add((AdventureQuestData) itsReallyAQuest);
|
quests.add((AdventureQuestData) itsReallyAQuest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (data.containsKey("events")) {
|
||||||
|
events.clear();
|
||||||
|
Object[] q = (Object[]) data.readObject("events");
|
||||||
|
if (q != null) {
|
||||||
|
for (Object itsReallyAnEvent : q){
|
||||||
|
events.add((AdventureEventData) itsReallyAnEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUMBER_OF_DECKS; i++) {
|
for (int i = 0; i < NUMBER_OF_DECKS; i++) {
|
||||||
if (!data.containsKey("deck_name_" + i)) {
|
if (!data.containsKey("deck_name_" + i)) {
|
||||||
@@ -413,6 +444,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
data.storeObject("equippedSlots", slots.toArray(new String[0]));
|
data.storeObject("equippedSlots", slots.toArray(new String[0]));
|
||||||
data.storeObject("equippedItems", items.toArray(new String[0]));
|
data.storeObject("equippedItems", items.toArray(new String[0]));
|
||||||
|
|
||||||
|
data.storeObject("boosters", boostersOwned.toArray(Deck.class));
|
||||||
|
|
||||||
data.storeObject("blessing", blessing);
|
data.storeObject("blessing", blessing);
|
||||||
|
|
||||||
//Save quest flags.
|
//Save quest flags.
|
||||||
@@ -425,6 +458,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
data.storeObject("questFlagsKey", questFlagsKey.toArray(new String[0]));
|
data.storeObject("questFlagsKey", questFlagsKey.toArray(new String[0]));
|
||||||
data.storeObject("questFlagsValue", questFlagsValue.toArray(new Byte[0]));
|
data.storeObject("questFlagsValue", questFlagsValue.toArray(new Byte[0]));
|
||||||
data.storeObject("quests", quests.toArray());
|
data.storeObject("quests", quests.toArray());
|
||||||
|
data.storeObject("events", events.toArray());
|
||||||
|
|
||||||
data.storeObject("deckCards", deck.getMain().toCardList("\n").split("\n"));
|
data.storeObject("deckCards", deck.getMain().toCardList("\n").split("\n"));
|
||||||
if (deck.get(DeckSection.Sideboard) != null)
|
if (deck.get(DeckSection.Sideboard) != null)
|
||||||
@@ -471,6 +505,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
if (reward.getItem() != null)
|
if (reward.getItem() != null)
|
||||||
inventoryItems.add(reward.getItem().name);
|
inventoryItems.add(reward.getItem().name);
|
||||||
break;
|
break;
|
||||||
|
case CardPack:
|
||||||
|
if (reward.getDeck() != null) {
|
||||||
|
boostersOwned.add(reward.getDeck());
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Life:
|
case Life:
|
||||||
addMaxLife(reward.getCount());
|
addMaxLife(reward.getCount());
|
||||||
break;
|
break;
|
||||||
@@ -770,6 +809,17 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean addBooster(Deck booster) {
|
||||||
|
if (booster == null || booster.isEmpty())
|
||||||
|
return false;
|
||||||
|
boostersOwned.add(booster);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeBooster(Deck booster) {
|
||||||
|
boostersOwned.removeValue(booster, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Quest functions.
|
// Quest functions.
|
||||||
public void setQuestFlag(String key, int value) {
|
public void setQuestFlag(String key, int value) {
|
||||||
@@ -826,6 +876,14 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
return quests;
|
return quests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addEvent(AdventureEventData e) {
|
||||||
|
events.add(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AdventureEventData> getEvents() {
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
public int getEnemyDeckNumber(String enemyName, int maxDecks) {
|
public int getEnemyDeckNumber(String enemyName, int maxDecks) {
|
||||||
int deckNumber = 0;
|
int deckNumber = 0;
|
||||||
if (statistic.getWinLossRecord().get(enemyName) != null) {
|
if (statistic.getWinLossRecord().get(enemyName) != null) {
|
||||||
@@ -873,4 +931,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
|
|||||||
public boolean isEmptyDeck(int deckIndex) {
|
public boolean isEmptyDeck(int deckIndex) {
|
||||||
return decks[deckIndex].isEmpty() && decks[deckIndex].getName().equals(Forge.getLocalizer().getMessage("lblEmptyDeck"));
|
return decks[deckIndex].isEmpty() && decks[deckIndex].getName().equals(Forge.getLocalizer().getMessage("lblEmptyDeck"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeEvent(AdventureEventData completedEvent) {
|
||||||
|
events.remove(completedEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package forge.adventure.player;
|
package forge.adventure.player;
|
||||||
|
|
||||||
|
import forge.adventure.data.AdventureEventData;
|
||||||
|
import forge.adventure.util.AdventureQuestController;
|
||||||
import forge.adventure.util.SaveFileContent;
|
import forge.adventure.util.SaveFileContent;
|
||||||
import forge.adventure.util.SaveFileData;
|
import forge.adventure.util.SaveFileData;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class PlayerStatistic implements SaveFileContent {
|
public class PlayerStatistic implements SaveFileContent {
|
||||||
|
|
||||||
HashMap<String, Pair<Integer,Integer>> winLossRecord=new HashMap<>();
|
HashMap<String, Pair<Integer,Integer>> winLossRecord=new HashMap<>();
|
||||||
|
List<AdventureEventData> completedEvents = new ArrayList<>();
|
||||||
int secondPlayed=0;
|
int secondPlayed=0;
|
||||||
|
|
||||||
public HashMap<String, Pair<Integer,Integer>> getWinLossRecord()
|
public HashMap<String, Pair<Integer,Integer>> getWinLossRecord()
|
||||||
@@ -43,6 +48,56 @@ public class PlayerStatistic implements SaveFileContent {
|
|||||||
|
|
||||||
return (float) totalWins()/(float)totalLoss();
|
return (float) totalWins()/(float)totalLoss();
|
||||||
}
|
}
|
||||||
|
public int eventWins(){
|
||||||
|
int win = 0;
|
||||||
|
for (AdventureEventData event : completedEvents){
|
||||||
|
if (event.playerWon)
|
||||||
|
win++;
|
||||||
|
}
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
public int eventLosses(){
|
||||||
|
int loss = 0;
|
||||||
|
for (AdventureEventData event : completedEvents){
|
||||||
|
if (!event.playerWon)
|
||||||
|
loss++;
|
||||||
|
}
|
||||||
|
return loss;
|
||||||
|
}
|
||||||
|
public float eventWinLossRatio()
|
||||||
|
{
|
||||||
|
if (eventLosses() == 0) {
|
||||||
|
// Not a true ratio but fixes division by zero
|
||||||
|
return eventWins();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (float) eventWins()/(float)eventLosses();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int eventMatchWins(){
|
||||||
|
int win = 0;
|
||||||
|
for (AdventureEventData event : completedEvents){
|
||||||
|
win+= event.matchesWon;
|
||||||
|
}
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
public int eventMatchLosses(){
|
||||||
|
int loss = 0;
|
||||||
|
for (AdventureEventData event : completedEvents){
|
||||||
|
loss += event.matchesLost;
|
||||||
|
}
|
||||||
|
return loss;
|
||||||
|
}
|
||||||
|
public float eventMatchWinLossRatio()
|
||||||
|
{
|
||||||
|
if (eventMatchLosses() == 0) {
|
||||||
|
// Not a true ratio but fixes division by zero
|
||||||
|
return eventMatchWins();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (float) eventMatchWins()/(float)eventMatchLosses();
|
||||||
|
}
|
||||||
|
|
||||||
public int getPlayTime()
|
public int getPlayTime()
|
||||||
{
|
{
|
||||||
return secondPlayed;
|
return secondPlayed;
|
||||||
@@ -54,6 +109,11 @@ public class PlayerStatistic implements SaveFileContent {
|
|||||||
winLossRecord = (HashMap<String, Pair<Integer, Integer>>) data.readObject("winLossRecord");
|
winLossRecord = (HashMap<String, Pair<Integer, Integer>>) data.readObject("winLossRecord");
|
||||||
else
|
else
|
||||||
winLossRecord.clear();
|
winLossRecord.clear();
|
||||||
|
|
||||||
|
if (data!=null&&data.containsKey("completedEvents"))
|
||||||
|
completedEvents = (ArrayList<AdventureEventData>) data.readObject("completedEvents");
|
||||||
|
else
|
||||||
|
completedEvents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResult(String enemy,boolean win)
|
public void setResult(String enemy,boolean win)
|
||||||
@@ -81,6 +141,7 @@ public class PlayerStatistic implements SaveFileContent {
|
|||||||
|
|
||||||
SaveFileData data=new SaveFileData();
|
SaveFileData data=new SaveFileData();
|
||||||
data.storeObject("winLossRecord",winLossRecord);
|
data.storeObject("winLossRecord",winLossRecord);
|
||||||
|
data.storeObject("completedEvents", completedEvents);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,4 +149,9 @@ public class PlayerStatistic implements SaveFileContent {
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
winLossRecord.clear();
|
winLossRecord.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResult(AdventureEventData completedEvent) {
|
||||||
|
completedEvents.add(completedEvent);
|
||||||
|
AdventureQuestController.instance().updateEventComplete(completedEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,16 @@ import com.badlogic.gdx.utils.Align;
|
|||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
|
import forge.adventure.data.AdventureEventData;
|
||||||
import forge.adventure.player.AdventurePlayer;
|
import forge.adventure.player.AdventurePlayer;
|
||||||
|
import forge.adventure.util.AdventureEventController;
|
||||||
import forge.adventure.util.Config;
|
import forge.adventure.util.Config;
|
||||||
import forge.assets.FImage;
|
import forge.assets.FImage;
|
||||||
import forge.assets.FSkinFont;
|
import forge.assets.FSkinFont;
|
||||||
import forge.assets.FSkinImage;
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.card.CardEdition;
|
||||||
import forge.deck.*;
|
import forge.deck.*;
|
||||||
|
import forge.gamemodes.limited.BoosterDraft;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.*;
|
import forge.itemmanager.*;
|
||||||
@@ -25,19 +29,101 @@ import forge.menu.FPopupMenu;
|
|||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.screens.FScreen;
|
import forge.screens.FScreen;
|
||||||
import forge.screens.TabPageScreen;
|
import forge.screens.TabPageScreen;
|
||||||
import forge.toolbox.FContainer;
|
import forge.toolbox.*;
|
||||||
import forge.toolbox.FEvent;
|
|
||||||
import forge.toolbox.FLabel;
|
|
||||||
import forge.toolbox.GuiChoose;
|
|
||||||
import forge.util.Callback;
|
import forge.util.Callback;
|
||||||
import forge.util.ItemPool;
|
import forge.util.ItemPool;
|
||||||
import forge.util.Utils;
|
import forge.util.Utils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
public class AdventureDeckEditor extends TabPageScreen<AdventureDeckEditor> {
|
|
||||||
|
public class AdventureDeckEditor extends TabPageScreen<AdventureDeckEditor> {
|
||||||
|
|
||||||
|
private static class DraftPackPage extends CatalogPage {
|
||||||
|
protected DraftPackPage() {
|
||||||
|
super(ItemManagerConfig.DRAFT_PACK, Forge.getLocalizer().getInstance().getMessage("lblPackN", String.valueOf(1)), FSkinImage.PACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refresh() {
|
||||||
|
BoosterDraft draft = parentScreen.getDraft();
|
||||||
|
if (draft == null || !draft.hasNextChoice()) { return; }
|
||||||
|
|
||||||
|
CardPool pool = draft.nextChoice();
|
||||||
|
|
||||||
|
if (pool == null || pool.isEmpty()) { return; }
|
||||||
|
|
||||||
|
int packNumber = draft.getCurrentBoosterIndex() + 1;
|
||||||
|
caption = Forge.getLocalizer().getMessage("lblPackN", String.valueOf(packNumber));
|
||||||
|
cardManager.setPool(pool);
|
||||||
|
cardManager.setShowRanking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCardActivated(PaperCard card) {
|
||||||
|
super.onCardActivated(card);
|
||||||
|
afterCardPicked(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void afterCardPicked(PaperCard card) {
|
||||||
|
BoosterDraft draft = parentScreen.getDraft();
|
||||||
|
draft.setChoice(card);
|
||||||
|
|
||||||
|
if (draft.hasNextChoice()) {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hideTab(); //hide this tab page when finished drafting
|
||||||
|
parentScreen.completeDraft();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buildMenu(final FDropDownMenu menu, final PaperCard card) {
|
||||||
|
addItem(menu, Forge.getLocalizer().getMessage("lblAdd"), Forge.getLocalizer().getMessage("lblToMainDeck"), getMainDeckPage().getIcon(), true, true, new Callback<Integer>() {
|
||||||
|
@Override
|
||||||
|
public void run(Integer result) { //ignore quantity
|
||||||
|
mainDeckPage.addCard(card);
|
||||||
|
|
||||||
|
afterCardPicked(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addItem(menu, Forge.getLocalizer().getMessage("lblAdd"), Forge.getLocalizer().getMessage("lbltosideboard"), getSideboardPage().getIcon(), true, true, new Callback<Integer>() {
|
||||||
|
@Override
|
||||||
|
public void run(Integer result) { //ignore quantity
|
||||||
|
getSideboardPage().addCard(card);
|
||||||
|
afterCardPicked(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoosterDraft getDraft(){
|
||||||
|
return currentEvent.getDraft();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdventureEventData currentEvent;
|
||||||
|
|
||||||
|
public void completeDraft(){
|
||||||
|
currentEvent.isDraftComplete = true;
|
||||||
|
Deck[] opponentDecks = currentEvent.getDraft().getDecks();
|
||||||
|
for (int i = 0; i < currentEvent.participants.length && i < opponentDecks.length; i++) {
|
||||||
|
currentEvent.participants[i].setDeck(opponentDecks[i]);
|
||||||
|
}
|
||||||
|
currentEvent.draftedDeck = (Deck)currentEvent.registeredDeck.copyTo("Draft Deck");
|
||||||
|
if (allowsAddBasic()){
|
||||||
|
launchBasicLandDialog();
|
||||||
|
//Might be annoying if you haven't pruned your deck yet, but best to remind player that
|
||||||
|
//this probably needs to be done since it's there since it's not normally part of Adventure
|
||||||
|
}
|
||||||
|
if (currentEvent.eventStatus == AdventureEventController.EventStatus.Entered) {
|
||||||
|
currentEvent.eventStatus = AdventureEventController.EventStatus.Ready;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final FileHandle deckIcon = Config.instance().getFile("ui/maindeck.png");
|
private static final FileHandle deckIcon = Config.instance().getFile("ui/maindeck.png");
|
||||||
private static FImage MAIN_DECK_ICON = deckIcon.exists() ? new FImage() {
|
private static FImage MAIN_DECK_ICON = deckIcon.exists() ? new FImage() {
|
||||||
@Override
|
@Override
|
||||||
@@ -105,9 +191,24 @@ import java.util.Map;
|
|||||||
private static ItemPool<InventoryItem> decksUsingMyCards=new ItemPool<>(InventoryItem.class);
|
private static ItemPool<InventoryItem> decksUsingMyCards=new ItemPool<>(InventoryItem.class);
|
||||||
private int selected = 0;
|
private int selected = 0;
|
||||||
public static void leave() {
|
public static void leave() {
|
||||||
AdventurePlayer.current().getNewCards().clear();
|
if(EventScene.currentEvent != null && EventScene.currentEvent.getDraft() != null && !EventScene.currentEvent.isDraftComplete){
|
||||||
Forge.clearCurrentScreen();
|
FOptionPane.showConfirmDialog(Forge.getLocalizer().getMessage("lblEndAdventureEventConfirm"), Forge.getLocalizer().getMessage("lblLeaveDraft"), Forge.getLocalizer().getMessage("lblLeave"), Forge.getLocalizer().getMessage("lblCancel"), false, new Callback<Boolean>() {
|
||||||
Forge.switchToLast();
|
@Override
|
||||||
|
public void run(Boolean result) {
|
||||||
|
if (result) {
|
||||||
|
EventScene.currentEvent.eventStatus = AdventureEventController.EventStatus.Abandoned;
|
||||||
|
AdventurePlayer.current().getNewCards().clear();
|
||||||
|
Forge.clearCurrentScreen();
|
||||||
|
Forge.switchToLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
AdventurePlayer.current().getNewCards().clear();
|
||||||
|
Forge.clearCurrentScreen();
|
||||||
|
Forge.switchToLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,27 +231,55 @@ import java.util.Map;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lblGold.setText(String.valueOf(AdventurePlayer.current().getGold()));
|
lblGold.setText(String.valueOf(AdventurePlayer.current().getGold()));
|
||||||
|
|
||||||
|
// if (currentEvent.registeredDeck!=null && !currentEvent.registeredDeck.isEmpty()){
|
||||||
|
// //Use this deck instead of selected deck
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
for(TabPage<AdventureDeckEditor> page:tabPages)
|
for(TabPage<AdventureDeckEditor> page:tabPages)
|
||||||
{
|
{
|
||||||
if(page instanceof CardManagerPage)
|
if(page instanceof CardManagerPage)
|
||||||
((CardManagerPage)page).refresh();
|
((CardManagerPage)page).initialize();
|
||||||
}
|
}
|
||||||
for (TabPage<AdventureDeckEditor> tabPage : tabPages) {
|
for (TabPage<AdventureDeckEditor> tabPage : tabPages) {
|
||||||
((DeckEditorPage)tabPage).initialize();
|
((DeckEditorPage)tabPage).initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static DeckEditorPage[] getPages() {
|
private static DeckEditorPage[] getPages(AdventureEventData event) {
|
||||||
return new DeckEditorPage[] {
|
if (event == null){
|
||||||
new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON),
|
return new DeckEditorPage[]{
|
||||||
new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR),
|
new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON),
|
||||||
new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.QUEST_DECK_EDITOR)
|
new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR),
|
||||||
};
|
new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.QUEST_DECK_EDITOR)};
|
||||||
|
}
|
||||||
|
switch (event.eventStatus) {
|
||||||
|
case Available:
|
||||||
|
return null;
|
||||||
|
case Started:
|
||||||
|
case Completed:
|
||||||
|
case Abandoned:
|
||||||
|
case Ready:
|
||||||
|
return new DeckEditorPage[]{
|
||||||
|
new DeckSectionPage(DeckSection.Main, ItemManagerConfig.DRAFT_POOL),
|
||||||
|
new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.SIDEBOARD)};
|
||||||
|
case Entered:
|
||||||
|
return new DeckEditorPage[]{
|
||||||
|
event.getDraft() != null ? (new DraftPackPage()) :
|
||||||
|
new CatalogPage(ItemManagerConfig.DRAFT_PACK, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON),
|
||||||
|
new DeckSectionPage(DeckSection.Main, ItemManagerConfig.DRAFT_POOL),
|
||||||
|
new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.SIDEBOARD)};
|
||||||
|
default:
|
||||||
|
return new DeckEditorPage[]{
|
||||||
|
new CatalogPage(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON),
|
||||||
|
new DeckSectionPage(DeckSection.Main, ItemManagerConfig.QUEST_DECK_EDITOR),
|
||||||
|
new DeckSectionPage(DeckSection.Sideboard, ItemManagerConfig.SIDEBOARD)};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private CatalogPage catalogPage;
|
private CatalogPage catalogPage;
|
||||||
private DeckSectionPage mainDeckPage;
|
private static DeckSectionPage mainDeckPage;
|
||||||
private DeckSectionPage sideboardPage;
|
private static DeckSectionPage sideboardPage;
|
||||||
private DeckSectionPage commanderPage;
|
private DeckSectionPage commanderPage;
|
||||||
|
|
||||||
protected final DeckHeader deckHeader = add(new DeckHeader());
|
protected final DeckHeader deckHeader = add(new DeckHeader());
|
||||||
@@ -159,10 +288,10 @@ import java.util.Map;
|
|||||||
|
|
||||||
|
|
||||||
boolean isShop;
|
boolean isShop;
|
||||||
public AdventureDeckEditor(boolean createAsShop) {
|
public AdventureDeckEditor(boolean createAsShop, AdventureEventData event) {
|
||||||
super(e -> leave(),getPages());
|
super(e -> leave(), getPages(event));
|
||||||
|
|
||||||
isShop=createAsShop;
|
isShop=createAsShop;
|
||||||
|
currentEvent = event;
|
||||||
|
|
||||||
//cache specific pages
|
//cache specific pages
|
||||||
for (TabPage<AdventureDeckEditor> tabPage : tabPages) {
|
for (TabPage<AdventureDeckEditor> tabPage : tabPages) {
|
||||||
@@ -196,6 +325,14 @@ import java.util.Map;
|
|||||||
@Override
|
@Override
|
||||||
protected void buildMenu() {
|
protected void buildMenu() {
|
||||||
addItem(new FMenuItem(Forge.getLocalizer().getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, e1 -> FDeckViewer.copyDeckToClipboard(getDeck())));
|
addItem(new FMenuItem(Forge.getLocalizer().getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, e1 -> FDeckViewer.copyDeckToClipboard(getDeck())));
|
||||||
|
FMenuItem addBasic = new FMenuItem(Forge.getLocalizer().getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, new FEvent.FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
launchBasicLandDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addBasic.setEnabled(allowsAddBasic());
|
||||||
|
addItem(addBasic);
|
||||||
((DeckEditorPage)getSelectedPage()).buildDeckMenu(this);
|
((DeckEditorPage)getSelectedPage()).buildDeckMenu(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -203,6 +340,34 @@ import java.util.Map;
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void launchBasicLandDialog(){
|
||||||
|
CardEdition defaultLandSet;
|
||||||
|
//suggest a random set from the ones used in the limited card pool that have all basic lands
|
||||||
|
Set<CardEdition> availableEditionCodes = new HashSet<>();
|
||||||
|
for (PaperCard p : currentEvent.registeredDeck.getAllCardsInASinglePool().toFlatList()) {
|
||||||
|
availableEditionCodes.add(FModel.getMagicDb().getEditions().get(p.getEdition()));
|
||||||
|
}
|
||||||
|
defaultLandSet = CardEdition.Predicates.getRandomSetWithAllBasicLands(availableEditionCodes);
|
||||||
|
|
||||||
|
AddBasicLandsDialog dialog = new AddBasicLandsDialog(currentEvent.registeredDeck, defaultLandSet, new Callback<CardPool>() {
|
||||||
|
@Override
|
||||||
|
public void run(CardPool landsToAdd) {
|
||||||
|
getMainDeckPage().addCards(landsToAdd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show();
|
||||||
|
setSelectedPage(getMainDeckPage()); //select main deck page if needed so main deck is visible below dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean allowsAddBasic() {
|
||||||
|
if (currentEvent == null || !currentEvent.eventRules.allowsAddBasicLands)
|
||||||
|
return false;
|
||||||
|
if (currentEvent.eventStatus == AdventureEventController.EventStatus.Entered && currentEvent.isDraftComplete)
|
||||||
|
return true;
|
||||||
|
else return currentEvent.eventStatus == AdventureEventController.EventStatus.Ready;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doLayout(float startY, float width, float height) {
|
protected void doLayout(float startY, float width, float height) {
|
||||||
if (deckHeader.isVisible()) {
|
if (deckHeader.isVisible()) {
|
||||||
@@ -212,17 +377,17 @@ import java.util.Map;
|
|||||||
super.doLayout(startY, width, height);
|
super.doLayout(startY, width, height);
|
||||||
}
|
}
|
||||||
public Deck getDeck() {
|
public Deck getDeck() {
|
||||||
return AdventurePlayer.current().getSelectedDeck();
|
return (currentEvent != null && currentEvent.registeredDeck != null)?currentEvent.registeredDeck:AdventurePlayer.current().getSelectedDeck();
|
||||||
}
|
}
|
||||||
protected CatalogPage getCatalogPage() {
|
protected CatalogPage getCatalogPage() {
|
||||||
return catalogPage;
|
return catalogPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DeckSectionPage getMainDeckPage() {
|
protected static DeckSectionPage getMainDeckPage() {
|
||||||
return mainDeckPage;
|
return mainDeckPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DeckSectionPage getSideboardPage() {
|
protected static DeckSectionPage getSideboardPage() {
|
||||||
return sideboardPage;
|
return sideboardPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +398,15 @@ import java.util.Map;
|
|||||||
@Override
|
@Override
|
||||||
public void onClose(final Callback<Boolean> canCloseCallback) {
|
public void onClose(final Callback<Boolean> canCloseCallback) {
|
||||||
|
|
||||||
|
if (currentEvent.getDraft() != null) {
|
||||||
|
if (currentEvent.isDraftComplete || canCloseCallback == null) {
|
||||||
|
super.onClose(canCloseCallback); //can skip prompt if draft saved
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FOptionPane.showConfirmDialog(Forge.getLocalizer().getMessage("lblEndAdventureEventConfirm"), Forge.getLocalizer().getMessage("lblLeaveDraft"), Forge.getLocalizer().getMessage("lblLeave"), Forge.getLocalizer().getMessage("lblCancel"), false, canCloseCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -794,9 +968,12 @@ import java.util.Map;
|
|||||||
case Planes:
|
case Planes:
|
||||||
case Schemes:
|
case Schemes:
|
||||||
removeCard(card);
|
removeCard(card);
|
||||||
if (parentScreen.getCatalogPage() != null) {
|
if (parentScreen.getCatalogPage() != null && parentScreen.currentEvent == null || parentScreen.currentEvent.getDraft() == null) {
|
||||||
parentScreen.getCatalogPage().addCard(card);
|
parentScreen.getCatalogPage().addCard(card);
|
||||||
}
|
}
|
||||||
|
else if (parentScreen.getSideboardPage() != null) {
|
||||||
|
parentScreen.getSideboardPage().addCard(card);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Sideboard:
|
case Sideboard:
|
||||||
removeCard(card);
|
removeCard(card);
|
||||||
@@ -821,17 +998,21 @@ import java.util.Map;
|
|||||||
addCard(card, result);
|
addCard(card, result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addItem(menu, Forge.getLocalizer().getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback<Integer>() {
|
if (parentScreen.currentEvent == null || parentScreen.currentEvent.getDraft() == null) {
|
||||||
@Override
|
addItem(menu, Forge.getLocalizer().getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback<Integer>() {
|
||||||
public void run(Integer result) {
|
@Override
|
||||||
if (result == null || result <= 0) { return; }
|
public void run(Integer result) {
|
||||||
|
if (result == null || result <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
removeCard(card, result);
|
removeCard(card, result);
|
||||||
if (parentScreen.getCatalogPage() != null) {
|
if (parentScreen.getCatalogPage() != null) {
|
||||||
parentScreen.getCatalogPage().addCard(card, result);
|
parentScreen.getCatalogPage().addCard(card, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
if (parentScreen.getSideboardPage() != null) {
|
if (parentScreen.getSideboardPage() != null) {
|
||||||
addItem(menu, Forge.getLocalizer().getMessage("lblMove"), Forge.getLocalizer().getMessage("lbltosideboard"), parentScreen.getSideboardPage().getIcon(), false, false, new Callback<Integer>() {
|
addItem(menu, Forge.getLocalizer().getMessage("lblMove"), Forge.getLocalizer().getMessage("lbltosideboard"), parentScreen.getSideboardPage().getIcon(), false, false, new Callback<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -855,17 +1036,21 @@ import java.util.Map;
|
|||||||
addCard(card, result);
|
addCard(card, result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addItem(menu, Forge.getLocalizer().getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback<Integer>() {
|
if (parentScreen.currentEvent == null || parentScreen.currentEvent.getDraft() == null) {
|
||||||
@Override
|
addItem(menu, Forge.getLocalizer().getMessage("lblRemove"), null, Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, false, false, new Callback<Integer>() {
|
||||||
public void run(Integer result) {
|
@Override
|
||||||
if (result == null || result <= 0) { return; }
|
public void run(Integer result) {
|
||||||
|
if (result == null || result <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
removeCard(card, result);
|
removeCard(card, result);
|
||||||
if (parentScreen.getCatalogPage() != null) {
|
if (parentScreen.getCatalogPage() != null) {
|
||||||
parentScreen.getCatalogPage().addCard(card, result);
|
parentScreen.getCatalogPage().addCard(card, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
addItem(menu, Forge.getLocalizer().getMessage("lblMove"), Forge.getLocalizer().getMessage("lblToMainDeck"), parentScreen.getMainDeckPage().getIcon(), false, false, new Callback<Integer>() {
|
addItem(menu, Forge.getLocalizer().getMessage("lblMove"), Forge.getLocalizer().getMessage("lblToMainDeck"), parentScreen.getMainDeckPage().getIcon(), false, false, new Callback<Integer>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Integer result) {
|
public void run(Integer result) {
|
||||||
@@ -896,6 +1081,14 @@ import java.util.Map;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCards(Iterable<Map.Entry<PaperCard, Integer>> cards) {
|
||||||
|
if (canAddCards()) {
|
||||||
|
cardManager.addItems(cards);
|
||||||
|
//parentScreen.getEditorType().getController().notifyModelChanged();
|
||||||
|
updateCaption();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isPartnerCommander(final PaperCard card) {
|
private boolean isPartnerCommander(final PaperCard card) {
|
||||||
if (parentScreen.getCommanderPage() == null || parentScreen.getDeck().getCommanders().isEmpty()) {
|
if (parentScreen.getCommanderPage() == null || parentScreen.getDeck().getCommanders().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class DeckEditScene extends ForgeScene {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public FScreen getScreen() {
|
public FScreen getScreen() {
|
||||||
return screen==null?screen = new AdventureDeckEditor(false):screen;
|
return screen==null?screen = new AdventureDeckEditor(false, null):screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
47
forge-gui-mobile/src/forge/adventure/scene/DraftScene.java
Normal file
47
forge-gui-mobile/src/forge/adventure/scene/DraftScene.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package forge.adventure.scene;
|
||||||
|
|
||||||
|
import forge.adventure.data.AdventureEventData;
|
||||||
|
import forge.adventure.stage.GameHUD;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DraftScene
|
||||||
|
* scene class that contains the Deck editor used for draft events
|
||||||
|
*/
|
||||||
|
public class DraftScene extends ForgeScene {
|
||||||
|
private static DraftScene object;
|
||||||
|
|
||||||
|
public static DraftScene instance() {
|
||||||
|
if(object==null)
|
||||||
|
object=new DraftScene();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdventureDeckEditor screen;
|
||||||
|
AdventureEventData currentEvent;
|
||||||
|
|
||||||
|
private DraftScene() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
GameHUD.getInstance().getTouchpad().setVisible(false);
|
||||||
|
screen = null;
|
||||||
|
getScreen();
|
||||||
|
screen.refresh();
|
||||||
|
super.enter();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public FScreen getScreen() {
|
||||||
|
return screen==null?screen = new AdventureDeckEditor(false, currentEvent):screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadEvent(AdventureEventData event) {
|
||||||
|
this.currentEvent = event;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import forge.Graphics;
|
|||||||
import forge.LobbyPlayer;
|
import forge.LobbyPlayer;
|
||||||
import forge.adventure.character.EnemySprite;
|
import forge.adventure.character.EnemySprite;
|
||||||
import forge.adventure.character.PlayerSprite;
|
import forge.adventure.character.PlayerSprite;
|
||||||
|
import forge.adventure.data.AdventureEventData;
|
||||||
import forge.adventure.data.EffectData;
|
import forge.adventure.data.EffectData;
|
||||||
import forge.adventure.data.EnemyData;
|
import forge.adventure.data.EnemyData;
|
||||||
import forge.adventure.data.ItemData;
|
import forge.adventure.data.ItemData;
|
||||||
@@ -70,6 +71,7 @@ public class DuelScene extends ForgeScene {
|
|||||||
boolean callbackExit = false;
|
boolean callbackExit = false;
|
||||||
boolean arenaBattleChallenge = false;
|
boolean arenaBattleChallenge = false;
|
||||||
boolean isArena = false;
|
boolean isArena = false;
|
||||||
|
AdventureEventData eventData;
|
||||||
private LoadingOverlay matchOverlay;
|
private LoadingOverlay matchOverlay;
|
||||||
List<IPaperCard> playerExtras = new ArrayList<>();
|
List<IPaperCard> playerExtras = new ArrayList<>();
|
||||||
List<IPaperCard> AIExtras = new ArrayList<>();
|
List<IPaperCard> AIExtras = new ArrayList<>();
|
||||||
@@ -88,15 +90,20 @@ public class DuelScene extends ForgeScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void GameEnd() {
|
public void GameEnd() {
|
||||||
|
//TODO: Progress towards applicable Adventure quests also needs to be reported here.
|
||||||
|
if (eventData != null)
|
||||||
|
eventData.nextOpponent = null;
|
||||||
boolean winner = false;
|
boolean winner = false;
|
||||||
try {
|
try {
|
||||||
winner = humanPlayer == hostedMatch.getGame().getMatch().getWinner();
|
winner = humanPlayer == hostedMatch.getGame().getMatch().getWinner();
|
||||||
|
|
||||||
//Persists expended (or potentially gained) shards back to Adventure
|
//Persists expended (or potentially gained) shards back to Adventure
|
||||||
//TODO: Progress towards applicable Adventure quests also needs to be reported here.
|
if (eventData == null || eventData.eventRules.allowsShards) {
|
||||||
List<PlayerControllerHuman> humans = hostedMatch.getHumanControllers();
|
List<PlayerControllerHuman> humans = hostedMatch.getHumanControllers(); {
|
||||||
if (humans.size() == 1) {
|
if (humans.size() == 1) {
|
||||||
Current.player().setShards(humans.get(0).getPlayer().getNumManaShards());
|
Current.player().setShards(humans.get(0).getPlayer().getNumManaShards());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -188,7 +195,8 @@ public class DuelScene extends ForgeScene {
|
|||||||
player.addExtraCardsOnBattlefield(startCards);
|
player.addExtraCardsOnBattlefield(startCards);
|
||||||
player.addExtraCardsInCommandZone(startCardsInCommandZone);
|
player.addExtraCardsInCommandZone(startCardsInCommandZone);
|
||||||
|
|
||||||
player.setStartingLife(Math.max(1, lifeMod + player.getStartingLife()));
|
if (lifeMod != 0)
|
||||||
|
player.setStartingLife(Math.max(1, lifeMod + player.getStartingLife()));
|
||||||
player.setStartingHand(player.getStartingHand() + changeStartCards);
|
player.setStartingHand(player.getStartingHand() + changeStartCards);
|
||||||
player.setManaShards((player.getManaShards() + extraManaShards));
|
player.setManaShards((player.getManaShards() + extraManaShards));
|
||||||
player.setEnableETBCountersEffect(true); //enable etbcounters on starting cards like Ring of Three Wishes, etc...
|
player.setEnableETBCountersEffect(true); //enable etbcounters on starting cards like Ring of Three Wishes, etc...
|
||||||
@@ -202,10 +210,17 @@ public class DuelScene extends ForgeScene {
|
|||||||
public void enter() {
|
public void enter() {
|
||||||
GameHUD.getInstance().unloadAudio();
|
GameHUD.getInstance().unloadAudio();
|
||||||
Set<GameType> appliedVariants = new HashSet<>();
|
Set<GameType> appliedVariants = new HashSet<>();
|
||||||
appliedVariants.add(GameType.Constructed);
|
if (eventData!= null && eventData.eventRules != null){
|
||||||
|
appliedVariants.add(eventData.eventRules.gameType);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
appliedVariants.add(GameType.Adventure);
|
||||||
|
}
|
||||||
|
|
||||||
AdventurePlayer advPlayer = Current.player();
|
AdventurePlayer advPlayer = Current.player();
|
||||||
|
|
||||||
List<RegisteredPlayer> players = new ArrayList<>();
|
List<RegisteredPlayer> players = new ArrayList<>();
|
||||||
|
|
||||||
int missingCards = Config.instance().getConfigData().minDeckSize - playerDeck.getMain().countAll();
|
int missingCards = Config.instance().getConfigData().minDeckSize - playerDeck.getMain().countAll();
|
||||||
if (missingCards > 0) //Replace unknown cards for a Wastes.
|
if (missingCards > 0) //Replace unknown cards for a Wastes.
|
||||||
playerDeck.getMain().add("Wastes", missingCards);
|
playerDeck.getMain().add("Wastes", missingCards);
|
||||||
@@ -222,8 +237,9 @@ public class DuelScene extends ForgeScene {
|
|||||||
playerObject.setAvatarIndex(90000);
|
playerObject.setAvatarIndex(90000);
|
||||||
humanPlayer.setPlayer(playerObject);
|
humanPlayer.setPlayer(playerObject);
|
||||||
humanPlayer.setTeamNumber(0);
|
humanPlayer.setTeamNumber(0);
|
||||||
humanPlayer.setStartingLife(advPlayer.getLife());
|
humanPlayer.setStartingLife(eventData!=null?eventData.eventRules.startingLife:advPlayer.getLife());
|
||||||
humanPlayer.setManaShards((advPlayer.getShards()));
|
if (eventData!=null && eventData.eventRules.allowsShards)
|
||||||
|
humanPlayer.setManaShards(advPlayer.getShards());
|
||||||
|
|
||||||
Array<EffectData> playerEffects = new Array<>();
|
Array<EffectData> playerEffects = new Array<>();
|
||||||
Array<EffectData> oppEffects = new Array<>();
|
Array<EffectData> oppEffects = new Array<>();
|
||||||
@@ -242,30 +258,32 @@ public class DuelScene extends ForgeScene {
|
|||||||
humanPlayer.addExtraCardsOnBattlefield(playerCards);
|
humanPlayer.addExtraCardsOnBattlefield(playerCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Collect and add items effects first.
|
if (eventData ==null || eventData.eventRules.allowsItems) {
|
||||||
for (String playerItem : advPlayer.getEquippedItems()) {
|
//Collect and add items effects first.
|
||||||
ItemData item = ItemData.getItem(playerItem);
|
for (String playerItem : advPlayer.getEquippedItems()) {
|
||||||
if (item != null && item.effect != null) {
|
ItemData item = ItemData.getItem(playerItem);
|
||||||
playerEffects.add(item.effect);
|
if (item != null && item.effect != null) {
|
||||||
if (item.effect.opponent != null) oppEffects.add(item.effect.opponent);
|
playerEffects.add(item.effect);
|
||||||
} else {
|
if (item.effect.opponent != null) oppEffects.add(item.effect.opponent);
|
||||||
System.err.printf("Item %s not found.", playerItem);
|
} else {
|
||||||
|
System.err.printf("Item %s not found.", playerItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (eventData ==null || eventData.eventRules.allowsBlessings) {
|
||||||
|
//Collect and add player blessings.
|
||||||
|
if (advPlayer.getBlessing() != null) {
|
||||||
|
playerEffects.add(advPlayer.getBlessing());
|
||||||
|
if (advPlayer.getBlessing().opponent != null) oppEffects.add(advPlayer.getBlessing().opponent);
|
||||||
|
}
|
||||||
|
|
||||||
//Collect and add player blessings.
|
//Collect and add enemy effects (same as blessings but for individual enemies).
|
||||||
if (advPlayer.getBlessing() != null) {
|
if (enemy.effect != null) {
|
||||||
playerEffects.add(advPlayer.getBlessing());
|
oppEffects.add(enemy.effect);
|
||||||
if (advPlayer.getBlessing().opponent != null) oppEffects.add(advPlayer.getBlessing().opponent);
|
if (enemy.effect.opponent != null)
|
||||||
|
playerEffects.add(enemy.effect.opponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Collect and add enemy effects (same as blessings but for individual enemies).
|
|
||||||
if (enemy.effect != null) {
|
|
||||||
oppEffects.add(enemy.effect);
|
|
||||||
if (enemy.effect.opponent != null)
|
|
||||||
playerEffects.add(enemy.effect.opponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Collect and add dungeon-wide effects.
|
//Collect and add dungeon-wide effects.
|
||||||
if (dungeonEffect != null) {
|
if (dungeonEffect != null) {
|
||||||
oppEffects.add(dungeonEffect);
|
oppEffects.add(dungeonEffect);
|
||||||
@@ -290,6 +308,8 @@ public class DuelScene extends ForgeScene {
|
|||||||
deck = deckProxy.getDeck();
|
deck = deckProxy.getDeck();
|
||||||
} else if (this.arenaBattleChallenge) {
|
} else if (this.arenaBattleChallenge) {
|
||||||
deck = Aggregates.random(DeckProxy.getAllGeneticAIDecks()).getDeck();
|
deck = Aggregates.random(DeckProxy.getAllGeneticAIDecks()).getDeck();
|
||||||
|
} else if (this.eventData != null){
|
||||||
|
deck = eventData.nextOpponent.getDeck();
|
||||||
} else {
|
} else {
|
||||||
deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard"));
|
deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard"));
|
||||||
}
|
}
|
||||||
@@ -304,14 +324,16 @@ public class DuelScene extends ForgeScene {
|
|||||||
enemyPlayer.setAvatarIndex(90001 + i);
|
enemyPlayer.setAvatarIndex(90001 + i);
|
||||||
aiPlayer.setPlayer(enemyPlayer);
|
aiPlayer.setPlayer(enemyPlayer);
|
||||||
aiPlayer.setTeamNumber(currentEnemy.teamNumber);
|
aiPlayer.setTeamNumber(currentEnemy.teamNumber);
|
||||||
aiPlayer.setStartingLife(Math.round((float) currentEnemy.life * advPlayer.getDifficulty().enemyLifeFactor));
|
aiPlayer.setStartingLife(eventData!=null?eventData.eventRules.startingLife:Math.round((float) currentEnemy.life * advPlayer.getDifficulty().enemyLifeFactor));
|
||||||
|
|
||||||
Array<EffectData> equipmentEffects = new Array<>();
|
Array<EffectData> equipmentEffects = new Array<>();
|
||||||
if (currentEnemy.equipment != null) {
|
if (eventData!=null && eventData.eventRules.allowsItems) {
|
||||||
for (String oppItem : currentEnemy.equipment) {
|
if (currentEnemy.equipment != null) {
|
||||||
ItemData item = ItemData.getItem(oppItem);
|
for (String oppItem : currentEnemy.equipment) {
|
||||||
equipmentEffects.add(item.effect);
|
ItemData item = ItemData.getItem(oppItem);
|
||||||
if (item.effect.opponent != null) playerEffects.add(item.effect.opponent);
|
equipmentEffects.add(item.effect);
|
||||||
|
if (item.effect.opponent != null) playerEffects.add(item.effect.opponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addEffects(aiPlayer, oppEffects);
|
addEffects(aiPlayer, oppEffects);
|
||||||
@@ -324,7 +346,9 @@ public class DuelScene extends ForgeScene {
|
|||||||
|
|
||||||
players.add(aiPlayer);
|
players.add(aiPlayer);
|
||||||
|
|
||||||
Current.setLatestDeck(deck);
|
if (eventData==null) {
|
||||||
|
Current.setLatestDeck(deck);
|
||||||
|
}
|
||||||
|
|
||||||
currentEnemy = currentEnemy.nextEnemy;
|
currentEnemy = currentEnemy.nextEnemy;
|
||||||
}
|
}
|
||||||
@@ -336,14 +360,23 @@ public class DuelScene extends ForgeScene {
|
|||||||
|
|
||||||
hostedMatch = MatchController.hostMatch();
|
hostedMatch = MatchController.hostMatch();
|
||||||
|
|
||||||
GameRules rules = new GameRules(GameType.Constructed);
|
GameRules rules;
|
||||||
|
|
||||||
|
if (eventData != null){
|
||||||
|
rules = new GameRules(eventData.eventRules.gameType);
|
||||||
|
rules.setGamesPerMatch(eventData.eventRules.gamesPerMatch);
|
||||||
|
bossBattle = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
rules = new GameRules(GameType.Adventure);
|
||||||
|
rules.setGamesPerMatch(1);
|
||||||
|
}
|
||||||
rules.setPlayForAnte(false);
|
rules.setPlayForAnte(false);
|
||||||
rules.setMatchAnteRarity(true);
|
rules.setMatchAnteRarity(true);
|
||||||
rules.setGamesPerMatch(1);
|
|
||||||
rules.setManaBurn(false);
|
rules.setManaBurn(false);
|
||||||
rules.setWarnAboutAICards(false);
|
rules.setWarnAboutAICards(false);
|
||||||
|
|
||||||
hostedMatch.setEndGameHook(() -> DuelScene.this.GameEnd());
|
//hostedMatch.setEndGameHook(() -> DuelScene.this.GameEnd());
|
||||||
hostedMatch.startMatch(rules, appliedVariants, players, guiMap, bossBattle ? MusicPlaylist.BOSS : MusicPlaylist.MATCH);
|
hostedMatch.startMatch(rules, appliedVariants, players, guiMap, bossBattle ? MusicPlaylist.BOSS : MusicPlaylist.MATCH);
|
||||||
MatchController.instance.setGameView(hostedMatch.getGameView());
|
MatchController.instance.setGameView(hostedMatch.getGameView());
|
||||||
boolean showMessages = enemy.getData().copyPlayerDeck && Current.player().isUsingCustomDeck();
|
boolean showMessages = enemy.getData().copyPlayerDeck && Current.player().isUsingCustomDeck();
|
||||||
@@ -393,16 +426,22 @@ public class DuelScene extends ForgeScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite) {
|
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite) {
|
||||||
initDuels(playerSprite, enemySprite, false);
|
initDuels(playerSprite, enemySprite, false, null);
|
||||||
}
|
}
|
||||||
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite, boolean isArena) {
|
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite, boolean isArena, AdventureEventData eventData) {
|
||||||
this.player = playerSprite;
|
this.player = playerSprite;
|
||||||
this.enemy = enemySprite;
|
this.enemy = enemySprite;
|
||||||
this.isArena = isArena;
|
this.isArena = isArena;
|
||||||
|
this.eventData = eventData;
|
||||||
|
if (eventData!= null && eventData.eventRules == null)
|
||||||
|
eventData.eventRules = new AdventureEventData.AdventureEventRules();
|
||||||
this.arenaBattleChallenge = isArena
|
this.arenaBattleChallenge = isArena
|
||||||
&& (Current.player().getDifficulty().name.equalsIgnoreCase("Hard")
|
&& (Current.player().getDifficulty().name.equalsIgnoreCase("Hard")
|
||||||
|| Current.player().getDifficulty().name.equalsIgnoreCase("Insane"));
|
|| Current.player().getDifficulty().name.equalsIgnoreCase("Insane"));
|
||||||
this.playerDeck = (Deck) Current.player().getSelectedDeck().copyTo("PlayerDeckCopy");
|
if (eventData != null && eventData.registeredDeck != null)
|
||||||
|
this.playerDeck = eventData.registeredDeck;
|
||||||
|
else
|
||||||
|
this.playerDeck = (Deck) Current.player().getSelectedDeck().copyTo("PlayerDeckCopy");
|
||||||
this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode();
|
this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode();
|
||||||
this.AIExtras.clear();
|
this.AIExtras.clear();
|
||||||
this.playerExtras.clear();
|
this.playerExtras.clear();
|
||||||
|
|||||||
539
forge-gui-mobile/src/forge/adventure/scene/EventScene.java
Normal file
539
forge-gui-mobile/src/forge/adventure/scene/EventScene.java
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
package forge.adventure.scene;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.Scaling;
|
||||||
|
import com.github.tommyettinger.textra.TextraButton;
|
||||||
|
import com.github.tommyettinger.textra.TextraLabel;
|
||||||
|
import com.github.tommyettinger.textra.TypingLabel;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.adventure.character.EnemySprite;
|
||||||
|
import forge.adventure.data.*;
|
||||||
|
import forge.adventure.player.AdventurePlayer;
|
||||||
|
import forge.adventure.stage.IAfterMatch;
|
||||||
|
import forge.adventure.stage.WorldStage;
|
||||||
|
import forge.adventure.util.*;
|
||||||
|
import forge.adventure.world.WorldSave;
|
||||||
|
import forge.gui.FThreads;
|
||||||
|
import forge.screens.TransitionScreen;
|
||||||
|
import forge.util.Callback;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static forge.adventure.util.AdventureEventController.EventStatus.Awarded;
|
||||||
|
import static forge.adventure.util.AdventureEventController.EventStatus.Ready;
|
||||||
|
|
||||||
|
public class EventScene extends MenuScene implements IAfterMatch {
|
||||||
|
TextraLabel money, shards;
|
||||||
|
TextraButton advance, back, editDeck, nextPage, previousPage;
|
||||||
|
private Table scrollContainer;
|
||||||
|
ScrollPane scroller;
|
||||||
|
Table root, headerTable;
|
||||||
|
int pageIndex = 0;
|
||||||
|
Scene lastGameScene;
|
||||||
|
|
||||||
|
Table[] eventPages;
|
||||||
|
|
||||||
|
static AdventureEventData currentEvent;
|
||||||
|
|
||||||
|
private Array<DialogData> entryDialog;
|
||||||
|
|
||||||
|
|
||||||
|
private EventScene() {
|
||||||
|
super(Forge.isLandscapeMode() ? "ui/event.json" : "ui/event_portrait.json");
|
||||||
|
|
||||||
|
DialogData introDialog = new DialogData();
|
||||||
|
introDialog.text = "Enter this event?";
|
||||||
|
DialogData enterWithCoin = new DialogData();
|
||||||
|
enterWithCoin.name = "Redeem a Challenge Coin [+ChallengeCoin]";
|
||||||
|
DialogData enterWithShards = new DialogData();
|
||||||
|
enterWithShards.name = String.format("Spend %d [+shards]", currentEvent.eventRules.shardsToEnter);
|
||||||
|
DialogData enterWithGold = new DialogData();
|
||||||
|
enterWithGold.name = String.format("Spend %d [+gold]", currentEvent.eventRules.goldToEnter);
|
||||||
|
|
||||||
|
DialogData.ConditionData hasGold = new DialogData.ConditionData();
|
||||||
|
hasGold.hasGold = currentEvent.eventRules.goldToEnter;
|
||||||
|
enterWithGold.condition = new DialogData.ConditionData[]{hasGold};
|
||||||
|
|
||||||
|
DialogData.ConditionData hasShards = new DialogData.ConditionData();
|
||||||
|
hasShards.hasShards = currentEvent.eventRules.shardsToEnter;
|
||||||
|
enterWithShards.condition = new DialogData.ConditionData[]{hasShards};
|
||||||
|
|
||||||
|
if (currentEvent.eventRules.acceptsChallengeCoin){
|
||||||
|
DialogData.ConditionData hasCoin = new DialogData.ConditionData();
|
||||||
|
hasCoin.item="Challenge Coin";
|
||||||
|
enterWithCoin.condition = new DialogData.ConditionData[]{hasCoin};
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
DialogData.ConditionData alwaysFalse = new DialogData.ConditionData();
|
||||||
|
alwaysFalse.not = true;
|
||||||
|
enterWithCoin.condition = new DialogData.ConditionData[]{alwaysFalse};
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogData.ActionData spendGold = new DialogData.ActionData();
|
||||||
|
spendGold.addGold=-currentEvent.eventRules.goldToEnter;
|
||||||
|
enterWithGold.action = new DialogData.ActionData[]{spendGold};
|
||||||
|
|
||||||
|
DialogData.ActionData spendShards = new DialogData.ActionData();
|
||||||
|
spendShards.addShards =-currentEvent.eventRules.shardsToEnter;
|
||||||
|
enterWithShards.action = new DialogData.ActionData[]{spendShards};
|
||||||
|
|
||||||
|
DialogData.ActionData giveCoin = new DialogData.ActionData();
|
||||||
|
giveCoin.removeItem = "Challenge Coin";
|
||||||
|
enterWithCoin.action = new DialogData.ActionData[]{giveCoin};
|
||||||
|
|
||||||
|
DialogData decline = new DialogData();
|
||||||
|
decline.name = "Do not enter event";
|
||||||
|
|
||||||
|
enterWithCoin.callback = new Callback<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void run(Boolean result) {
|
||||||
|
currentEvent.eventStatus = AdventureEventController.EventStatus.Entered;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
enterWithShards.callback = new Callback<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void run(Boolean result) {
|
||||||
|
currentEvent.eventStatus = AdventureEventController.EventStatus.Entered;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
enterWithGold.callback = new Callback<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void run(Boolean result) {
|
||||||
|
currentEvent.eventStatus = AdventureEventController.EventStatus.Entered;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
introDialog.options = new DialogData[4];
|
||||||
|
introDialog.options[0] = enterWithCoin;
|
||||||
|
introDialog.options[1] = enterWithShards;
|
||||||
|
introDialog.options[2] = enterWithGold;
|
||||||
|
introDialog.options[3] = decline;
|
||||||
|
|
||||||
|
entryDialog = new Array<>();
|
||||||
|
entryDialog.add(introDialog);
|
||||||
|
|
||||||
|
TypingLabel blessingScroll = Controls.newTypingLabel("[BLACK]" + currentEvent.getDescription());
|
||||||
|
blessingScroll.skipToTheEnd();
|
||||||
|
blessingScroll.setAlignment(Align.topLeft);
|
||||||
|
blessingScroll.setWrap(true);
|
||||||
|
|
||||||
|
ui.onButtonPress("return", EventScene.this::back);
|
||||||
|
ui.onButtonPress("advance", EventScene.this::advance);
|
||||||
|
ui.onButtonPress("editDeck", EventScene.this::editDeck);
|
||||||
|
|
||||||
|
back = ui.findActor("return");
|
||||||
|
advance = ui.findActor("advance");
|
||||||
|
nextPage = ui.findActor("nextPage");
|
||||||
|
nextPage.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
|
if (nextPage.isDisabled())
|
||||||
|
return;
|
||||||
|
nextPage(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
previousPage = ui.findActor("previousPage");
|
||||||
|
previousPage.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
|
if (previousPage.isDisabled())
|
||||||
|
return;
|
||||||
|
nextPage(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
editDeck = ui.findActor("editDeck");
|
||||||
|
editDeck.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
|
if (currentEvent.getDraft() != null && currentEvent.eventStatus == Ready) {
|
||||||
|
DraftScene.instance().loadEvent(currentEvent);
|
||||||
|
Forge.switchScene(DraftScene.instance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Window window = ui.findActor("scrollWindow");
|
||||||
|
root = ui.findActor("enemies");
|
||||||
|
|
||||||
|
|
||||||
|
Window header = ui.findActor("header");
|
||||||
|
header.toFront();
|
||||||
|
headerTable = new Table(Controls.getSkin());
|
||||||
|
headerTable.add("Event Standings").expand();
|
||||||
|
header.add(headerTable).expand();
|
||||||
|
|
||||||
|
ScrollPane blessing = ui.findActor("blessingInfo");
|
||||||
|
blessing.setActor(blessingScroll);
|
||||||
|
blessingScroll.setWidth(blessing.getWidth()-5);
|
||||||
|
blessing.layout();
|
||||||
|
window.add(root);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refresh(){
|
||||||
|
scrollContainer = new Table(Controls.getSkin());
|
||||||
|
scrollContainer.row();
|
||||||
|
|
||||||
|
Arrays.sort(currentEvent.participants);
|
||||||
|
|
||||||
|
for (AdventureEventData.AdventureEventParticipant participant: currentEvent.participants){
|
||||||
|
Image avatar = participant.getAvatar();
|
||||||
|
avatar.setScaling(Scaling.stretch);
|
||||||
|
scrollContainer.add(avatar).pad(5).size(16).fillY();
|
||||||
|
scrollContainer.add().width(16);
|
||||||
|
|
||||||
|
boolean notEliminated = !currentEvent.eventStatus.equals(AdventureEventController.EventStatus.Started) || !currentEvent.matches.containsKey(currentEvent.currentRound) || currentEvent.matches.get(currentEvent.currentRound).stream().anyMatch(q -> q.p1.equals(participant) || q.p2.equals(participant));
|
||||||
|
TextraLabel participantName = Controls.newTextraLabel((notEliminated?"":"[RED]") + participant.getName());
|
||||||
|
participantName.setWrap(true);
|
||||||
|
|
||||||
|
scrollContainer.add(participantName).fillX().pad(5).width(120);
|
||||||
|
scrollContainer.add().width(16);
|
||||||
|
scrollContainer.add(String.format("%d-%d", participant.wins, participant.losses)).pad(5);
|
||||||
|
scrollContainer.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
eventPages = new Table[currentEvent.rounds + 1];
|
||||||
|
eventPages[0] = scrollContainer;
|
||||||
|
for (int i = 0; i < currentEvent.rounds; i++){
|
||||||
|
|
||||||
|
Table round = new Table(Controls.getSkin());
|
||||||
|
round.row();
|
||||||
|
|
||||||
|
List<AdventureEventData.AdventureEventMatch> matches = currentEvent.getMatches(i+1);
|
||||||
|
|
||||||
|
if (matches == null){
|
||||||
|
round.add(Controls.newTextraLabel("Pairings not yet generated"));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Table roundScrollContainer = new Table(Controls.getSkin());
|
||||||
|
for (AdventureEventData.AdventureEventMatch match: matches){
|
||||||
|
|
||||||
|
Table p1Table = new Table(Controls.getSkin());
|
||||||
|
|
||||||
|
Image p1Avatar = match.p1.getAvatar();
|
||||||
|
p1Avatar.setScaling(Scaling.stretch);
|
||||||
|
|
||||||
|
p1Table.add(p1Avatar).pad(5).size(16).fillY().top();
|
||||||
|
String color = match.winner == null?"":match.winner.equals(match.p1)?"[GREEN]":match.winner.equals(match.p2)?"[RED]":"";
|
||||||
|
TypingLabel p1Name = Controls.newTypingLabel(color + match.p1.getName());
|
||||||
|
p1Name.skipToTheEnd();
|
||||||
|
p1Name.setWrap(true);
|
||||||
|
p1Table.add(p1Name).width(50).expandX().top();
|
||||||
|
|
||||||
|
roundScrollContainer.add(p1Table).left().uniformY().top().padBottom(10);
|
||||||
|
|
||||||
|
Table verbTable = new Table(Controls.getSkin());
|
||||||
|
|
||||||
|
if (match.p2 == null){
|
||||||
|
verbTable.add("has a bye").expand().fillX().top();
|
||||||
|
}
|
||||||
|
else if (match.winner != null && match.winner.equals(match.p1)){
|
||||||
|
verbTable.add("defeated").expand().fillX().top();
|
||||||
|
}
|
||||||
|
else if (match.winner != null && match.winner.equals(match.p2)){
|
||||||
|
verbTable.add("defeated by").expand().fillX().top();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verbTable.add("versus").expand().fillX().top();
|
||||||
|
}
|
||||||
|
|
||||||
|
roundScrollContainer.add(verbTable).padLeft(10).padRight(10).top();
|
||||||
|
|
||||||
|
Table p2Table = new Table(Controls.getSkin());
|
||||||
|
if (match.p2 != null) {
|
||||||
|
Image p2Avatar = match.p2.getAvatar();
|
||||||
|
p2Avatar.setScaling(Scaling.stretch);
|
||||||
|
String color2 = match.winner == null?"":match.winner.equals(match.p2)?"[GREEN]":match.winner.equals(match.p1)?"[RED]":"";
|
||||||
|
TypingLabel p2Name = Controls.newTypingLabel(color2 + match.p2.getName());
|
||||||
|
p2Name.skipToTheEnd();
|
||||||
|
p2Name.setWrap(true);
|
||||||
|
p2Table.add(p2Name).width(50).expandX().top();
|
||||||
|
p2Table.add(p2Avatar).pad(5).size(16).fillY().top();
|
||||||
|
}
|
||||||
|
roundScrollContainer.add(p2Table).right().uniformY().top().padBottom(10);
|
||||||
|
roundScrollContainer.row();
|
||||||
|
}
|
||||||
|
round.add(roundScrollContainer).expandX().fillX();
|
||||||
|
round.row();
|
||||||
|
}
|
||||||
|
eventPages[i+1] = round;
|
||||||
|
}
|
||||||
|
|
||||||
|
performTouch(scrollPaneOfActor(scrollContainer)); //can use mouse wheel if available to scroll
|
||||||
|
|
||||||
|
root.clear();
|
||||||
|
scrollContainer.layout();
|
||||||
|
scroller = new ScrollPane(scrollContainer);
|
||||||
|
|
||||||
|
root.add(scroller).fill().prefWidth(root.getWidth());
|
||||||
|
|
||||||
|
root.layout();
|
||||||
|
scroller.layout();
|
||||||
|
|
||||||
|
scroller.clear();
|
||||||
|
scroller.setActor(eventPages[pageIndex]);
|
||||||
|
performTouch(scroller);
|
||||||
|
|
||||||
|
|
||||||
|
switch (currentEvent.eventStatus){
|
||||||
|
case Available:
|
||||||
|
nextPage.setDisabled(true);
|
||||||
|
previousPage.setDisabled(true);
|
||||||
|
editDeck.setDisabled(true);
|
||||||
|
editDeck.setVisible(false);
|
||||||
|
advance.setText("Join Event");
|
||||||
|
advance.setVisible(true);
|
||||||
|
break;
|
||||||
|
case Entered:
|
||||||
|
nextPage.setDisabled(true);
|
||||||
|
previousPage.setDisabled(true);
|
||||||
|
editDeck.setDisabled(true);
|
||||||
|
editDeck.setVisible(false);
|
||||||
|
if (currentEvent.getDraft() != null){
|
||||||
|
advance.setText("Enter Draft");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
advance.setText("Select Deck");
|
||||||
|
}
|
||||||
|
advance.setVisible(true);
|
||||||
|
break;
|
||||||
|
case Ready:
|
||||||
|
advance.setText("Start Event");
|
||||||
|
advance.setVisible(true);
|
||||||
|
editDeck.setDisabled(false);
|
||||||
|
editDeck.setVisible(true);
|
||||||
|
nextPage.setDisabled(false);
|
||||||
|
previousPage.setDisabled(false);
|
||||||
|
break;
|
||||||
|
case Started:
|
||||||
|
advance.setText("Play round " +currentEvent.currentRound);
|
||||||
|
advance.setVisible(true);
|
||||||
|
editDeck.setDisabled(true);
|
||||||
|
editDeck.setVisible(false);
|
||||||
|
nextPage.setDisabled(false);
|
||||||
|
previousPage.setDisabled(false);
|
||||||
|
break;
|
||||||
|
case Completed:
|
||||||
|
advance.setText("Collect Rewards");
|
||||||
|
advance.setVisible(true);
|
||||||
|
editDeck.setDisabled(true);
|
||||||
|
editDeck.setVisible(false);
|
||||||
|
nextPage.setDisabled(false);
|
||||||
|
previousPage.setDisabled(false);
|
||||||
|
break;
|
||||||
|
case Awarded:
|
||||||
|
case Abandoned:
|
||||||
|
advance.setVisible(false);
|
||||||
|
editDeck.setDisabled(true);
|
||||||
|
editDeck.setVisible(false);
|
||||||
|
nextPage.setDisabled(false);
|
||||||
|
previousPage.setDisabled(false);
|
||||||
|
AdventureEventController.instance().finalizeEvent(currentEvent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EventScene object;
|
||||||
|
|
||||||
|
public static EventScene instance(Scene lastGameScene, AdventureEventData event) {
|
||||||
|
currentEvent = event;
|
||||||
|
// if (object == null)
|
||||||
|
object = new EventScene();
|
||||||
|
if (lastGameScene != null)
|
||||||
|
object.lastGameScene=lastGameScene;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextPage(boolean reverse) {
|
||||||
|
headerTable.clear();
|
||||||
|
if (!reverse && ++pageIndex >= eventPages.length){
|
||||||
|
pageIndex = 0;
|
||||||
|
}
|
||||||
|
else if (reverse && --pageIndex < 0) {
|
||||||
|
pageIndex = eventPages.length - 1;
|
||||||
|
}
|
||||||
|
if (pageIndex == 0){
|
||||||
|
headerTable.add("Event Standings").expand();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
headerTable.add("Round " + (pageIndex) + " of " + (eventPages.length - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enter() {
|
||||||
|
super.enter();
|
||||||
|
scrollContainer.clear();
|
||||||
|
|
||||||
|
if (money != null) {
|
||||||
|
WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText("[+Gold] [BLACK]" + AdventurePlayer.current().getGold()));
|
||||||
|
}
|
||||||
|
if (shards != null) {
|
||||||
|
WorldSave.getCurrentSave().getPlayer().onShardsChange(() -> shards.setText("[+Shards] [BLACK]" + AdventurePlayer.current().getShards()));
|
||||||
|
}
|
||||||
|
performTouch(scrollPaneOfActor(scrollContainer)); //can use mouse wheel if available to scroll
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editDeck(){
|
||||||
|
if (currentEvent.eventStatus == Ready){
|
||||||
|
DraftScene.instance().loadEvent(currentEvent);
|
||||||
|
Forge.switchScene(DraftScene.instance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void advance() {
|
||||||
|
switch (currentEvent.eventStatus){
|
||||||
|
case Available:
|
||||||
|
activate(entryDialog); //Entry fee pop-up
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Entered: //Start draft or select deck
|
||||||
|
//Show progress / wait indicator? Draft can take a while to generate
|
||||||
|
if (currentEvent.getDraft() != null) {
|
||||||
|
DraftScene.instance().loadEvent(currentEvent);
|
||||||
|
Forge.switchScene(DraftScene.instance());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Ready: //Commit to selected deck
|
||||||
|
//Add confirmation pop-up?
|
||||||
|
currentEvent.startEvent();
|
||||||
|
case Started: //Play next round
|
||||||
|
advance.setDisabled(true);
|
||||||
|
startRound();
|
||||||
|
break;
|
||||||
|
case Completed://Show results, allow collection of rewards
|
||||||
|
case Awarded: //Show results but don't allow any further interaction
|
||||||
|
advance.setDisabled(true);
|
||||||
|
currentEvent.giveRewards();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Abandoned: //Show results but don't allow any interaction
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean back(){
|
||||||
|
if (currentEvent.eventStatus.equals(Awarded)){
|
||||||
|
AdventureEventController.instance().finalizeEvent(currentEvent);
|
||||||
|
currentEvent = null;
|
||||||
|
}
|
||||||
|
Forge.switchScene(lastGameScene==null?GameScene.instance():lastGameScene);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startRound() {
|
||||||
|
for (AdventureEventData.AdventureEventMatch match : currentEvent.matches.get(currentEvent.currentRound)) {
|
||||||
|
match.round = currentEvent.currentRound;
|
||||||
|
if (match.winner != null) continue;
|
||||||
|
|
||||||
|
if (match.p2 == null) {
|
||||||
|
//shouldn't happen under current setup, but this would be a bye
|
||||||
|
match.winner = match.p1;
|
||||||
|
match.p1.wins +=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match.p1 instanceof AdventureEventData.AdventureEventHuman) {
|
||||||
|
humanMatch = match;
|
||||||
|
continue;
|
||||||
|
} else if (match.p2 instanceof AdventureEventData.AdventureEventHuman) {
|
||||||
|
AdventureEventData.AdventureEventParticipant placeholder = match.p1;
|
||||||
|
match.p1 = match.p2;
|
||||||
|
match.p2 = placeholder;
|
||||||
|
humanMatch = match;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
//Todo: Actually run match simulation here
|
||||||
|
if(MyRandom.percentTrue(50)){
|
||||||
|
match.p1.wins++;
|
||||||
|
match.p2.losses++;
|
||||||
|
match.winner = match.p1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
match.p1.losses++;
|
||||||
|
match.p2.wins++;
|
||||||
|
match.winner = match.p2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (humanMatch != null && humanMatch.round != currentEvent.currentRound)
|
||||||
|
humanMatch = null;
|
||||||
|
if (humanMatch != null)
|
||||||
|
{
|
||||||
|
DuelScene duelScene = DuelScene.instance();
|
||||||
|
EnemySprite enemy = humanMatch.p2.getSprite();
|
||||||
|
currentEvent.nextOpponent = humanMatch.p2;
|
||||||
|
FThreads.invokeInEdtNowOrLater(() -> {
|
||||||
|
Forge.setTransitionScreen(new TransitionScreen(() -> {
|
||||||
|
duelScene.initDuels(WorldStage.getInstance().getPlayerSprite(), enemy, false, currentEvent);
|
||||||
|
Forge.switchScene(duelScene);
|
||||||
|
}, Forge.takeScreenshot(), true, false, false, false, "", Current.player().avatar(), enemy.getAtlasPath(), Current.player().getName(), enemy.nameOverride.isEmpty() ? enemy.getData().name : enemy.nameOverride, humanMatch.p1.getRecord(), humanMatch.p2.getRecord()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
finishRound();
|
||||||
|
}
|
||||||
|
advance.setDisabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
AdventureEventData.AdventureEventMatch humanMatch = null;
|
||||||
|
|
||||||
|
public void setWinner(boolean winner) {
|
||||||
|
if (winner) {
|
||||||
|
humanMatch.winner = humanMatch.p1;
|
||||||
|
humanMatch.p1.wins++;
|
||||||
|
humanMatch.p2.losses++;
|
||||||
|
currentEvent.matchesWon++;
|
||||||
|
} else {
|
||||||
|
humanMatch.winner = humanMatch.p2;
|
||||||
|
humanMatch.p2.wins++;
|
||||||
|
humanMatch.p1.losses++;
|
||||||
|
currentEvent.matchesLost++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (winner) {
|
||||||
|
//AdventureQuestController.instance().updateQuestsWin(currentMob,enemies);
|
||||||
|
//AdventureQuestController.instance().showQuestDialogs(MapStage.this);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// AdventureQuestController.instance().updateQuestsLose(currentMob);
|
||||||
|
// AdventureQuestController.instance().showQuestDialogs(MapStage.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishRound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishRound(){
|
||||||
|
if (currentEvent.currentRound == currentEvent.rounds){
|
||||||
|
finishEvent();
|
||||||
|
}
|
||||||
|
else currentEvent.currentRound += 1;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishEvent(){
|
||||||
|
currentEvent.eventStatus = AdventureEventController.EventStatus.Completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,25 +4,45 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
|||||||
import com.github.tommyettinger.textra.TextraButton;
|
import com.github.tommyettinger.textra.TextraButton;
|
||||||
import com.github.tommyettinger.textra.TextraLabel;
|
import com.github.tommyettinger.textra.TextraLabel;
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.adventure.stage.GameHUD;
|
import forge.adventure.data.AdventureEventData;
|
||||||
|
import forge.adventure.player.AdventurePlayer;
|
||||||
|
import forge.adventure.pointofintrest.PointOfInterestChanges;
|
||||||
|
import forge.adventure.util.AdventureEventController;
|
||||||
import forge.adventure.util.Controls;
|
import forge.adventure.util.Controls;
|
||||||
import forge.adventure.util.Current;
|
import forge.adventure.util.Current;
|
||||||
|
import forge.adventure.world.WorldSave;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scene for the Inn in towns
|
* Scene for the Inn in towns
|
||||||
*/
|
*/
|
||||||
public class InnScene extends UIScene {
|
public class InnScene extends UIScene {
|
||||||
private static InnScene object;
|
private static InnScene object;
|
||||||
|
private static int localObjectId;
|
||||||
|
private static String localPointOfInterestId;
|
||||||
|
private static AdventureEventData localEvent;
|
||||||
|
Scene lastGameScene;
|
||||||
public static InnScene instance() {
|
public static InnScene instance() {
|
||||||
|
return instance(null, "",-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InnScene instance(Scene lastGameScene, String pointOfInterestId, int objectId){
|
||||||
if(object==null)
|
if(object==null)
|
||||||
object=new InnScene();
|
object=new InnScene();
|
||||||
|
|
||||||
|
changes = WorldSave.getCurrentSave().getPointOfInterestChanges(pointOfInterestId);
|
||||||
|
localPointOfInterestId = pointOfInterestId;
|
||||||
|
localObjectId = objectId;
|
||||||
|
if (lastGameScene != null)
|
||||||
|
object.lastGameScene=lastGameScene;
|
||||||
|
getLocalEvent();
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextraButton tempHitPointCost, sell, leave;
|
|
||||||
|
TextraButton tempHitPointCost, sell, leave, event;
|
||||||
Image healIcon, sellIcon, leaveIcon;
|
Image healIcon, sellIcon, leaveIcon;
|
||||||
private TextraLabel playerGold,playerShards;
|
private TextraLabel playerGold,playerShards,eventDescription;
|
||||||
|
|
||||||
private InnScene() {
|
private InnScene() {
|
||||||
|
|
||||||
@@ -39,13 +59,17 @@ public class InnScene extends UIScene {
|
|||||||
leaveIcon = ui.findActor("leaveIcon");
|
leaveIcon = ui.findActor("leaveIcon");
|
||||||
healIcon = ui.findActor("healIcon");
|
healIcon = ui.findActor("healIcon");
|
||||||
sellIcon = ui.findActor("sellIcon");
|
sellIcon = ui.findActor("sellIcon");
|
||||||
|
|
||||||
|
event = ui.findActor("event");
|
||||||
|
eventDescription = ui.findActor("eventDescription");
|
||||||
|
|
||||||
|
ui.onButtonPress("event", InnScene.this::startEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void done() {
|
public void done() {
|
||||||
GameHUD.getInstance().getTouchpad().setVisible(false);
|
Forge.switchScene(lastGameScene==null?GameScene.instance():lastGameScene);
|
||||||
Forge.switchToLast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void potionOfFalseLife() {
|
public void potionOfFalseLife() {
|
||||||
@@ -66,6 +90,7 @@ public class InnScene extends UIScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int tempHealthCost = 0;
|
int tempHealthCost = 0;
|
||||||
|
static PointOfInterestChanges changes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
@@ -74,16 +99,69 @@ public class InnScene extends UIScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refreshStatus(){
|
private void refreshStatus(){
|
||||||
|
|
||||||
tempHealthCost = Current.player().falseLifeCost();
|
tempHealthCost = Current.player().falseLifeCost();
|
||||||
boolean purchaseable = Current.player().getMaxLife() == Current.player().getLife() &&
|
boolean purchaseable = Current.player().getMaxLife() == Current.player().getLife() &&
|
||||||
tempHealthCost <= Current.player().getGold();
|
tempHealthCost <= Current.player().getGold();
|
||||||
|
|
||||||
tempHitPointCost.setDisabled(!purchaseable);
|
tempHitPointCost.setDisabled(!purchaseable);
|
||||||
tempHitPointCost.setText( tempHealthCost+"[+Gold]");
|
tempHitPointCost.setText( tempHealthCost+"[+Gold]");
|
||||||
|
|
||||||
|
getLocalEvent();
|
||||||
|
if (localEvent == null){
|
||||||
|
eventDescription.setText("[GREY]No events at this time");
|
||||||
|
event.setDisabled(true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
event.setDisabled(false);
|
||||||
|
switch (localEvent.eventStatus){
|
||||||
|
case Available:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " available");
|
||||||
|
break;
|
||||||
|
case Entered:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " [GREEN]entered");
|
||||||
|
break;
|
||||||
|
case Ready:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " [GREEN]ready");
|
||||||
|
break;
|
||||||
|
case Started:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " [GREEN]in progress");
|
||||||
|
break;
|
||||||
|
case Completed:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " [GREEN]rewards available");
|
||||||
|
break;
|
||||||
|
case Awarded:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " complete");
|
||||||
|
break;
|
||||||
|
case Abandoned:
|
||||||
|
eventDescription.setText(localEvent.format.toString() + " [RED]abandoned");
|
||||||
|
event.setDisabled(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sell() {
|
private void sell() {
|
||||||
Forge.switchScene(ShopScene.instance());
|
Forge.switchScene(ShopScene.instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static void getLocalEvent() {
|
||||||
|
localEvent = null;
|
||||||
|
for (AdventureEventData data : AdventurePlayer.current().getEvents()){
|
||||||
|
if (data.sourceID.equals(localPointOfInterestId) && data.eventOrigin == localObjectId){
|
||||||
|
localEvent = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
localEvent = AdventureEventController.instance().createEvent(AdventureEventController.EventFormat.Draft, AdventureEventController.EventStyle.Bracket, localPointOfInterestId, localObjectId, changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startEvent(){
|
||||||
|
|
||||||
|
Forge.switchScene(EventScene.instance(this, localEvent), true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package forge.adventure.scene;
|
package forge.adventure.scene;
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
import com.badlogic.gdx.scenes.scene2d.ui.*;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
@@ -17,10 +19,13 @@ import forge.adventure.util.Config;
|
|||||||
import forge.adventure.util.Controls;
|
import forge.adventure.util.Controls;
|
||||||
import forge.adventure.util.Current;
|
import forge.adventure.util.Current;
|
||||||
import forge.adventure.util.Paths;
|
import forge.adventure.util.Paths;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static forge.adventure.util.Paths.ITEMS_ATLAS;
|
||||||
|
|
||||||
public class InventoryScene extends UIScene {
|
public class InventoryScene extends UIScene {
|
||||||
TextraButton leave;
|
TextraButton leave;
|
||||||
Button equipButton;
|
Button equipButton;
|
||||||
@@ -30,10 +35,11 @@ public class InventoryScene extends UIScene {
|
|||||||
private final Array<Button> inventoryButtons = new Array<>();
|
private final Array<Button> inventoryButtons = new Array<>();
|
||||||
private final HashMap<String, Button> equipmentSlots = new HashMap<>();
|
private final HashMap<String, Button> equipmentSlots = new HashMap<>();
|
||||||
HashMap<Button, String> itemLocation = new HashMap<>();
|
HashMap<Button, String> itemLocation = new HashMap<>();
|
||||||
|
HashMap<Button, Deck> deckLocation = new HashMap<>();
|
||||||
Button selected;
|
Button selected;
|
||||||
Button deleteButton;
|
Button deleteButton;
|
||||||
Texture equipOverlay;
|
Texture equipOverlay;
|
||||||
Dialog useDialog, deleteDialog;
|
Dialog useDialog, deleteDialog, openDialog;
|
||||||
int columns = 0;
|
int columns = 0;
|
||||||
|
|
||||||
public InventoryScene() {
|
public InventoryScene() {
|
||||||
@@ -160,19 +166,47 @@ public class InventoryScene extends UIScene {
|
|||||||
ConsoleCommandInterpreter.getInstance().command(data.commandOnUse);
|
ConsoleCommandInterpreter.getInstance().command(data.commandOnUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openBooster() {
|
||||||
|
if (selected == null) return;
|
||||||
|
|
||||||
|
Deck data = (deckLocation.get(selected));
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
|
done();
|
||||||
|
RewardScene.instance().loadRewards(data, RewardScene.Type.Loot, null);
|
||||||
|
Forge.switchScene(RewardScene.instance());
|
||||||
|
Current.player().getBoostersOwned().removeValue(data, true);
|
||||||
|
}
|
||||||
|
|
||||||
private void use() {
|
private void use() {
|
||||||
ItemData data = ItemData.getItem(itemLocation.get(selected));
|
if (itemLocation.containsKey(selected)) {
|
||||||
if (data == null)
|
ItemData data = ItemData.getItem(itemLocation.get(selected));
|
||||||
return;
|
if (data == null)
|
||||||
if (useDialog == null) {
|
return;
|
||||||
useDialog = createGenericDialog("", null, Forge.getLocalizer().getMessage("lblYes"),
|
if (useDialog == null) {
|
||||||
Forge.getLocalizer().getMessage("lblNo"), () -> {
|
useDialog = createGenericDialog("", null, Forge.getLocalizer().getMessage("lblYes"),
|
||||||
this.triggerUse();
|
Forge.getLocalizer().getMessage("lblNo"), () -> {
|
||||||
removeDialog();
|
this.triggerUse();
|
||||||
}, this::removeDialog);
|
removeDialog();
|
||||||
useDialog.getContentTable().add(Controls.newTextraLabel("Use " + data.name + "?\n" + data.getDescription()));
|
}, this::removeDialog);
|
||||||
|
useDialog.getContentTable().add(Controls.newTextraLabel("Use " + data.name + "?\n" + data.getDescription()));
|
||||||
|
}
|
||||||
|
showDialog(useDialog);
|
||||||
|
}
|
||||||
|
if (deckLocation.containsKey(selected)){
|
||||||
|
Deck data = deckLocation.get(selected);
|
||||||
|
if (data == null)
|
||||||
|
return;
|
||||||
|
if (openDialog == null) {
|
||||||
|
openDialog = createGenericDialog("", null, Forge.getLocalizer().getMessage("lblYes"),
|
||||||
|
Forge.getLocalizer().getMessage("lblNo"), () -> {
|
||||||
|
this.openBooster();
|
||||||
|
removeDialog();
|
||||||
|
}, this::removeDialog);
|
||||||
|
openDialog.getContentTable().add(Controls.newTextraLabel("Open Booster Pack?"));
|
||||||
|
}
|
||||||
|
showDialog(openDialog);
|
||||||
}
|
}
|
||||||
showDialog(useDialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSelected(Button actor) {
|
private void setSelected(Button actor) {
|
||||||
@@ -187,43 +221,59 @@ public class InventoryScene extends UIScene {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ItemData data = ItemData.getItem(itemLocation.get(actor));
|
if (itemLocation.containsKey(actor)) {
|
||||||
|
ItemData data = ItemData.getItem(itemLocation.get(actor));
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
if (data == null) return;
|
deleteButton.setDisabled(data.questItem);
|
||||||
deleteButton.setDisabled(data.questItem);
|
|
||||||
|
|
||||||
boolean isInPoi = MapStage.getInstance().isInMap();
|
boolean isInPoi = MapStage.getInstance().isInMap();
|
||||||
useButton.setDisabled(!(isInPoi && data.usableInPoi || !isInPoi && data.usableOnWorldMap));
|
useButton.setDisabled(!(isInPoi && data.usableInPoi || !isInPoi && data.usableOnWorldMap));
|
||||||
if (data.shardsNeeded == 0)
|
if (data.shardsNeeded == 0)
|
||||||
useButton.setText("Use");
|
useButton.setText("Use");
|
||||||
else
|
else
|
||||||
useButton.setText("Use " + data.shardsNeeded + "[+Shards]");
|
useButton.setText("Use " + data.shardsNeeded + "[+Shards]");
|
||||||
useButton.layout();
|
useButton.layout();
|
||||||
if (Current.player().getShards() < data.shardsNeeded)
|
if (Current.player().getShards() < data.shardsNeeded)
|
||||||
useButton.setDisabled(true);
|
useButton.setDisabled(true);
|
||||||
|
|
||||||
if (data.equipmentSlot == null || data.equipmentSlot.equals("")) {
|
if (data.equipmentSlot == null || data.equipmentSlot.equals("")) {
|
||||||
equipButton.setDisabled(true);
|
equipButton.setDisabled(true);
|
||||||
} else {
|
} else {
|
||||||
equipButton.setDisabled(false);
|
equipButton.setDisabled(false);
|
||||||
if (equipButton instanceof TextraButton) {
|
if (equipButton instanceof TextraButton) {
|
||||||
TextraButton button = (TextraButton) equipButton;
|
TextraButton button = (TextraButton) equipButton;
|
||||||
String item = Current.player().itemInSlot(data.equipmentSlot);
|
String item = Current.player().itemInSlot(data.equipmentSlot);
|
||||||
if (item != null && item.equals(data.name)) {
|
if (item != null && item.equals(data.name)) {
|
||||||
button.setText("Unequip");
|
button.setText("Unequip");
|
||||||
} else {
|
} else {
|
||||||
button.setText("Equip");
|
button.setText("Equip");
|
||||||
|
}
|
||||||
|
button.layout();
|
||||||
}
|
}
|
||||||
button.layout();
|
|
||||||
}
|
}
|
||||||
|
itemDescription.setText(data.name + "\n[%98]" + data.getDescription());
|
||||||
}
|
}
|
||||||
|
else if (deckLocation.containsKey(actor)){
|
||||||
|
Deck data = (deckLocation.get(actor));
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
|
deleteButton.setDisabled(true);
|
||||||
|
useButton.setDisabled(false);
|
||||||
|
useButton.setText("Open");
|
||||||
|
useButton.layout();
|
||||||
|
equipButton.setDisabled(true);
|
||||||
|
|
||||||
|
itemDescription.setText("Card Pack - " + data.getName() + "\n[%98]" + (data.getComment() == null?"":data.getComment()+" - ") + data.getAllCardsInASinglePool().countAll() + " cards");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (Button button : inventoryButtons) {
|
for (Button button : inventoryButtons) {
|
||||||
if (actor != button && button.isChecked()) {
|
if (actor != button && button.isChecked()) {
|
||||||
button.setChecked(false);
|
button.setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemDescription.setText(data.name + "\n[%98]" + data.getDescription());
|
|
||||||
performTouch(scrollPaneOfActor(itemDescription)); //can use mouse wheel if available to scroll after selection
|
performTouch(scrollPaneOfActor(itemDescription)); //can use mouse wheel if available to scroll after selection
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +282,9 @@ public class InventoryScene extends UIScene {
|
|||||||
inventoryButtons.clear();
|
inventoryButtons.clear();
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
Current.player().getItems().sort();
|
Current.player().getItems().sort();
|
||||||
|
|
||||||
|
int itemSlotsUsed = 0;
|
||||||
|
|
||||||
for (int i = 0; i < Current.player().getItems().size; i++) {
|
for (int i = 0; i < Current.player().getItems().size; i++) {
|
||||||
|
|
||||||
if (i % columns == 0)
|
if (i % columns == 0)
|
||||||
@@ -274,7 +327,47 @@ public class InventoryScene extends UIScene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
itemSlotsUsed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Current.player().getBoostersOwned().size; i++) {
|
||||||
|
|
||||||
|
if ((i + itemSlotsUsed) % columns == 0)
|
||||||
|
inventory.row();
|
||||||
|
Button newActor = createInventorySlot();
|
||||||
|
inventory.add(newActor).top().left().space(1);
|
||||||
|
addToSelectable(new Selectable(newActor) {
|
||||||
|
@Override
|
||||||
|
public void onSelect(UIScene scene) {
|
||||||
|
setSelected(newActor);
|
||||||
|
super.onSelect(scene);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
inventoryButtons.add(newActor);
|
||||||
|
Deck deck = Current.player().getBoostersOwned().get(i);
|
||||||
|
if (deck == null | deck.isEmpty()) {
|
||||||
|
System.err.print("Can not add null / empty booster " + Current.player().getBoostersOwned().get(i) + "\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TextureAtlas atlas = Config.instance().getAtlas(ITEMS_ATLAS);
|
||||||
|
Sprite deckSprite = atlas.createSprite("Deck");
|
||||||
|
|
||||||
|
Image img = new Image(deckSprite);
|
||||||
|
img.setX((newActor.getWidth() - img.getWidth()) / 2);
|
||||||
|
img.setY((newActor.getHeight() - img.getHeight()) / 2);
|
||||||
|
newActor.addActor(img);
|
||||||
|
deckLocation.put(newActor, Current.player().getBoostersOwned().get(i));
|
||||||
|
newActor.addListener(new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
|
if (((Button) actor).isChecked()) {
|
||||||
|
setSelected((Button) actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (Map.Entry<String, Button> slot : equipmentSlots.entrySet()) {
|
for (Map.Entry<String, Button> slot : equipmentSlots.entrySet()) {
|
||||||
if (slot.getValue().getChildren().size >= 2)
|
if (slot.getValue().getChildren().size >= 2)
|
||||||
slot.getValue().removeActorAt(1, false);
|
slot.getValue().removeActorAt(1, false);
|
||||||
|
|||||||
295
forge-gui-mobile/src/forge/adventure/scene/MenuScene.java
Normal file
295
forge-gui-mobile/src/forge/adventure/scene/MenuScene.java
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
package forge.adventure.scene;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.Timer;
|
||||||
|
import com.github.tommyettinger.textra.TextraButton;
|
||||||
|
import com.github.tommyettinger.textra.TypingAdapter;
|
||||||
|
import com.github.tommyettinger.textra.TypingLabel;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.adventure.data.DialogData;
|
||||||
|
import forge.adventure.data.RewardData;
|
||||||
|
import forge.adventure.player.AdventurePlayer;
|
||||||
|
import forge.adventure.util.Controls;
|
||||||
|
import forge.adventure.util.Current;
|
||||||
|
import forge.adventure.util.Reward;
|
||||||
|
import forge.card.ColorSet;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MenuScene
|
||||||
|
* Superclass for menu scenes which do not have HUD but need dialog functionality
|
||||||
|
*/
|
||||||
|
public class MenuScene extends UIScene {
|
||||||
|
protected final Dialog dialog;
|
||||||
|
private final Array<TextraButton> dialogButtonMap = new Array<>();
|
||||||
|
protected java.util.List<ChangeListener> dialogCompleteList = new ArrayList<>();
|
||||||
|
|
||||||
|
public MenuScene(String uiFilePath) {
|
||||||
|
super(uiFilePath);
|
||||||
|
dialog = Controls.newDialog("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dialog getDialog() {
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean activate(Array<DialogData> data) { //Method for actors to show their dialogues.
|
||||||
|
boolean dialogShown = false;
|
||||||
|
if (data != null) {
|
||||||
|
for (DialogData dialog : data) {
|
||||||
|
if (isConditionOk(dialog.condition)) {
|
||||||
|
loadDialog(dialog);
|
||||||
|
dialogShown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dialogShown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEffects(DialogData.ActionData[] data) {
|
||||||
|
if (data == null) return;
|
||||||
|
for (DialogData.ActionData E : data) {
|
||||||
|
if (E == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (E.removeItem != null && (!E.removeItem.isEmpty())) { //Removes an item from the player's inventory.
|
||||||
|
Current.player().removeItem(E.removeItem);
|
||||||
|
}
|
||||||
|
if (E.addItem != null && (!E.addItem.isEmpty())) { //Gives an item to the player.
|
||||||
|
Current.player().addItem(E.addItem);
|
||||||
|
}
|
||||||
|
if (E.addLife != 0) { //Gives (positive or negative) life to the player. Cannot go over max health.
|
||||||
|
Current.player().heal(E.addLife);
|
||||||
|
}
|
||||||
|
if (E.addGold != 0) { //Gives (positive or negative) gold to the player.
|
||||||
|
if (E.addGold > 0) Current.player().giveGold(E.addGold);
|
||||||
|
else Current.player().takeGold(-E.addGold);
|
||||||
|
}
|
||||||
|
if (E.addShards != 0) { //Gives (positive or negative) mana shards to the player.
|
||||||
|
if (E.addShards > 0) Current.player().addShards(E.addShards);
|
||||||
|
else Current.player().takeShards(-E.addShards);
|
||||||
|
}
|
||||||
|
if (E.giveBlessing != null) { //Gives a blessing for your next battle.
|
||||||
|
Current.player().addBlessing(E.giveBlessing);
|
||||||
|
}
|
||||||
|
if (E.setColorIdentity != null && !E.setColorIdentity.isEmpty()) { //Sets color identity (use sparingly)
|
||||||
|
Current.player().setColorIdentity(E.setColorIdentity);
|
||||||
|
}
|
||||||
|
if (E.setQuestFlag != null && !E.setQuestFlag.key.isEmpty()) { //Set a quest to given value.
|
||||||
|
Current.player().setQuestFlag(E.setQuestFlag.key, E.setQuestFlag.val);
|
||||||
|
}
|
||||||
|
if (E.advanceQuestFlag != null && !E.advanceQuestFlag.isEmpty()) { //Increase a given quest flag by 1.
|
||||||
|
Current.player().advanceQuestFlag(E.advanceQuestFlag);
|
||||||
|
}
|
||||||
|
if (E.grantRewards != null && E.grantRewards.length > 0) {
|
||||||
|
Array<Reward> ret = new Array<Reward>();
|
||||||
|
for (RewardData rdata : E.grantRewards) {
|
||||||
|
ret.addAll(rdata.generate(false, true));
|
||||||
|
}
|
||||||
|
RewardScene.instance().loadRewards(ret, RewardScene.Type.QuestReward, null);
|
||||||
|
Forge.switchScene(RewardScene.instance());
|
||||||
|
}
|
||||||
|
// if (E.issueQuest != null && (!E.issueQuest.isEmpty())) {
|
||||||
|
// emitQuestAccepted();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadDialog(DialogData dialog) { //Displays a dialog with dialogue and possible choices.
|
||||||
|
setEffects(dialog.action);
|
||||||
|
Dialog D = getDialog();
|
||||||
|
Localizer L = Forge.getLocalizer();
|
||||||
|
D.getTitleTable().clear();
|
||||||
|
D.getContentTable().clear();
|
||||||
|
D.getButtonTable().clear(); //Clear tables to start fresh.
|
||||||
|
D.clearListeners();
|
||||||
|
// Sprite sprite = null;
|
||||||
|
|
||||||
|
// Actor actor = stage.getByID(parentID);
|
||||||
|
// if (actor instanceof CharacterSprite)
|
||||||
|
// sprite = ((CharacterSprite) actor).getAvatar();
|
||||||
|
String text; //Check for localized string (locname), otherwise print text.
|
||||||
|
if (dialog.loctext != null && !dialog.loctext.isEmpty()) text = L.getMessage(dialog.loctext);
|
||||||
|
else text = dialog.text;
|
||||||
|
|
||||||
|
TypingLabel A = Controls.newTypingLabel(text);
|
||||||
|
A.setWrap(true);
|
||||||
|
Array<TextraButton> buttons = new Array<>();
|
||||||
|
A.setTypingListener(new TypingAdapter() {
|
||||||
|
@Override
|
||||||
|
public void end() {
|
||||||
|
float delay = 0.09f;
|
||||||
|
for (TextraButton button : buttons) {
|
||||||
|
Timer.schedule(new Timer.Task() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
button.setVisible(true);
|
||||||
|
}
|
||||||
|
}, delay);
|
||||||
|
delay += 0.10f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
float width = 250f;
|
||||||
|
|
||||||
|
D.getContentTable().add(A).width(width); //Add() returns a Cell, which is what the width is being applied to.
|
||||||
|
if (dialog.options != null) {
|
||||||
|
int i = 0;
|
||||||
|
for (DialogData option : dialog.options) {
|
||||||
|
if (isConditionOk(option.condition)) {
|
||||||
|
String name; //Get localized label if present.
|
||||||
|
if (option.locname != null && !option.locname.isEmpty()) name = L.getMessage(option.locname);
|
||||||
|
else name = option.name;
|
||||||
|
TextraButton B = Controls.newTextButton(name, () -> {
|
||||||
|
loadDialog(option);
|
||||||
|
|
||||||
|
if (option.callback != null) {
|
||||||
|
option.callback.run(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
B.getTextraLabel().setWrap(true); //We want this to wrap in case it's a wordy choice.
|
||||||
|
buttons.add(B);
|
||||||
|
B.setVisible(false);
|
||||||
|
D.getButtonTable().add(B).width(width - 10); //The button table also returns a Cell when adding.
|
||||||
|
//TODO: Reducing the space a tiny bit could help. But should be fine as long as there aren't more than 4-5 options.
|
||||||
|
D.getButtonTable().row(); //Add a row. Tried to allow a few per row but it was a bit erratic.
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
D.addListener(new ClickListener() {
|
||||||
|
@Override
|
||||||
|
public void clicked(InputEvent event, float x, float y) {
|
||||||
|
A.skipToTheEnd();
|
||||||
|
super.clicked(event, x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (i == 0) {
|
||||||
|
hideDialog();
|
||||||
|
emitDialogFinished();
|
||||||
|
} else
|
||||||
|
showDialog(getDialog());
|
||||||
|
} else {
|
||||||
|
hideDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDialogCompleteListener(ChangeListener listener) {
|
||||||
|
dialogCompleteList.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void emitDialogFinished() {
|
||||||
|
if (dialogCompleteList != null && dialogCompleteList.size() > 0) {
|
||||||
|
ChangeListener.ChangeEvent evt = new ChangeListener.ChangeEvent();
|
||||||
|
for (ChangeListener listener : dialogCompleteList) {
|
||||||
|
listener.changed(evt, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConditionOk(DialogData.ConditionData[] data) {
|
||||||
|
if (data == null) return true;
|
||||||
|
AdventurePlayer player = Current.player();
|
||||||
|
for (DialogData.ConditionData condition : data) {
|
||||||
|
//TODO:Check for card in inventory.
|
||||||
|
if (condition.item != null && !condition.item.isEmpty()) { //Check for an item in player's inventory.
|
||||||
|
if (!player.hasItem(condition.item)) {
|
||||||
|
if (!condition.not) return false; //Only return on a false.
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
if (condition.colorIdentity != null && !condition.colorIdentity.isEmpty()) { //Check for player's color ID.
|
||||||
|
if (player.getColorIdentity().hasAllColors(ColorSet.fromNames(condition.colorIdentity.toCharArray()).getColor())) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
if (condition.hasGold != 0) { //Check for at least X gold.
|
||||||
|
if (player.getGold() < condition.hasGold) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
if (condition.hasShards != 0) { //Check for at least X gold.
|
||||||
|
if (player.getShards() < condition.hasShards) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
if (condition.hasLife != 0) { //Check for at least X life..
|
||||||
|
if (player.getLife() < condition.hasLife + 1) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
if (condition.hasBlessing != null && !condition.hasBlessing.isEmpty()) { //Check for a named blessing.
|
||||||
|
if (!player.hasBlessing(condition.hasBlessing)) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition.getQuestFlag != null) {
|
||||||
|
String key = condition.getQuestFlag.key;
|
||||||
|
String cond = condition.getQuestFlag.op;
|
||||||
|
int val = condition.getQuestFlag.val;
|
||||||
|
int QF = player.getQuestFlag(key);
|
||||||
|
if (!player.checkQuestFlag(key)) return false; //If the quest is not ongoing, stop.
|
||||||
|
if (!checkFlagCondition(QF, cond, val)) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else {
|
||||||
|
if (condition.not) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (condition.checkQuestFlag != null && !condition.checkQuestFlag.isEmpty()) {
|
||||||
|
if (!player.checkQuestFlag(condition.checkQuestFlag)) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkFlagCondition(int flag, String condition, int value) {
|
||||||
|
switch (condition.toUpperCase()) {
|
||||||
|
default:
|
||||||
|
case "EQUALS":
|
||||||
|
case "EQUAL":
|
||||||
|
case "=":
|
||||||
|
if (flag == value) return true;
|
||||||
|
case "LESSTHAN":
|
||||||
|
case "<":
|
||||||
|
if (flag < value) return true;
|
||||||
|
case "MORETHAN":
|
||||||
|
case ">":
|
||||||
|
if (flag > value) return true;
|
||||||
|
case "LE_THAN":
|
||||||
|
case "<=":
|
||||||
|
if (flag <= value) return true;
|
||||||
|
case "ME_THAN":
|
||||||
|
case ">=":
|
||||||
|
if (flag >= value) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDialog(Array<DialogData> data) {
|
||||||
|
if (!activate(data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogButtonMap.clear();
|
||||||
|
for (int i = 0; i < dialog.getButtonTable().getCells().size; i++) {
|
||||||
|
dialogButtonMap.add((TextraButton) dialog.getButtonTable().getCells().get(i).getActor());
|
||||||
|
}
|
||||||
|
dialog.show(stage, Actions.show());
|
||||||
|
dialog.setPosition((stage.getWidth() - dialog.getWidth()) / 2, (stage.getHeight() - dialog.getHeight()) / 2);
|
||||||
|
if (Forge.hasGamepad() && !dialogButtonMap.isEmpty())
|
||||||
|
stage.setKeyboardFocus(dialogButtonMap.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideDialog() {
|
||||||
|
dialog.hide();
|
||||||
|
dialog.clearListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,9 +39,9 @@ public class PlayerStatisticScene extends UIScene {
|
|||||||
Image avatar, avatarBorder;
|
Image avatar, avatarBorder;
|
||||||
Image colorFrame;
|
Image colorFrame;
|
||||||
TextraLabel money, life, shards;
|
TextraLabel money, life, shards;
|
||||||
TextraLabel wins, totalWins;
|
TextraLabel wins, totalWins, eventWins, eventMatchWins;
|
||||||
TextraLabel loss, totalLoss;
|
TextraLabel loss, totalLoss, eventLosses, eventMatchLosses;
|
||||||
TextraLabel winloss, lossWinRatio;
|
TextraLabel winloss, lossWinRatio, eventLossWinRatio, eventMatchLossWinRatio;
|
||||||
TextraLabel playerName, headerAchievements, headerAvatar, headerName, headerWinLoss;
|
TextraLabel playerName, headerAchievements, headerAvatar, headerName, headerWinLoss;
|
||||||
TextraButton back, toggleAward;
|
TextraButton back, toggleAward;
|
||||||
private final Table scrollContainer, achievementContainer;
|
private final Table scrollContainer, achievementContainer;
|
||||||
@@ -78,6 +78,22 @@ public class PlayerStatisticScene extends UIScene {
|
|||||||
totalLoss = ui.findActor("totalLoss");
|
totalLoss = ui.findActor("totalLoss");
|
||||||
winloss = ui.findActor("winloss");
|
winloss = ui.findActor("winloss");
|
||||||
lossWinRatio = ui.findActor("lossWinRatio");
|
lossWinRatio = ui.findActor("lossWinRatio");
|
||||||
|
|
||||||
|
eventMatchWins = ui.findActor("eventMatchWins");
|
||||||
|
eventMatchLosses = ui.findActor("eventMatchLosses");
|
||||||
|
eventMatchLossWinRatio = ui.findActor("eventMatchLossWinRatio");
|
||||||
|
|
||||||
|
eventWins = ui.findActor("eventWins");
|
||||||
|
eventLosses = ui.findActor("eventLosses");
|
||||||
|
eventLossWinRatio = ui.findActor("eventLossWinRatio");
|
||||||
|
|
||||||
|
totalWins = ui.findActor("totalWins");
|
||||||
|
loss = ui.findActor("loss");
|
||||||
|
totalLoss = ui.findActor("totalLoss");
|
||||||
|
winloss = ui.findActor("winloss");
|
||||||
|
lossWinRatio = ui.findActor("lossWinRatio");
|
||||||
|
|
||||||
|
|
||||||
back = ui.findActor("return");
|
back = ui.findActor("return");
|
||||||
toggleAward = ui.findActor("toggleAward");
|
toggleAward = ui.findActor("toggleAward");
|
||||||
headerAchievements = Controls.newTextraLabel("[%110]" + Forge.getLocalizer().getMessage("lblAchievements"));
|
headerAchievements = Controls.newTextraLabel("[%110]" + Forge.getLocalizer().getMessage("lblAchievements"));
|
||||||
@@ -200,6 +216,25 @@ public class PlayerStatisticScene extends UIScene {
|
|||||||
if (lossWinRatio != null) {
|
if (lossWinRatio != null) {
|
||||||
lossWinRatio.setText(Float.toString(Current.player().getStatistic().winLossRatio()));
|
lossWinRatio.setText(Float.toString(Current.player().getStatistic().winLossRatio()));
|
||||||
}
|
}
|
||||||
|
if (eventMatchWins != null) {
|
||||||
|
eventMatchWins.setText(String.valueOf(Current.player().getStatistic().eventWins()));
|
||||||
|
}
|
||||||
|
if (eventMatchLosses != null) {
|
||||||
|
eventMatchLosses.setText(String.valueOf(Current.player().getStatistic().eventMatchLosses()));
|
||||||
|
}
|
||||||
|
if (eventMatchLossWinRatio != null) {
|
||||||
|
eventMatchLossWinRatio.setText(Float.toString(Current.player().getStatistic().eventMatchWinLossRatio()));
|
||||||
|
}
|
||||||
|
if (eventWins != null) {
|
||||||
|
eventWins.setText(String.valueOf(Current.player().getStatistic().eventWins()));
|
||||||
|
}
|
||||||
|
if (eventLosses != null) {
|
||||||
|
eventLosses.setText(String.valueOf(Current.player().getStatistic().eventLosses()));
|
||||||
|
}
|
||||||
|
if (eventLossWinRatio != null) {
|
||||||
|
eventLossWinRatio.setText(Float.toString(Current.player().getStatistic().eventWinLossRatio()));
|
||||||
|
}
|
||||||
|
|
||||||
if (colorFrame != null) {
|
if (colorFrame != null) {
|
||||||
colorFrame.setDrawable(new TextureRegionDrawable(getColorFrame(Current.player().getColorIdentity())));
|
colorFrame.setDrawable(new TextureRegionDrawable(getColorFrame(Current.player().getColorIdentity())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import forge.adventure.stage.GameHUD;
|
|||||||
import forge.adventure.util.*;
|
import forge.adventure.util.*;
|
||||||
import forge.adventure.world.WorldSave;
|
import forge.adventure.world.WorldSave;
|
||||||
import forge.assets.ImageCache;
|
import forge.assets.ImageCache;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.item.PaperCard;
|
||||||
import forge.sound.SoundEffectType;
|
import forge.sound.SoundEffectType;
|
||||||
import forge.sound.SoundSystem;
|
import forge.sound.SoundSystem;
|
||||||
|
|
||||||
@@ -279,6 +281,14 @@ public class RewardScene extends UIScene {
|
|||||||
loadRewards(ret, RewardScene.Type.Shop,shopActor);
|
loadRewards(ret, RewardScene.Type.Shop,shopActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadRewards(Deck deck, Type type, ShopActor shopActor){
|
||||||
|
Array<Reward> rewards = new Array<>();
|
||||||
|
for (PaperCard card : deck.getAllCardsInASinglePool().toFlatList()){
|
||||||
|
rewards.add(new Reward(card));
|
||||||
|
}
|
||||||
|
loadRewards(rewards, type, shopActor);
|
||||||
|
}
|
||||||
|
|
||||||
public void loadRewards(Array<Reward> newRewards, Type type, ShopActor shopActor) {
|
public void loadRewards(Array<Reward> newRewards, Type type, ShopActor shopActor) {
|
||||||
clearSelectable();
|
clearSelectable();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class ShopScene extends ForgeScene {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public FScreen getScreen() {
|
public FScreen getScreen() {
|
||||||
return screen==null?screen = new AdventureDeckEditor(true):screen;
|
return screen==null?screen = new AdventureDeckEditor(true, null):screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ public class MapStage extends GameStage {
|
|||||||
//TODO: Ability to move them (using a sequence such as "UULU" for up, up, left, up).
|
//TODO: Ability to move them (using a sequence such as "UULU" for up, up, left, up).
|
||||||
break;
|
break;
|
||||||
case "inn":
|
case "inn":
|
||||||
addMapActor(obj, new OnCollide(() -> Forge.switchScene(InnScene.instance())));
|
addMapActor(obj, new OnCollide(() -> Forge.switchScene(InnScene.instance(TileMapScene.instance(), TileMapScene.instance().rootPoint.getID(), id))));
|
||||||
break;
|
break;
|
||||||
case "spellsmith":
|
case "spellsmith":
|
||||||
addMapActor(obj, new OnCollide(() -> Forge.switchScene(SpellSmithScene.instance())));
|
addMapActor(obj, new OnCollide(() -> Forge.switchScene(SpellSmithScene.instance())));
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package forge.adventure.util;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.Json;
|
||||||
|
import forge.StaticData;
|
||||||
|
import forge.adventure.data.AdventureEventData;
|
||||||
|
import forge.adventure.player.AdventurePlayer;
|
||||||
|
import forge.adventure.pointofintrest.PointOfInterestChanges;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.item.generation.BoosterGenerator;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class AdventureEventController implements Serializable {
|
||||||
|
|
||||||
|
public void finalizeEvent(AdventureEventData completedEvent) {
|
||||||
|
Current.player().getStatistic().setResult(completedEvent);
|
||||||
|
Current.player().removeEvent(completedEvent);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EventFormat{
|
||||||
|
Draft,
|
||||||
|
Sealed,
|
||||||
|
Constructed
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EventStyle{
|
||||||
|
Bracket,
|
||||||
|
RoundRobin,
|
||||||
|
Swiss
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EventStatus{
|
||||||
|
Available, //New event
|
||||||
|
Entered, //Entry fee paid, deck not locked in
|
||||||
|
Ready, //Deck is registered but can still be edited
|
||||||
|
Started, //Matches available
|
||||||
|
Completed, //All matches complete, rewards pending
|
||||||
|
Awarded, //Rewards distributed
|
||||||
|
Abandoned //Ended without completing all matches
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AdventureEventController object;
|
||||||
|
|
||||||
|
public static AdventureEventController instance() {
|
||||||
|
if (object == null) {
|
||||||
|
object = new AdventureEventController();
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AdventureEventController(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private transient Array<AdventureEventData> allEvents = new Array<>();
|
||||||
|
private Map<String, Long> nextEventDate = new HashMap<>();
|
||||||
|
|
||||||
|
public AdventureEventController(AdventureEventController other){
|
||||||
|
if (object == null) {
|
||||||
|
object = this;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
System.out.println("Could not initialize AdventureEventController. An instance already exists and cannot be merged.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clear(){
|
||||||
|
object = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdventureEventData createEvent(EventFormat format, EventStyle style, String pointID, int eventOrigin, PointOfInterestChanges changes)
|
||||||
|
{
|
||||||
|
if (nextEventDate.containsKey(pointID) && nextEventDate.get(pointID) >= LocalDate.now().toEpochDay()){
|
||||||
|
//No event currently available here
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
long eventSeed;
|
||||||
|
long timeSeed = LocalDate.now().toEpochDay();
|
||||||
|
long placeSeed = Long.parseLong(pointID.replaceAll("[^0-9]",""));
|
||||||
|
long room = Long.MAX_VALUE - placeSeed;
|
||||||
|
if (timeSeed > room){
|
||||||
|
//ensuring we don't ever hit an overflow
|
||||||
|
eventSeed = Long.MIN_VALUE + timeSeed - room;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventSeed = timeSeed + placeSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new Random(eventSeed).nextInt(10) <=6){
|
||||||
|
//60% chance of new event being available in a given location on a day by day basis.
|
||||||
|
//This is intentionally cumulative with the potential nextEventDate lockout to encourage moving around map
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdventureEventData e = new AdventureEventData(eventSeed);
|
||||||
|
if (e.cardBlock == null){
|
||||||
|
//covers cases where (somehow) metaset only editions (like jumpstart) have been picked up
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
e.sourceID = pointID;
|
||||||
|
e.eventOrigin = eventOrigin;
|
||||||
|
e.format = format;
|
||||||
|
e.eventRules = new AdventureEventData.AdventureEventRules();
|
||||||
|
e.eventRules.acceptsChallengeCoin = true;
|
||||||
|
e.eventRules.goldToEnter = (int)((changes.getTownPriceModifier() == -1.0f? 1: changes.getTownPriceModifier())* 3000);
|
||||||
|
e.eventRules.shardsToEnter = (int)((changes.getTownPriceModifier() == -1.0f? 1: changes.getTownPriceModifier())* 50);
|
||||||
|
e.style = style;
|
||||||
|
|
||||||
|
switch (style){
|
||||||
|
case Swiss:
|
||||||
|
case Bracket:
|
||||||
|
e.rounds = (e.participants.length / 2) - 1;
|
||||||
|
break;
|
||||||
|
case RoundRobin:
|
||||||
|
e.rounds = e.participants.length - 1 ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdventurePlayer.current().addEvent(e);
|
||||||
|
nextEventDate.put(pointID, LocalDate.now().toEpochDay() + new Random().nextInt(2)); //next local event availability date
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Deck generateBooster(String setCode) {
|
||||||
|
List<PaperCard> cards = BoosterGenerator.getBoosterPack(StaticData.instance().getBoosters().get(setCode));
|
||||||
|
Deck output = new Deck();
|
||||||
|
output.getMain().add(cards);
|
||||||
|
output.setName("Booster Pack: " + setCode);
|
||||||
|
output.setComment(setCode);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,9 @@ public class AdventureQuestController implements Serializable {
|
|||||||
Defeat,
|
Defeat,
|
||||||
Delivery,
|
Delivery,
|
||||||
Escort,
|
Escort,
|
||||||
|
EventFinish,
|
||||||
|
EventWin,
|
||||||
|
EventWinMatches,
|
||||||
Fetch,
|
Fetch,
|
||||||
Find,
|
Find,
|
||||||
Gather,
|
Gather,
|
||||||
@@ -171,6 +174,10 @@ public class AdventureQuestController implements Serializable {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void clear(){
|
||||||
|
object = null;
|
||||||
|
}
|
||||||
|
|
||||||
private AdventureQuestController(){
|
private AdventureQuestController(){
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -280,6 +287,12 @@ public class AdventureQuestController implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateEventComplete(AdventureEventData completedEvent) {
|
||||||
|
for(AdventureQuestData currentQuest: Current.player().getQuests()) {
|
||||||
|
currentQuest.updateEventComplete(completedEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AdventureQuestData generateQuest(int id){
|
public AdventureQuestData generateQuest(int id){
|
||||||
AdventureQuestData generated = null;
|
AdventureQuestData generated = null;
|
||||||
for (AdventureQuestData template: allQuests) {
|
for (AdventureQuestData template: allQuests) {
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package forge.adventure.util;
|
|||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import com.badlogic.gdx.utils.Json;
|
import com.badlogic.gdx.utils.Json;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.adventure.data.GeneratedDeckData;
|
import forge.adventure.data.GeneratedDeckData;
|
||||||
import forge.adventure.data.GeneratedDeckTemplateData;
|
import forge.adventure.data.GeneratedDeckTemplateData;
|
||||||
|
import forge.adventure.data.ItemData;
|
||||||
import forge.adventure.data.RewardData;
|
import forge.adventure.data.RewardData;
|
||||||
import forge.card.*;
|
import forge.card.*;
|
||||||
import forge.card.mana.ManaCostShard;
|
import forge.card.mana.ManaCostShard;
|
||||||
@@ -14,11 +16,16 @@ import forge.deck.Deck;
|
|||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
import forge.deck.DeckgenUtil;
|
import forge.deck.DeckgenUtil;
|
||||||
import forge.deck.io.DeckSerializer;
|
import forge.deck.io.DeckSerializer;
|
||||||
|
import forge.game.GameFormat;
|
||||||
|
import forge.gamemodes.quest.QuestController;
|
||||||
|
import forge.item.BoosterPack;
|
||||||
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.item.SealedProduct;
|
import forge.item.SealedProduct;
|
||||||
import forge.item.generation.UnOpenedProduct;
|
import forge.item.generation.UnOpenedProduct;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -654,6 +661,62 @@ public class CardUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final GameFormat.Collection formats = FModel.getFormats();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final Predicate<CardEdition> filterPioneer = formats.getPioneer().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterModern= formats.getModern().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterVintage = formats.getVintage().editionLegalPredicate;
|
||||||
|
private static final Predicate<CardEdition> filterStandard = formats.getStandard().editionLegalPredicate;
|
||||||
|
public static Deck generateStandardBoosterAsDeck(){
|
||||||
|
return generateRandomBoosterPackAsDeck(filterStandard);
|
||||||
|
}
|
||||||
|
public static Deck generatePioneerBoosterAsDeck(){
|
||||||
|
return generateRandomBoosterPackAsDeck(filterPioneer);
|
||||||
|
}
|
||||||
|
public static Deck generateModernBoosterAsDeck(){
|
||||||
|
return generateRandomBoosterPackAsDeck(filterModern);
|
||||||
|
}
|
||||||
|
public static Deck generateVintageBoosterAsDeck(){
|
||||||
|
return generateRandomBoosterPackAsDeck(filterVintage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Deck generateBoosterPackAsDeck(String code){
|
||||||
|
|
||||||
|
if (Arrays.asList(Config.instance().getConfigData().restrictedEditions).contains(code)){
|
||||||
|
System.err.println("Cannot generate booster pack, '" + code + "' is a restricted edition");
|
||||||
|
}
|
||||||
|
|
||||||
|
CardEdition edition = StaticData.instance().getEditions().get(code);
|
||||||
|
if (edition == null){
|
||||||
|
System.err.println("Set code '" + code + "' not found.");
|
||||||
|
return new Deck();
|
||||||
|
}
|
||||||
|
BoosterPack cards = BoosterPack.FN_FROM_SET.apply(edition);
|
||||||
|
return generateBoosterPackAsDeck(edition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Deck generateBoosterPackAsDeck(CardEdition edition){
|
||||||
|
Deck d = new Deck("Booster pack");
|
||||||
|
d.setComment(edition.getCode());
|
||||||
|
d.getMain().add(BoosterPack.FN_FROM_SET.apply(edition).getCards());
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Deck generateRandomBoosterPackAsDeck(final Predicate<CardEdition> editionFilter) {
|
||||||
|
Predicate<CardEdition> filter = Predicates.and(CardEdition.Predicates.CAN_MAKE_BOOSTER, editionFilter);
|
||||||
|
Iterable<CardEdition> possibleEditions = Iterables.filter(FModel.getMagicDb().getEditions(), filter);
|
||||||
|
|
||||||
|
if (!possibleEditions.iterator().hasNext()) {
|
||||||
|
System.err.println("No sets found matching edition filter that can create boosters.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardEdition edition = Aggregates.random(possibleEditions);
|
||||||
|
return generateBoosterPackAsDeck(edition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -305,6 +305,10 @@ public class MapDialog {
|
|||||||
if (E.addGold > 0) Current.player().giveGold(E.addGold);
|
if (E.addGold > 0) Current.player().giveGold(E.addGold);
|
||||||
else Current.player().takeGold(-E.addGold);
|
else Current.player().takeGold(-E.addGold);
|
||||||
}
|
}
|
||||||
|
if (E.addShards != 0) { //Gives (positive or negative) mana shards to the player.
|
||||||
|
if (E.addShards > 0) Current.player().giveGold(E.addShards);
|
||||||
|
else Current.player().takeGold(-E.addShards);
|
||||||
|
}
|
||||||
if (E.addMapReputation != 0) {
|
if (E.addMapReputation != 0) {
|
||||||
PointOfInterestChanges p;
|
PointOfInterestChanges p;
|
||||||
if (E.POIReference.length()>0 && !E.POIReference.contains("$"))
|
if (E.POIReference.length()>0 && !E.POIReference.contains("$"))
|
||||||
@@ -391,6 +395,11 @@ public class MapDialog {
|
|||||||
if (!condition.not) return false;
|
if (!condition.not) return false;
|
||||||
} else if (condition.not) return false;
|
} else if (condition.not) return false;
|
||||||
}
|
}
|
||||||
|
if (condition.hasShards != 0) { //Check for at least X gold.
|
||||||
|
if (player.getShards() < condition.hasShards) {
|
||||||
|
if (!condition.not) return false;
|
||||||
|
} else if (condition.not) return false;
|
||||||
|
}
|
||||||
if (condition.hasLife != 0) { //Check for at least X life..
|
if (condition.hasLife != 0) { //Check for at least X life..
|
||||||
if (player.getLife() < condition.hasLife + 1) {
|
if (player.getLife() < condition.hasLife + 1) {
|
||||||
if (!condition.not) return false;
|
if (!condition.not) return false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.adventure.util;
|
package forge.adventure.util;
|
||||||
|
|
||||||
import forge.adventure.data.ItemData;
|
import forge.adventure.data.ItemData;
|
||||||
|
import forge.deck.Deck;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,11 +13,13 @@ public class Reward {
|
|||||||
Gold,
|
Gold,
|
||||||
Item,
|
Item,
|
||||||
Life,
|
Life,
|
||||||
Shards
|
Shards,
|
||||||
|
CardPack
|
||||||
}
|
}
|
||||||
Type type;
|
Type type;
|
||||||
PaperCard card;
|
PaperCard card;
|
||||||
ItemData item;
|
ItemData item;
|
||||||
|
Deck deck;
|
||||||
private final int count;
|
private final int count;
|
||||||
|
|
||||||
public Reward(ItemData item) {
|
public Reward(ItemData item) {
|
||||||
@@ -37,8 +40,14 @@ public class Reward {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
this.count = count;
|
this.count = count;
|
||||||
}
|
}
|
||||||
|
public Reward(Deck deck) {
|
||||||
|
type = Type.CardPack;
|
||||||
|
this.deck = deck;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
public PaperCard getCard() { return card; }
|
public PaperCard getCard() { return card; }
|
||||||
public ItemData getItem() { return item; }
|
public ItemData getItem() { return item; }
|
||||||
|
public Deck getDeck() { return deck; }
|
||||||
public Type getType() { return type; }
|
public Type getType() { return type; }
|
||||||
public int getCount() { return count; }
|
public int getCount() { return count; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,12 @@ import com.github.tommyettinger.textra.TextraLabel;
|
|||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
|
import forge.StaticData;
|
||||||
import forge.adventure.data.ItemData;
|
import forge.adventure.data.ItemData;
|
||||||
import forge.adventure.scene.RewardScene;
|
import forge.adventure.scene.RewardScene;
|
||||||
import forge.adventure.scene.Scene;
|
import forge.adventure.scene.Scene;
|
||||||
import forge.adventure.scene.UIScene;
|
import forge.adventure.scene.UIScene;
|
||||||
|
import forge.assets.FImageComplex;
|
||||||
import forge.assets.FSkin;
|
import forge.assets.FSkin;
|
||||||
import forge.assets.ImageCache;
|
import forge.assets.ImageCache;
|
||||||
import forge.card.CardImageRenderer;
|
import forge.card.CardImageRenderer;
|
||||||
@@ -38,12 +40,16 @@ import forge.card.CardRenderer;
|
|||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.gui.GuiBase;
|
import forge.gui.GuiBase;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
|
import forge.item.SealedProduct;
|
||||||
import forge.sound.SoundEffectType;
|
import forge.sound.SoundEffectType;
|
||||||
import forge.sound.SoundSystem;
|
import forge.sound.SoundSystem;
|
||||||
import forge.util.ImageFetcher;
|
import forge.util.ImageFetcher;
|
||||||
import forge.util.ImageUtil;
|
import forge.util.ImageUtil;
|
||||||
|
import forge.util.MyRandom;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import static forge.adventure.util.Paths.ITEMS_ATLAS;
|
import static forge.adventure.util.Paths.ITEMS_ATLAS;
|
||||||
@@ -304,6 +310,45 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
|||||||
needsToBeDisposed = true;
|
needsToBeDisposed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CardPack: {
|
||||||
|
TextureAtlas atlas = Config.instance().getAtlas(ITEMS_ATLAS);
|
||||||
|
Sprite backSprite = atlas.createSprite("CardBack");
|
||||||
|
if (reward.getDeck() == null) {
|
||||||
|
needsToBeDisposed = true;
|
||||||
|
processSprite(backSprite, null, null, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String imageKey;
|
||||||
|
try {
|
||||||
|
String editionCode = reward.getDeck().getComment();
|
||||||
|
int artIndex = 1;
|
||||||
|
if (SealedProduct.specialSets.contains(editionCode) || editionCode.equals("?")) {
|
||||||
|
imageKey = "b:" + getName().substring(0, getName().indexOf("Booster Pack") - 1);
|
||||||
|
} else {
|
||||||
|
int maxIdx = StaticData.instance().getEditions().get(editionCode).getCntBoosterPictures();
|
||||||
|
artIndex = MyRandom.getRandom().nextInt(maxIdx) + 1;
|
||||||
|
imageKey = ImageKeys.BOOSTER_PREFIX + editionCode + ((1 >= maxIdx) ? "" : ("_" + artIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
//Comment did not contain the edition code, this is not a basic booster pack
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//FImageComplex cardArt = CardRenderer.getCardArt(imageKey, false, false, false, false, false,false,false,false,false,false);
|
||||||
|
|
||||||
|
//Sprite item = new Sprite(cardArt.getTexture());
|
||||||
|
|
||||||
|
Sprite item = atlas.createSprite("Deck");
|
||||||
|
setItemTooltips(item, backSprite);
|
||||||
|
processSprite(backSprite, item, Controls.newTextraLabel("[80%]Booster"), 0, -10);
|
||||||
|
needsToBeDisposed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Life:
|
case Life:
|
||||||
case Shards:
|
case Shards:
|
||||||
case Gold: {
|
case Gold: {
|
||||||
@@ -567,6 +612,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
|||||||
if (itemExists) {
|
if (itemExists) {
|
||||||
description = item.getDescription();
|
description = item.getDescription();
|
||||||
layout.reset();
|
layout.reset();
|
||||||
|
} else if (getReward().getDeck() != null) {
|
||||||
|
description = getReward().getDeck().getName();
|
||||||
} else {
|
} else {
|
||||||
description = "Adds " + getReward().getCount() + " " + getReward().type;
|
description = "Adds " + getReward().getCount() + " " + getReward().type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,11 +533,11 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
return catalogPage;
|
return catalogPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DeckSectionPage getMainDeckPage() {
|
public DeckSectionPage getMainDeckPage() {
|
||||||
return mainDeckPage;
|
return mainDeckPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DeckSectionPage getSideboardPage() {
|
public DeckSectionPage getSideboardPage() {
|
||||||
return sideboardPage;
|
return sideboardPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +545,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
return commanderPage;
|
return commanderPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BoosterDraft getDraft() {
|
public BoosterDraft getDraft() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +584,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
saveHandler = saveHandler0;
|
saveHandler = saveHandler0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void save(final Callback<Boolean> callback) {
|
public void save(final Callback<Boolean> callback) {
|
||||||
if (StringUtils.isEmpty(deck.getName())) {
|
if (StringUtils.isEmpty(deck.getName())) {
|
||||||
List<PaperCard> commanders = deck.getCommanders(); //use commander name as default deck name
|
List<PaperCard> commanders = deck.getCommanders(); //use commander name as default deck name
|
||||||
String initialInput = Lang.joinHomogenous(commanders);
|
String initialInput = Lang.joinHomogenous(commanders);
|
||||||
@@ -1073,7 +1073,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class CatalogPage extends CardManagerPage {
|
public static class CatalogPage extends CardManagerPage {
|
||||||
private boolean initialized, needRefreshWhenShown;
|
private boolean initialized, needRefreshWhenShown;
|
||||||
|
|
||||||
protected CatalogPage(ItemManagerConfig config) {
|
protected CatalogPage(ItemManagerConfig config) {
|
||||||
|
|||||||
@@ -30,19 +30,22 @@ public class TransitionScreen extends FContainer {
|
|||||||
TextureRegion textureRegion, screenUIBackground, playerAvatar;
|
TextureRegion textureRegion, screenUIBackground, playerAvatar;
|
||||||
Texture vsTexture;
|
Texture vsTexture;
|
||||||
String enemyAtlasPath, playerAvatarName, enemyAvatarName;
|
String enemyAtlasPath, playerAvatarName, enemyAvatarName;
|
||||||
private String message = "";
|
private String message = "", playerRecord = "", enemyRecord = "";
|
||||||
boolean matchTransition, isloading, isIntro, isFadeMusic, isArenaScene;
|
boolean matchTransition, isloading, isIntro, isFadeMusic, isArenaScene;
|
||||||
GlyphLayout layout;
|
GlyphLayout layout;
|
||||||
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading) {
|
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading) {
|
||||||
this(proc, screen, enterMatch, loading, false, false);
|
this(proc, screen, enterMatch, loading, false, false);
|
||||||
}
|
}
|
||||||
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, String loadingMessage) {
|
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, String loadingMessage) {
|
||||||
this(proc, screen, enterMatch, loading, false, false, loadingMessage, null, "", "", "");
|
this(proc, screen, enterMatch, loading, false, false, loadingMessage, null, "", "", "", "", "");
|
||||||
}
|
}
|
||||||
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic) {
|
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic) {
|
||||||
this(proc, screen, enterMatch, loading, intro, fadeMusic, "", null, "", "", "");
|
this(proc, screen, enterMatch, loading, intro, fadeMusic, "", null, "", "", "", "", "");
|
||||||
}
|
}
|
||||||
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic, String loadingMessage, TextureRegion player, String enemyAtlas, String playerName, String enemyName) {
|
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic, String loadingMessage, TextureRegion player, String enemyAtlas, String playerName, String enemyName) {
|
||||||
|
this(proc, screen, enterMatch, loading, intro, fadeMusic, loadingMessage, player, enemyAtlas, playerName, enemyName, "", "");
|
||||||
|
}
|
||||||
|
public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic, String loadingMessage, TextureRegion player, String enemyAtlas, String playerName, String enemyName, String playerRecord, String enemyRecord) {
|
||||||
progressBar = new FProgressBar();
|
progressBar = new FProgressBar();
|
||||||
progressBar.setMaximum(100);
|
progressBar.setMaximum(100);
|
||||||
progressBar.setPercentMode(true);
|
progressBar.setPercentMode(true);
|
||||||
@@ -55,6 +58,8 @@ public class TransitionScreen extends FContainer {
|
|||||||
isIntro = intro;
|
isIntro = intro;
|
||||||
isFadeMusic = fadeMusic;
|
isFadeMusic = fadeMusic;
|
||||||
message = loadingMessage;
|
message = loadingMessage;
|
||||||
|
this.playerRecord = playerRecord;
|
||||||
|
this.enemyRecord = enemyRecord;
|
||||||
Forge.advStartup = intro && Forge.selector.equals("Adventure");
|
Forge.advStartup = intro && Forge.selector.equals("Adventure");
|
||||||
if (Forge.getCurrentScene() instanceof ArenaScene) {
|
if (Forge.getCurrentScene() instanceof ArenaScene) {
|
||||||
isArenaScene = true;
|
isArenaScene = true;
|
||||||
@@ -156,13 +161,17 @@ public class TransitionScreen extends FContainer {
|
|||||||
g.drawImage(textureRegion, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight());
|
g.drawImage(textureRegion, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight());
|
||||||
g.setAlphaComposite(oldAlpha);
|
g.setAlphaComposite(oldAlpha);
|
||||||
}
|
}
|
||||||
String wins = "0 - 0";
|
String p1Record = "0 - 0";
|
||||||
String loss = "0 - 0";
|
String p2Record = "0 - 0";
|
||||||
//stats
|
//stats
|
||||||
|
if (playerRecord.length() > 0 && enemyRecord.length() > 0) {
|
||||||
|
p1Record = playerRecord;
|
||||||
|
p2Record = enemyRecord;
|
||||||
|
}
|
||||||
Pair<Integer, Integer> winloss = Current.player().getStatistic().getWinLossRecord().get(enemyAvatarName);
|
Pair<Integer, Integer> winloss = Current.player().getStatistic().getWinLossRecord().get(enemyAvatarName);
|
||||||
if (winloss != null) {
|
if (winloss != null) {
|
||||||
wins = "" + winloss.getKey() + " - " + winloss.getValue();
|
p1Record = "" + winloss.getKey() + " - " + winloss.getValue();
|
||||||
loss = "" + winloss.getValue() + " - " + winloss.getKey();
|
p2Record = "" + winloss.getValue() + " - " + winloss.getKey();
|
||||||
}
|
}
|
||||||
if (Forge.isLandscapeMode()) {
|
if (Forge.isLandscapeMode()) {
|
||||||
//player
|
//player
|
||||||
@@ -171,16 +180,16 @@ public class TransitionScreen extends FContainer {
|
|||||||
g.drawImage(playerAvatar, playerAvatarX, playerAvatarY, scale, scale);
|
g.drawImage(playerAvatar, playerAvatarX, playerAvatarY, scale, scale);
|
||||||
layout.setText(font, playerAvatarName);
|
layout.setText(font, playerAvatarName);
|
||||||
g.drawText(playerAvatarName, font, screenW/4 - layout.width/2, playerAvatarY - layout.height, Color.WHITE, percentage);
|
g.drawText(playerAvatarName, font, screenW/4 - layout.width/2, playerAvatarY - layout.height, Color.WHITE, percentage);
|
||||||
layout.setText(font, wins);
|
layout.setText(font, p1Record);
|
||||||
g.drawText(wins, font, screenW/4 - layout.width/2, playerAvatarY - layout.height*2.5f, Color.WHITE, percentage);
|
g.drawText(p1Record, font, screenW/4 - layout.width/2, playerAvatarY - layout.height*2.5f, Color.WHITE, percentage);
|
||||||
//enemy
|
//enemy
|
||||||
float enemyAvatarX = screenW - screenW/4 - (scale/2 * percentage);
|
float enemyAvatarX = screenW - screenW/4 - (scale/2 * percentage);
|
||||||
float enemyAvatarY = centerY - scale/2;
|
float enemyAvatarY = centerY - scale/2;
|
||||||
g.drawImage(enemyAvatar, enemyAvatarX, enemyAvatarY, scale, scale);
|
g.drawImage(enemyAvatar, enemyAvatarX, enemyAvatarY, scale, scale);
|
||||||
layout.setText(font, enemyAvatarName);
|
layout.setText(font, enemyAvatarName);
|
||||||
g.drawText(enemyAvatarName, font, screenW - screenW/4 - layout.width/2, enemyAvatarY - layout.height, Color.WHITE, percentage);
|
g.drawText(enemyAvatarName, font, screenW - screenW/4 - layout.width/2, enemyAvatarY - layout.height, Color.WHITE, percentage);
|
||||||
layout.setText(font, loss);
|
layout.setText(font, p2Record);
|
||||||
g.drawText(loss, font, screenW - screenW/4 - layout.width/2, enemyAvatarY - layout.height*2.5f, Color.WHITE, percentage);
|
g.drawText(p2Record, font, screenW - screenW/4 - layout.width/2, enemyAvatarY - layout.height*2.5f, Color.WHITE, percentage);
|
||||||
//vs
|
//vs
|
||||||
float vsScale = (screenW / 3.2f);
|
float vsScale = (screenW / 3.2f);
|
||||||
g.drawHueShift(vsTexture, centerX - vsScale / 2, centerY - vsScale / 2, vsScale, vsScale, percentage*4);
|
g.drawHueShift(vsTexture, centerX - vsScale / 2, centerY - vsScale / 2, vsScale, vsScale, percentage*4);
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ public class DraftingProcessScreen extends FDeckEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BoosterDraft getDraft() {
|
public BoosterDraft getDraft() {
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void save(final Callback<Boolean> callback) {
|
public void save(final Callback<Boolean> callback) {
|
||||||
if (isDraftSaved) { //if draft itself is saved, let base class handle saving deck changes
|
if (isDraftSaved) { //if draft itself is saved, let base class handle saving deck changes
|
||||||
super.save(callback);
|
super.save(callback);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -11,16 +11,26 @@ public class AdventureWinLose extends ControlWinLose {
|
|||||||
*/
|
*/
|
||||||
public AdventureWinLose(ViewWinLose v, GameView game) {
|
public AdventureWinLose(ViewWinLose v, GameView game) {
|
||||||
super(v, game);
|
super(v, game);
|
||||||
v.getBtnContinue().setVisible(false);
|
|
||||||
|
if (lastGame.isMatchOver()) {
|
||||||
|
v.getBtnQuit().setText(Forge.getLocalizer().getMessage("lblBackToAdventure"));
|
||||||
|
//v.getBtnContinue().setVisible(false);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
v.getBtnContinue().setVisible(true);
|
||||||
|
v.getBtnContinue().setEnabled(true);
|
||||||
|
v.getBtnContinue().setText("CONTINUE MATCH");
|
||||||
|
v.getBtnQuit().setText(Forge.getLocalizer().getMessage("lblQuitAdventureEventMatch"));
|
||||||
|
}
|
||||||
v.getBtnRestart().setVisible(false);
|
v.getBtnRestart().setVisible(false);
|
||||||
v.getLabelShowBattlefield().setVisible(false);
|
v.getBtnRestart().setEnabled(false);
|
||||||
v.getBtnQuit().setText(Forge.getLocalizer().getMessage("lblBackToAdventure"));
|
//v.getBtnQuit().setText(Forge.getLocalizer().getMessage("lblBackToAdventure"));
|
||||||
Forge.setCursor(null, "0");
|
Forge.setCursor(null, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionOnContinue() {
|
public void actionOnContinue() {
|
||||||
//Do Nothing
|
super.actionOnContinue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,6 +41,7 @@ public class AdventureWinLose extends ControlWinLose {
|
|||||||
@Override
|
@Override
|
||||||
public void actionOnQuit() {
|
public void actionOnQuit() {
|
||||||
getView().hide();
|
getView().hide();
|
||||||
|
DuelScene.instance().GameEnd();
|
||||||
DuelScene.instance().exitDuelScene();
|
DuelScene.instance().exitDuelScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.screens.match.winlose;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import forge.game.GameType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.badlogic.gdx.Input.Keys;
|
import com.badlogic.gdx.Input.Keys;
|
||||||
@@ -68,6 +69,10 @@ public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
|
|||||||
case PlanarConquest:
|
case PlanarConquest:
|
||||||
control = new ConquestWinLose(this, game0);
|
control = new ConquestWinLose(this, game0);
|
||||||
break;
|
break;
|
||||||
|
case Adventure:
|
||||||
|
case AdventureEvent:
|
||||||
|
control = new AdventureWinLose(this, game0);
|
||||||
|
break;
|
||||||
case Draft:
|
case Draft:
|
||||||
if (!FModel.getGauntletMini().isGauntletDraft()) {
|
if (!FModel.getGauntletMini().isGauntletDraft()) {
|
||||||
break;
|
break;
|
||||||
@@ -92,7 +97,7 @@ public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
|
|||||||
btnContinue.setFont(FSkinFont.get(22));
|
btnContinue.setFont(FSkinFont.get(22));
|
||||||
btnRestart.setText(Forge.getLocalizer().getMessage("btnStartNewMatch"));
|
btnRestart.setText(Forge.getLocalizer().getMessage("btnStartNewMatch"));
|
||||||
btnRestart.setFont(btnContinue.getFont());
|
btnRestart.setFont(btnContinue.getFont());
|
||||||
btnQuit.setText(Forge.getLocalizer().getMessage("btnQuitMatch"));
|
//btnQuit.setText(Forge.getLocalizer().getMessage("btnQuitMatch"));
|
||||||
btnQuit.setFont(btnContinue.getFont());
|
btnQuit.setFont(btnContinue.getFont());
|
||||||
btnContinue.setEnabled(!game0.isMatchOver());
|
btnContinue.setEnabled(!game0.isMatchOver());
|
||||||
|
|
||||||
@@ -123,8 +128,8 @@ public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
|
|||||||
}).build());
|
}).build());
|
||||||
lblTitle.setText(composeTitle(game0));
|
lblTitle.setText(composeTitle(game0));
|
||||||
|
|
||||||
if (Forge.isMobileAdventureMode)
|
// if (Forge.isMobileAdventureMode)
|
||||||
control = new AdventureWinLose(this, game0);
|
// control = new AdventureWinLose(this, game0);
|
||||||
|
|
||||||
showGameOutcomeSummary();
|
showGameOutcomeSummary();
|
||||||
showPlayerScores();
|
showPlayerScores();
|
||||||
@@ -199,9 +204,16 @@ public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
|
|||||||
|
|
||||||
h = height / 12;
|
h = height / 12;
|
||||||
if (Forge.isMobileAdventureMode) {
|
if (Forge.isMobileAdventureMode) {
|
||||||
|
if (game.getGameType() == GameType.AdventureEvent) {
|
||||||
|
btnContinue.setBounds(x, y, w, h);
|
||||||
|
y += h + dy;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
btnContinue.setVisible(false);
|
||||||
|
}
|
||||||
btnQuit.setBounds(x, y, w, h);
|
btnQuit.setBounds(x, y, w, h);
|
||||||
y += h + dy;
|
y += h + dy;
|
||||||
btnContinue.setVisible(false);
|
|
||||||
btnRestart.setVisible(false);
|
btnRestart.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
btnContinue.setBounds(x, y, w, h);
|
btnContinue.setBounds(x, y, w, h);
|
||||||
|
|||||||
104
forge-gui/res/adventure/Shandalar/ui/event.json
Normal file
104
forge-gui/res/adventure/Shandalar/ui/event.json
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"width": 480,
|
||||||
|
"height": 270,
|
||||||
|
"yDown": true,
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "Image",
|
||||||
|
"image": "ui/tavern.png",
|
||||||
|
"width": 480,
|
||||||
|
"height": 270
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Scroll",
|
||||||
|
"name": "stats",
|
||||||
|
"style": "paper",
|
||||||
|
"x": 300,
|
||||||
|
"y": 18,
|
||||||
|
"width": 160,
|
||||||
|
"height": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Window",
|
||||||
|
"name": "scrollWindow",
|
||||||
|
"x": 15,
|
||||||
|
"y": 30,
|
||||||
|
"width": 256,
|
||||||
|
"maxWidth": 200,
|
||||||
|
"prefWidth": 140,
|
||||||
|
"height": 240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Table",
|
||||||
|
"name": "enemies",
|
||||||
|
"x": 15,
|
||||||
|
"y": 7,
|
||||||
|
"width": 256,
|
||||||
|
"height": 222
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Scroll",
|
||||||
|
"name": "blessingInfo",
|
||||||
|
"style": "nobg",
|
||||||
|
"x": 308,
|
||||||
|
"y": 20,
|
||||||
|
"width": 144,
|
||||||
|
"height": 195
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "return",
|
||||||
|
"text": "tr(lblBack)",
|
||||||
|
"binding": "Back",
|
||||||
|
"width": 85,
|
||||||
|
"height": 30,
|
||||||
|
"x": 390,
|
||||||
|
"y": 224
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "nextPage",
|
||||||
|
"text": "[%200]>",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 241,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Window",
|
||||||
|
"name": "header",
|
||||||
|
"x": 45,
|
||||||
|
"y": 0,
|
||||||
|
"width": 196,
|
||||||
|
"height": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "previousPage",
|
||||||
|
"text": "[%200]<",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 15,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "advance",
|
||||||
|
"text": "Advance",
|
||||||
|
"binding": "Status",
|
||||||
|
"width": 85,
|
||||||
|
"height": 30,
|
||||||
|
"x": 305,
|
||||||
|
"y": 224
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "editDeck",
|
||||||
|
"text": "[+Deck]",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 275,
|
||||||
|
"y": 224
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
102
forge-gui/res/adventure/Shandalar/ui/event_portrait.json
Normal file
102
forge-gui/res/adventure/Shandalar/ui/event_portrait.json
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
{
|
||||||
|
"width": 270,
|
||||||
|
"height": 480,
|
||||||
|
"yDown": true,
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "Image",
|
||||||
|
"image": "ui/tavern_portrait.png",
|
||||||
|
"width": 270,
|
||||||
|
"height": 480
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Scroll",
|
||||||
|
"name": "stats",
|
||||||
|
"style": "paper",
|
||||||
|
"x": 4,
|
||||||
|
"y": 4,
|
||||||
|
"width": 262,
|
||||||
|
"height": 98
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Window",
|
||||||
|
"name": "scrollWindow",
|
||||||
|
"x": 4,
|
||||||
|
"y": 136,
|
||||||
|
"width": 262,
|
||||||
|
"height": 297
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Table",
|
||||||
|
"name": "enemies",
|
||||||
|
"x": 15,
|
||||||
|
"y": 37,
|
||||||
|
"width": 256,
|
||||||
|
"height": 222
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Scroll",
|
||||||
|
"name": "blessingInfo",
|
||||||
|
"style": "nobg",
|
||||||
|
"x": 8,
|
||||||
|
"y": 14,
|
||||||
|
"width": 254,
|
||||||
|
"height": 84
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "return",
|
||||||
|
"text": "tr(lblBack)",
|
||||||
|
"binding": "Back",
|
||||||
|
"width": 115,
|
||||||
|
"height": 30,
|
||||||
|
"x": 155,
|
||||||
|
"y": 440
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "nextPage",
|
||||||
|
"text": "[%200]>",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 235,
|
||||||
|
"y": 106
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Window",
|
||||||
|
"name": "header",
|
||||||
|
"x": 34,
|
||||||
|
"y": 106,
|
||||||
|
"width": 201,
|
||||||
|
"height": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "previousPage",
|
||||||
|
"text": "[%200]<",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 4,
|
||||||
|
"y": 106
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "advance",
|
||||||
|
"text": "Advance",
|
||||||
|
"binding": "Status",
|
||||||
|
"width": 115,
|
||||||
|
"height": 30,
|
||||||
|
"x": 35,
|
||||||
|
"y": 440
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "editDeck",
|
||||||
|
"text": "[+Deck]",
|
||||||
|
"width": 30,
|
||||||
|
"height": 30,
|
||||||
|
"x": 0,
|
||||||
|
"y": 440
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -59,18 +59,37 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"name": "leaveIcon",
|
"name": "tavernEvent",
|
||||||
"image": "ui/leave.png",
|
"image": "ui/tavernevent.png",
|
||||||
"x": 320,
|
"x": 320,
|
||||||
"y": 85,
|
"y": 85,
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 100
|
"height": 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"type": "Label",
|
||||||
|
"name": "eventDescription",
|
||||||
|
"text": "Booster Draft Available",
|
||||||
|
"font": "default",
|
||||||
|
"width": 100,
|
||||||
|
"height": 30,
|
||||||
|
"x": 320,
|
||||||
|
"y": 170
|
||||||
|
},
|
||||||
|
{
|
||||||
"type": "TextButton",
|
"type": "TextButton",
|
||||||
"name": "done",
|
"name": "done",
|
||||||
"text": "tr(lblBack)",
|
"text": "tr(lblBack)",
|
||||||
"binding": "Back",
|
"binding": "Back",
|
||||||
|
"width": 48,
|
||||||
|
"height": 30,
|
||||||
|
"x": 5,
|
||||||
|
"y": 235
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "event",
|
||||||
|
"text": "Info",
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 320,
|
"x": 320,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"name": "healIcon",
|
"name": "healIcon",
|
||||||
"image": "ui/heal.png",
|
"image": "ui/heal.png",
|
||||||
"x": 60,
|
"x": 60,
|
||||||
"y": 85,
|
"y": 5,
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 100
|
"height": 100
|
||||||
},
|
},
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 165,
|
"x": 165,
|
||||||
"y": 105
|
"y": 25
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Label",
|
"type": "Label",
|
||||||
@@ -35,14 +35,14 @@
|
|||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 165,
|
"x": 165,
|
||||||
"y": 85
|
"y": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"name": "sellIcon",
|
"name": "sellIcon",
|
||||||
"image": "ui/sell.png",
|
"image": "ui/sell.png",
|
||||||
"x": 60,
|
"x": 60,
|
||||||
"y": 200,
|
"y": 125,
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 100
|
"height": 100
|
||||||
},
|
},
|
||||||
@@ -53,14 +53,42 @@
|
|||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 165,
|
"x": 165,
|
||||||
"y": 220
|
"y": 145
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Image",
|
||||||
|
"name": "tavernEvent",
|
||||||
|
"image": "ui/tavernevent.png",
|
||||||
|
"x": 60,
|
||||||
|
"y": 245,
|
||||||
|
"width": 100,
|
||||||
|
"height": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Label",
|
||||||
|
"name": "eventDescription",
|
||||||
|
"text": "Booster Draft Available",
|
||||||
|
"font": "default",
|
||||||
|
"width": 100,
|
||||||
|
"height": 30,
|
||||||
|
"x": 165,
|
||||||
|
"y": 245
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextButton",
|
||||||
|
"name": "event",
|
||||||
|
"text": "Info",
|
||||||
|
"width": 100,
|
||||||
|
"height": 30,
|
||||||
|
"x": 165,
|
||||||
|
"y": 265
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"name": "leaveIcon",
|
"name": "leaveIcon",
|
||||||
"image": "ui/leave.png",
|
"image": "ui/leave.png",
|
||||||
"x": 60,
|
"x": 60,
|
||||||
"y": 315,
|
"y": 365,
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 100
|
"height": 100
|
||||||
},
|
},
|
||||||
@@ -71,7 +99,7 @@
|
|||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 30,
|
"height": 30,
|
||||||
"x": 165,
|
"x": 165,
|
||||||
"y": 335
|
"y": 385
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Label",
|
"type": "Label",
|
||||||
|
|||||||
BIN
forge-gui/res/adventure/Shandalar/ui/tavernevent.png
Normal file
BIN
forge-gui/res/adventure/Shandalar/ui/tavernevent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -2948,6 +2948,7 @@ lblLossProper=Loss
|
|||||||
lblWinLossRatio=Win Loss Ratio
|
lblWinLossRatio=Win Loss Ratio
|
||||||
lblHeal=Heal
|
lblHeal=Heal
|
||||||
lblTempHitPoints=Temporary Hit Points
|
lblTempHitPoints=Temporary Hit Points
|
||||||
|
lblEndAdventureEventConfirm=This will end the current event, and your entry fee will not be refunded.\n\nLeave anyway?
|
||||||
#CardDetailUtil.java
|
#CardDetailUtil.java
|
||||||
lblChosenColors=Chosen colors:
|
lblChosenColors=Chosen colors:
|
||||||
lblLoyalty=Loyalty
|
lblLoyalty=Loyalty
|
||||||
@@ -2976,6 +2977,8 @@ lblEffect=Effect
|
|||||||
lblEmblem=Emblem
|
lblEmblem=Emblem
|
||||||
lblBoon=Boon
|
lblBoon=Boon
|
||||||
lblBackToAdventure=Back to Adventure
|
lblBackToAdventure=Back to Adventure
|
||||||
|
lblQuitAdventureEventMatch=Quit Match (will count as a loss)
|
||||||
|
lblQuitAdventureEvent=You have matches left to play!\nLeaving the event early will forfeit your potential future winnings.\nYou will still receive winnings as if you conceded your remaining matches.\n\nWould you still like to quit the event?
|
||||||
lblDisableWinLose=Disable WinLose Overlay
|
lblDisableWinLose=Disable WinLose Overlay
|
||||||
lblExitToWoldMap=Exit to the World Map?
|
lblExitToWoldMap=Exit to the World Map?
|
||||||
lblStartArena=Do you want to go into the Arena?
|
lblStartArena=Do you want to go into the Arena?
|
||||||
|
|||||||
@@ -338,7 +338,9 @@ public class BoosterDraft implements IBoosterDraft {
|
|||||||
this.computerChoose();
|
this.computerChoose();
|
||||||
|
|
||||||
final CardPool result = new CardPool();
|
final CardPool result = new CardPool();
|
||||||
result.addAllFlat(localPlayer.nextChoice());
|
|
||||||
|
if (localPlayer.nextChoice() != null && !localPlayer.nextChoice().isEmpty())
|
||||||
|
result.addAllFlat(localPlayer.nextChoice());
|
||||||
|
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
// Can't set a card, since none are available. Just pass "empty" packs.
|
// Can't set a card, since none are available. Just pass "empty" packs.
|
||||||
@@ -397,6 +399,9 @@ public class BoosterDraft implements IBoosterDraft {
|
|||||||
for (int i = 0; i < N_PLAYERS; i++) {
|
for (int i = 0; i < N_PLAYERS; i++) {
|
||||||
List<PaperCard> passingPack = this.players.get(i).passPack();
|
List<PaperCard> passingPack = this.players.get(i).passPack();
|
||||||
|
|
||||||
|
if (passingPack == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!passingPack.isEmpty()) {
|
if (!passingPack.isEmpty()) {
|
||||||
// TODO Canal Dredger for passing a pack with a single card in it
|
// TODO Canal Dredger for passing a pack with a single card in it
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user