mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
- Added a new quest preference "Do Not Play AI Matches" which allows the player to decide the outcome of AI vs. AI matches randomly instead of playing them out and thus simulating them. This is disabled by default, set to "1" to enable.
- Currently determines the outcome of all AI vs. AI matches in a 50-50 fashion. Might be upgraded later to bias the outcome towards a stronger deck judging by the total card draft rating value.
This commit is contained in:
@@ -84,6 +84,10 @@ public enum CSubmenuQuestPrefs implements ICDoc {
|
||||
view.getLblErrShop().setVisible(true);
|
||||
view.getLblErrShop().setText(s);
|
||||
break;
|
||||
case DRAFT_TOURNAMENTS:
|
||||
view.getLblErrDraftTournaments().setVisible(true);
|
||||
view.getLblErrDraftTournaments().setText(s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -99,6 +103,7 @@ public enum CSubmenuQuestPrefs implements ICDoc {
|
||||
view.getLblErrDifficulty().setVisible(false);
|
||||
view.getLblErrRewards().setVisible(false);
|
||||
view.getLblErrShop().setVisible(false);
|
||||
view.getLblErrDraftTournaments().setVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,11 +52,13 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
private final JPanel pnlDifficulty = new JPanel();
|
||||
private final JPanel pnlBooster = new JPanel();
|
||||
private final JPanel pnlShop = new JPanel();
|
||||
private final JPanel pnlDraftTournaments = new JPanel();
|
||||
|
||||
private final FLabel lblErrRewards = new FLabel.Builder().text("Rewards Error").fontStyle(Font.BOLD).build();
|
||||
private final FLabel lblErrDifficulty = new FLabel.Builder().text("Difficulty Error").fontStyle(Font.BOLD).build();
|
||||
private final FLabel lblErrBooster = new FLabel.Builder().text("Booster Error").fontStyle(Font.BOLD).build();
|
||||
private final FLabel lblErrShop = new FLabel.Builder().text("Shop Error").fontStyle(Font.BOLD).build();
|
||||
private final FLabel lblErrDraftTournaments = new FLabel.Builder().text("Draft Tournaments Error").fontStyle(Font.BOLD).build();
|
||||
|
||||
private final QuestPreferences prefs = FModel.getQuestPreferences();
|
||||
private PrefInput focusTarget;
|
||||
@@ -66,7 +68,8 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
REWARDS, /** */
|
||||
DIFFICULTY, /** */
|
||||
BOOSTER, /** */
|
||||
SHOP
|
||||
SHOP, /***/
|
||||
DRAFT_TOURNAMENTS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +85,7 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
lblErrDifficulty.setForeground(Color.red);
|
||||
lblErrBooster.setForeground(Color.red);
|
||||
lblErrShop.setForeground(Color.red);
|
||||
lblErrDraftTournaments.setForeground(Color.red);
|
||||
|
||||
// Rewards panel
|
||||
final FPanel pnlTitleRewards = new FPanel();
|
||||
@@ -127,6 +131,17 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
pnlContent.add(pnlTitleShop, "w 96%!, h 36px!, gap 2% 0 10px 10px");
|
||||
pnlContent.add(pnlShop, "w 96%!, gap 2% 0 10px 20px");
|
||||
populateShop();
|
||||
|
||||
// Draft tournaments panel
|
||||
final FPanel pnlTitleDraftTournaments = new FPanel();
|
||||
pnlTitleDraftTournaments.setLayout(new MigLayout("insets 0, align center"));
|
||||
pnlTitleDraftTournaments.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||
pnlTitleDraftTournaments.add(new FLabel.Builder().text("Draft Tournaments")
|
||||
.icon(FSkin.getIcon(FSkinProp.ICO_QUEST_COIN))
|
||||
.fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0");
|
||||
pnlContent.add(pnlTitleDraftTournaments, "w 96%!, h 36px!, gap 2% 0 10px 10px");
|
||||
pnlContent.add(pnlDraftTournaments, "w 96%!, gap 2% 0 10px 20px");
|
||||
populateDraftTournaments();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -190,6 +205,11 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
return lblErrBooster;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JLabel} */
|
||||
public JLabel getLblErrDraftTournaments() {
|
||||
return lblErrDraftTournaments;
|
||||
}
|
||||
|
||||
public void focusFirstTextbox() {
|
||||
focusTarget.requestFocusInWindow();
|
||||
}
|
||||
@@ -414,6 +434,20 @@ public enum VSubmenuQuestPrefs implements IVSubmenu<CSubmenuQuestPrefs> {
|
||||
|
||||
}
|
||||
|
||||
private void populateDraftTournaments() {
|
||||
|
||||
pnlDraftTournaments.setOpaque(false);
|
||||
pnlDraftTournaments.setLayout(new MigLayout("insets 0, gap 0, wrap 2, hidemode 3"));
|
||||
pnlDraftTournaments.removeAll();
|
||||
pnlDraftTournaments.add(lblErrDraftTournaments, "w 100%!, h 30px!, span 2 1");
|
||||
|
||||
FLabel randomAIMatches = new FLabel.Builder().text("Do Not Play AI Matches").fontAlign(SwingConstants.RIGHT).build();
|
||||
randomAIMatches.setToolTipText("If set to 1, AI vs. AI matches in draft tournaments will not be played and their outcome will be decided randomly instead.");
|
||||
pnlDraftTournaments.add(randomAIMatches, labelConstraints);
|
||||
pnlDraftTournaments.add(new PrefInput(QPref.RANDOMLY_DECIDE_AI_VS_AI, QuestPreferencesErrType.DRAFT_TOURNAMENTS), fieldConstraints);
|
||||
|
||||
}
|
||||
|
||||
/** */
|
||||
@SuppressWarnings("serial")
|
||||
public class PrefInput extends SkinnedTextField {
|
||||
|
||||
@@ -29,7 +29,8 @@ public class QuestPrefsScreen extends FScreen {
|
||||
DIFFICULTY_EASY,
|
||||
DIFFICULTY_MEDIUM,
|
||||
DIFFICULTY_HARD,
|
||||
DIFFICULTY_EXPERT
|
||||
DIFFICULTY_EXPERT,
|
||||
DRAFT_TOURNAMENTS
|
||||
}
|
||||
|
||||
private FScrollPane scroller = add(new FScrollPane() {
|
||||
@@ -88,6 +89,10 @@ public class QuestPrefsScreen extends FScreen {
|
||||
scroller.add(new PrefsOption("Playset Size: Basic Lands", QPref.PLAYSET_BASIC_LAND_SIZE, PrefsGroup.SHOP));
|
||||
scroller.add(new PrefsOption("Playset Size: Any Number", QPref.PLAYSET_ANY_NUMBER_SIZE, PrefsGroup.SHOP));
|
||||
|
||||
//Quest Draft Tournament Preferences
|
||||
scroller.add(new PrefsHeader("Quest Draft Tournaments", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_EXPERT));
|
||||
scroller.add(new PrefsOption("Do Not Play AI Matches", QPref.RANDOMLY_DECIDE_AI_VS_AI, PrefsGroup.DRAFT_TOURNAMENTS));
|
||||
|
||||
//Difficulty Adjustments (All)
|
||||
scroller.add(new PrefsHeader("Difficulty Adjustments (All)", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_ALL));
|
||||
//scroller.add(new PrefsOption("Starting basic lands", QPref.STARTING_BASIC_LANDS, PrefsGroup.DIFFICULTY_ALL)); // Add Basic Lands is used instead
|
||||
@@ -95,7 +100,7 @@ public class QuestPrefsScreen extends FScreen {
|
||||
scroller.add(new PrefsOption("Color bias (1-100%)", QPref.STARTING_POOL_COLOR_BIAS, PrefsGroup.DIFFICULTY_ALL));
|
||||
scroller.add(new PrefsOption("Penalty for loss", QPref.PENALTY_LOSS, PrefsGroup.DIFFICULTY_ALL));
|
||||
|
||||
//Difficult Adjustments (Easy)
|
||||
//Difficulty Adjustments (Easy)
|
||||
scroller.add(new PrefsHeader("Difficulty Adjustments (Easy)", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_EASY));
|
||||
scroller.add(new PrefsOption("Wins For Booster", QPref.WINS_BOOSTER_EASY, PrefsGroup.DIFFICULTY_EASY));
|
||||
scroller.add(new PrefsOption("Wins For Rank Increase", QPref.WINS_RANKUP_EASY, PrefsGroup.DIFFICULTY_EASY));
|
||||
@@ -107,7 +112,7 @@ public class QuestPrefsScreen extends FScreen {
|
||||
scroller.add(new PrefsOption("Starting rares", QPref.STARTING_RARES_EASY, PrefsGroup.DIFFICULTY_EASY));
|
||||
scroller.add(new PrefsOption("Starting credits", QPref.STARTING_CREDITS_EASY, PrefsGroup.DIFFICULTY_EASY));
|
||||
|
||||
//Difficult Adjustments (Medium)
|
||||
//Difficulty Adjustments (Medium)
|
||||
scroller.add(new PrefsHeader("Difficulty Adjustments (Medium)", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_MEDIUM));
|
||||
scroller.add(new PrefsOption("Wins For Booster", QPref.WINS_BOOSTER_MEDIUM, PrefsGroup.DIFFICULTY_MEDIUM));
|
||||
scroller.add(new PrefsOption("Wins For Rank Increase", QPref.WINS_RANKUP_MEDIUM, PrefsGroup.DIFFICULTY_MEDIUM));
|
||||
@@ -119,7 +124,7 @@ public class QuestPrefsScreen extends FScreen {
|
||||
scroller.add(new PrefsOption("Starting rares", QPref.STARTING_RARES_MEDIUM, PrefsGroup.DIFFICULTY_MEDIUM));
|
||||
scroller.add(new PrefsOption("Starting credits", QPref.STARTING_CREDITS_MEDIUM, PrefsGroup.DIFFICULTY_MEDIUM));
|
||||
|
||||
//Difficult Adjustments (Hard)
|
||||
//Difficulty Adjustments (Hard)
|
||||
scroller.add(new PrefsHeader("Difficulty Adjustments (Hard)", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_HARD));
|
||||
scroller.add(new PrefsOption("Wins For Booster", QPref.WINS_BOOSTER_HARD, PrefsGroup.DIFFICULTY_HARD));
|
||||
scroller.add(new PrefsOption("Wins For Rank Increase", QPref.WINS_RANKUP_HARD, PrefsGroup.DIFFICULTY_HARD));
|
||||
@@ -131,7 +136,7 @@ public class QuestPrefsScreen extends FScreen {
|
||||
scroller.add(new PrefsOption("Starting rares", QPref.STARTING_RARES_HARD, PrefsGroup.DIFFICULTY_HARD));
|
||||
scroller.add(new PrefsOption("Starting credits", QPref.STARTING_CREDITS_HARD, PrefsGroup.DIFFICULTY_HARD));
|
||||
|
||||
//Difficult Adjustments (Expert)
|
||||
//Difficulty Adjustments (Expert)
|
||||
scroller.add(new PrefsHeader("Difficulty Adjustments (Expert)", FSkinImage.QUEST_NOTES, PrefsGroup.DIFFICULTY_EXPERT));
|
||||
scroller.add(new PrefsOption("Wins For Booster", QPref.WINS_BOOSTER_EXPERT, PrefsGroup.DIFFICULTY_EXPERT));
|
||||
scroller.add(new PrefsOption("Wins For Rank Increase", QPref.WINS_RANKUP_EXPERT, PrefsGroup.DIFFICULTY_EXPERT));
|
||||
@@ -214,6 +219,9 @@ public class QuestPrefsScreen extends FScreen {
|
||||
case SHOP:
|
||||
prefType = "Shop Preferences";
|
||||
break;
|
||||
case DRAFT_TOURNAMENTS:
|
||||
prefType = "Draft Tournaments";
|
||||
break;
|
||||
default:
|
||||
prefType = "Difficulty Adjustments";
|
||||
break;
|
||||
|
||||
@@ -16,12 +16,15 @@ import forge.match.HostedMatch;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.data.QuestPreferences;
|
||||
import forge.tournament.system.TournamentBracket;
|
||||
import forge.tournament.system.TournamentPairing;
|
||||
import forge.tournament.system.TournamentPlayer;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.storage.IStorage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class QuestDraftUtils {
|
||||
@@ -146,6 +149,11 @@ public class QuestDraftUtils {
|
||||
latestSet--;
|
||||
}
|
||||
|
||||
if (latestSet == currentStandings.length - 1) {
|
||||
// No more matches left
|
||||
return;
|
||||
}
|
||||
|
||||
//Fill in any missing spots in previous brackets
|
||||
boolean foundMatchups = false;
|
||||
for (int i = 0; i <= latestSet && i <= 14; i += 2) {
|
||||
@@ -262,6 +270,15 @@ public class QuestDraftUtils {
|
||||
gui.enableOverlay();
|
||||
|
||||
final DraftMatchup nextMatch = matchups.remove(0);
|
||||
|
||||
if (FModel.getQuestPreferences().getPrefInt(QuestPreferences.QPref.RANDOMLY_DECIDE_AI_VS_AI) == 1) {
|
||||
// the user asked to decide the AI vs AI match randomly, so just call the UI update and leave the rest to injection code
|
||||
if (injectRandomMatchOutcome(false)) {
|
||||
update(gui);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
matchInProgress = true;
|
||||
|
||||
if (nextMatch.hasHumanPlayer()) {
|
||||
@@ -394,4 +411,28 @@ public class QuestDraftUtils {
|
||||
return humanPlayer != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean injectRandomMatchOutcome(boolean simHumanMatches) {
|
||||
QuestEventDraft qd = FModel.getQuest().getAchievements().getCurrentDraft();
|
||||
|
||||
int pos = Arrays.asList(qd.getStandings()).indexOf(QuestEventDraft.UNDETERMINED);
|
||||
int offset = (pos - 8) * 2;
|
||||
|
||||
String sid1 = qd.getStandings()[offset];
|
||||
String sid2 = qd.getStandings()[offset + 1];
|
||||
|
||||
if (sid1.equals(QuestEventDraft.HUMAN) || sid2.equals(QuestEventDraft.HUMAN)) {
|
||||
if (!simHumanMatches) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: bias the outcome towards a deck with higher total card draft rating value instead of going 50-50
|
||||
boolean randomWinner = MyRandom.getRandom().nextBoolean();
|
||||
qd.getStandings()[pos] = randomWinner ? sid1 : sid2;
|
||||
|
||||
FModel.getQuest().save();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestDraftUtils.Mode;
|
||||
import forge.quest.QuestEventDraft.QuestDraftFormat;
|
||||
import forge.quest.data.QuestAchievements;
|
||||
import forge.quest.data.QuestPreferences;
|
||||
import forge.tournament.system.TournamentBracket;
|
||||
import forge.tournament.system.TournamentPairing;
|
||||
import forge.tournament.system.TournamentPlayer;
|
||||
@@ -459,5 +460,11 @@ public class QuestTournamentController {
|
||||
|
||||
gui = GuiBase.getInterface().getNewGuiGame();
|
||||
QuestDraftUtils.startNextMatch(gui);
|
||||
|
||||
if (FModel.getQuestPreferences().getPrefInt(QuestPreferences.QPref.RANDOMLY_DECIDE_AI_VS_AI) == 1) {
|
||||
// need to force a view update after a random match outcome was injected into standings
|
||||
view.populate();
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,9 @@ public class QuestPreferences extends PreferencesStore<QuestPreferences.QPref> i
|
||||
PLAYSET_ANY_NUMBER_SIZE("500"),
|
||||
PLAYSET_BASIC_LAND_SIZE("50"),
|
||||
|
||||
ITEM_LEVEL_RESTRICTION("1");
|
||||
ITEM_LEVEL_RESTRICTION("1"),
|
||||
|
||||
RANDOMLY_DECIDE_AI_VS_AI("0");
|
||||
|
||||
private final String strDefaultVal;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user