/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { var curDeck = con.GetLoadedDeck(); if (curDeck != null) { MessageBox.Show(String.Format("{0}", curDeck.CardCount)); } // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.SelectCards(null).Rows.Count > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.SelectRandomCardModels(1).FirstOrDefault(); var d = new Deck(game); // It's weird, but this is how you add a card. d.Sections[0].Cards.Add(new Deck.Element() { Card = cm, Quantity = (byte)1 }); // Load that mother. con.LoadDeck(d); }
/// <summary> /// Initializes a new instance of the <see cref="MainViewModel" /> class. /// </summary> /// <param name="pluginController">The plugin controller.</param> public MainViewModel(IDeckBuilderPluginController pluginController) { PluginController = pluginController; GameDefinitions = PluginController.Games.Games.ToList(); SelectedGame = GameDefinitions.FirstOrDefault(); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { var curDeck = con.GetLoadedDeck(); if (curDeck != null) { MessageBox.Show(String.Format("{0}", curDeck.CardCount())); } // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.AllCards().Count() > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.AllCards().First(); var d = new Deck(); d.GameId = game.Id; // It's weird, but this is how you add a card. var multiCard = cm.ToMultiCard(1); var secArray = d.Sections.ToArray(); secArray[0].Cards.AddCard(multiCard); d.Sections = secArray; // Load that mother. con.LoadDeck(d); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="pluginController"></param> public void OnClick(IDeckBuilderPluginController pluginController) { // WHI: e1e11562-efce-4379-9701-534f9717391f // Find the first game with cards in it. // var game = pluginController.Games.Games.FirstOrDefault(x => x.SelectCards(null).Rows.Count > 0); var game = pluginController.Games.Games.FirstOrDefault(); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. pluginController.SetLoadedGame(game); var window = new MainWindow(new MainViewModel(pluginController)); // Trigger the version check here var dispatcher = Dispatcher.CurrentDispatcher; var task = new Task(() => { var versionDetails = GetLatestVersion.LatestVersionDetails(); if (!VersionCheckDone && versionDetails.Any()) { var current = Assembly.GetExecutingAssembly().GetName().Version; var latest = new Version(versionDetails.First().Version); if (latest > current) { dispatcher.Invoke(() => { // TODO: Owner sichern + exception fangen (owner zu schnell zu) var dialog = new NewVersionAvailableDialog() { Owner = window, VersionDetails = versionDetails, }; dialog.ShowDialog(); }); } VersionCheckDone = true; } }); task.Start(); window.ShowDialog(); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> /// public void OnClick(IDeckBuilderPluginController con) { if (con.GetLoadedGame() == null || con.GetLoadedGame().Id.ToString() != "a6c8d2e8-7cd8-11dd-8f94-e62b56d89593") { MessageBox.Show("Can only use this plugin for Magic the Gathering"); return; } MainWindow window = new MainWindow() { game = con.GetLoadedGame() }; window.ShowDialog(); }
/// <summary> /// Should be called when the user clicks on the menu item for this Plugin. It will launch the /// Deck Converter Wizard Window. If the Wizard is completed successfully, the Deck will be /// loaded into OCTGN's Deck Editor. /// </summary> /// <param name="controller">The controller which is using this plugin. Usually it is OCTGN</param> public void OnClick(IDeckBuilderPluginController controller) { // Attempt to get the MTG Game from the IDeckBuilderPluginController Game mtgGame = MTGDeckConverterPluginMenuItem.GetGameDefinition(controller); if (mtgGame != null) { // Initialize the ConverterDatabase with the MTG Game Model.ConverterDatabase.SingletonInstance.Initialize(mtgGame); MainWindow mainWindow = new MainWindow(); MTGDeckConverter.ViewModel.ImportDeckWizardVM importDeckWizardVM = new MTGDeckConverter.ViewModel.ImportDeckWizardVM(); // This will execute when the Close event is fired. // If the Main Window is closed via 'X' button, this won't be executed. importDeckWizardVM.Close += (s, e) => { if ( importDeckWizardVM.Completed && importDeckWizardVM.WasNotCancelled ) { controller.SetLoadedGame(mtgGame); controller.LoadDeck(importDeckWizardVM.Converter.CreateDeck()); } }; mainWindow.DataContext = importDeckWizardVM; // This will block until the Main Window is closed mainWindow.ShowDialog(); // Clean up the Singleton items, regardless of whether the Wizard did anything or not Model.ConverterDatabase.SingletonInstance.UpdateSetsExcludedFromSearches(); Model.SettingsManager.SingletonInstance.SaveSettingsManager(); Model.ConverterDatabase.SingletonInstance.Cleanup(); } else { System.Windows.MessageBox.Show ( "The Game Definition for Magic: the Gathering could not be found, check that it is installed in OCTGN correctly.", "Game Definition Not Found" ); } }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { var curDeck = con.GetLoadedDeck(); if (curDeck != null) { MessageBox.Show(String.Format("{0}", curDeck.CardCount())); } // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.AllCards().Count() > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.AllCards().First(); var d = game.CreateDeck(); foreach (Section section in d.Sections) { //this is how you can set a specific section to be shared. //the section names should match what is defined in gamedefinitions. if (section.Name == "Special section name") { section.Shared = true; } } d.Notes = "Add notes all at once to the deck like this"; //TODO: Add example section for tags // It's weird, but this is how you add a card. var multiCard = cm.ToMultiCard(1); var secArray = d.Sections.ToArray(); secArray[0].Cards.AddCard(multiCard); d.Sections = secArray; // Load that mother. con.LoadDeck(d); }
/// <summary> /// Should be called when the user clicks on the menu item for this Plugin. It will launch the /// Deck Converter Wizard Window. If the Wizard is completed successfully, the Deck will be /// loaded into OCTGN's Deck Editor. /// </summary> /// <param name="controller">The controller which is using this plugin. Usually it is OCTGN</param> public void OnClick(IDeckBuilderPluginController controller) { Logger.Info("OCTGNDeckConverter clicked from the Plugins menu of the Deck Editor"); if (controller.Games.Games.Count() > 0) { // Initialize the ConverterDatabase2 with all available Games Model.ConverterDatabase.SingletonInstance.LoadGames(controller.Games.Games); MainWindow mainWindow = new MainWindow(); OCTGNDeckConverter.ViewModel.ImportDeckWizardVM importDeckWizardVM = new OCTGNDeckConverter.ViewModel.ImportDeckWizardVM(); // This will execute when the Close event is fired. // If the Main Window is closed via 'X' button, this won't be executed. importDeckWizardVM.Close += (s, e) => { if ( importDeckWizardVM.Completed && importDeckWizardVM.WasNotCancelled ) { controller.SetLoadedGame(importDeckWizardVM.Converter.ConverterGame.Game); controller.LoadDeck(importDeckWizardVM.Converter.CreateDeck()); } }; mainWindow.DataContext = importDeckWizardVM; // This will block until the Main Window is closed mainWindow.ShowDialog(); // Clean up the Singleton items, regardless of whether the Wizard did anything or not Model.ConverterDatabase.SingletonInstance.UpdateSetsExcludedFromSearches(); Model.SettingsManager.SingletonInstance.SaveSettingsManager(); } else { Logger.Error("No Game Definitions could be found.Check that you have installed them in OCTGN."); System.Windows.MessageBox.Show ( "No Game Definitions could be found. Check that you have installed them in OCTGN.", "Game Definitions Not Found" ); } }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); Log.Info("Starting OnClick"); ObservableDeck curDeck = (ObservableDeck)con.GetLoadedDeck(); if (curDeck == null) { MessageBox.Show("Failed to load Deck"); return; } DeckAnalysis results = WH40KCDeckAnalyser.Analyse(curDeck); curDeck.Notes = TextAnalysisRenderer.RenderAnalysis(results); }
/// <summary> /// Should be called when the user clicks on the menu item for this Plugin. It will launch the /// Deck Converter Wizard Window. If the Wizard is completed successfully, the Deck will be /// loaded into OCTGN's Deck Editor. /// </summary> /// <param name="controller">The controller which is using this plugin. Usually it is OCTGN</param> public void OnClick(IDeckBuilderPluginController controller) { if (controller.Games.Games.Count() > 0) { // Initialize the ConverterDatabase2 with all available Games Model.ConverterDatabase.SingletonInstance.LoadGames(controller.Games.Games); MainWindow mainWindow = new MainWindow(); OCTGNDeckConverter.ViewModel.ImportDeckWizardVM importDeckWizardVM = new OCTGNDeckConverter.ViewModel.ImportDeckWizardVM(); // This will execute when the Close event is fired. // If the Main Window is closed via 'X' button, this won't be executed. importDeckWizardVM.Close += (s, e) => { if ( importDeckWizardVM.Completed && importDeckWizardVM.WasNotCancelled ) { controller.SetLoadedGame(importDeckWizardVM.Converter.ConverterGame.Game); controller.LoadDeck(importDeckWizardVM.Converter.CreateDeck()); } }; mainWindow.DataContext = importDeckWizardVM; // This will block until the Main Window is closed mainWindow.ShowDialog(); // Clean up the Singleton items, regardless of whether the Wizard did anything or not Model.ConverterDatabase.SingletonInstance.UpdateSetsExcludedFromSearches(); Model.SettingsManager.SingletonInstance.SaveSettingsManager(); } else { System.Windows.MessageBox.Show ( "No Game Definitions could be found. Check that you have installed them in OCTGN.", "Game Definitions Not Found" ); } }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { var curDeck = con.GetLoadedDeck(); if(curDeck != null) MessageBox.Show(String.Format("{0}",curDeck.CardCount())); // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.AllCards().Count() > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.AllCards().First(); var d = game.CreateDeck(); foreach (Section section in d.Sections) { //this is how you can set a specific section to be shared. //the section names should match what is defined in gamedefinitions. if (section.Name == "Special section name") { section.Shared = true; } } d.Notes = "Add notes all at once to the deck like this"; //TODO: Add example section for tags // It's weird, but this is how you add a card. var multiCard = cm.ToMultiCard(1); var secArray = d.Sections.ToArray(); secArray[0].Cards.AddCard(multiCard); d.Sections = secArray; // Load that mother. con.LoadDeck(d); }
/// <summary> /// Initializes a new instance of the <see cref="MainViewModel" /> class. /// </summary> /// <param name="pluginController">The plugin controller.</param> public MainViewModel(IDeckBuilderPluginController pluginController) { PluginController = pluginController; GameDefinitions = PluginController.Games.Games.ToList(); SelectedGame = GameDefinitions.FirstOrDefault(d => d.Id.ToString() == Properties.Settings.Default.LastGame); if (SelectedGame == null) { // Default: Use WHI SelectedGame = GameDefinitions.FirstOrDefault(d => d.Id.ToString() == GameExtension.WarhammerInvasionGameId); } if (SelectedGame == null) { // Still no game: Take the first one SelectedGame = GameDefinitions.FirstOrDefault(); } AvailableLanguages = new[] { "English", "Deutsch" }; SelectedLanguage = Properties.Settings.Default.LastCultureCode; AvailablePlayModes = (PlayMode[])Enum.GetValues(typeof(PlayMode)); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { if (con.GetLoadedGame() == null || con.GetLoadedGame().Id.ToString() != "9acef3d0-efa8-4d3f-a10c-54812baecdda") { MessageBox.Show("You must have Mage Wars loaded to use this feature."); return; } var curDeck = con.GetLoadedDeck(); if (curDeck == null) { MessageBox.Show("You must have a Mage Wars deck loaded to use this feature."); return; } deckValidated = false; var secArray = curDeck.Sections.ToArray(); int cardcount = 0; int spellbook = 0; string magename = "none in deck"; int spellpoints = 0; string reporttxt = ""; bool Talos = false; int hashtotal = 0; Dictionary <string, int> training = new Dictionary <string, int>() { { "Dark", 2 }, { "Holy", 2 }, { "Nature", 2 }, { "Mind", 2 }, { "Arcane", 2 }, { "War", 2 }, { "Earth", 2 }, { "Water", 2 }, { "Air", 2 }, { "Fire", 2 }, { "Creature", 0 } }; Dictionary <string, int> levels = new Dictionary <string, int>() { { "Dark", 0 }, { "Holy", 0 }, { "Nature", 0 }, { "Mind", 0 }, { "Arcane", 0 }, { "War", 0 }, { "Earth", 0 }, { "Water", 0 }, { "Air", 0 }, { "Fire", 0 }, { "Creature", 0 } }; foreach (var section in secArray) { foreach (var card in section.Cards) { hashtotal += card.GetHashCode() + card.Quantity; //MessageBox.Show(String.Format("{0}", card.Name)); if (Property(card, "Subtype").Contains("Mage")) { var mageschoolcost = Splitme(Property(card, "MageSchoolCost"), ","); var magespellbooklimit = Splitme(Property(card, "Stats"), ","); magename = card.Name; reporttxt += string.Format("{1}\n", card.Quantity.ToString(), card.Name); foreach (var msc in mageschoolcost) { foreach (var t in training.ToList()) { if (msc.Contains(t.Key)) //scan mageschoolcost for training info { var tlevel = Splitme(msc, "="); training[t.Key] = Convert.ToInt32(tlevel[1]); } } } foreach (var mstat in magespellbooklimit) { if (mstat.Contains("Spellbook")) { spellpoints = Convert.ToInt32(Splitme(mstat, "=")[1]); } } continue; } if (HasProperty(card, "Traits")) { if (Property(card, "Traits").Contains("Novice")) //Novice spells always cost 1 point { cardcount += card.Quantity; spellbook += card.Quantity; var typestr = Property(card, "Type"); if (typestr.Equals("Conjuration-Wall")) { typestr = "Conjuration"; } if (!reporttxt.Contains(typestr)) // has this type been listed before?? { reporttxt += string.Format("\n--- {0} ---\n", typestr); } reporttxt += string.Format("{0} - {1} - 1 - 1 - {0}\n", card.Quantity.ToString(), card.Name); continue; } } if (card.Name.Contains("Talos")) { Talos = true; } else { Talos = false; } if (HasProperty(card, "School") & HasProperty(card, "Level")) { var school = Property(card, "School"); var level = Property(card, "Level"); var typestr = Property(card, "Type"); if (typestr.Equals("Conjuration-Wall")) { typestr = "Conjuration"; } if (typestr.Equals("Conjuration-Terrain")) { typestr = "Conjuration"; } if (!reporttxt.Contains(typestr)) // has this type been listed before?? { reporttxt += string.Format("\n--- {0} ---\n", typestr); } reporttxt += string.Format("{0} - {1} - ", card.Quantity.ToString(), card.Name); //Calculate card's spell level int totalLevel = 0; string deli = level.Contains("+") ? "+" : level.Contains("/") ? "/" : ""; if (deli == "/") { string lev = level.Substring(0, 1); totalLevel = Convert.ToInt32(lev); } else if (deli == "+") { string[] levs = level.Split('+'); string[] schs = school.Split('+'); for (int i = 0; i < levs.Length; ++i) { if (schs[i] != "Water") { totalLevel += Convert.ToInt32(levs[i]); } } } else { totalLevel = Convert.ToInt32(level); } //calculate spell cost in book int cost = 0; if (!Talos) { if (school.Contains("+")) //add all spell levels { var lev = Splitme(level, "+"); int x = 0; foreach (var s in Splitme(school, "+")) { cost += Convert.ToInt32(lev[x]) * training[s]; levels[s] += Convert.ToInt32(lev[x]) * card.Quantity; x++; } } else if (school.Contains("/")) //add just the cheapest of these { if (magename == "none in deck") //no mage found yet { System.Windows.MessageBox.Show("Warning - No mage card has been found yet. This may lead to inaccurate calculations. Ensure that the first card in the deck is a mage"); } var lev = Splitme(level, "/")[0]; //just take the first value as each is the same var mincost = 3; string minschool = ""; foreach (var s in Splitme(school, "/")) { if (training[s] < mincost) { minschool = s; mincost = training[s]; } } cost += Convert.ToInt32(lev) * training[minschool]; levels[minschool] += Convert.ToInt32(lev) * card.Quantity; } else //Only one school in spell { if (training.ContainsKey(school)) { cost += Convert.ToInt32(level) * training[school]; levels[school] += Convert.ToInt32(level) * card.Quantity; } } } //Paladin is trained in level 3 holy, level 2 war, and all holy creatures //If the current card is in the paladin's trainings, it has already been correctly added (assuming paladin's trainings contains Holy=1 and War=1) //so we only need to check for the exceptions if (magename.Contains("Paladin")) { string delim = school.Contains("+") ? "+" : school.Contains("/") ? "/" : ""; if (school.Contains("Holy")) { int holyLevel = Convert.ToInt32(Splitme(level, delim)[Splitme(school, delim).ToList().IndexOf("Holy")]); if (holyLevel > 3 && Property(card, "Type") != "Creature") { spellbook += holyLevel * card.Quantity; cost += holyLevel; } } if (school.Contains("War")) { int warLevel = Convert.ToInt32(Splitme(level, delim)[Splitme(school, delim).ToList().IndexOf("War")]); if (warLevel > 2 && !school.Contains("+")) { spellbook += warLevel * card.Quantity; cost += warLevel; } } //{ // Holy Creature rules go here should check of Creatures that are in two schools Holy + Other School // (other school should also exclude War) // we need to reduce the spellbook & cost by the spelllevel as if they were a 1x training. //spellbook -= spellLevel * card.Quantity; //cost -= spellLevel //} } //Siren is trained in Water and all spells with Song or Pirate subtypes. //By this point, Water has been correctly calculated, but the Song/Pirate spells are overcosted if they are not Water if (magename.Contains("Siren") && !school.Contains("Water") && (Property(card, "Subtype").Contains("Song") || Property(card, "Subtype").Contains("Pirate"))) { //subtract 1 per level per count as this card has been added x2 per non-trained school already spellbook -= totalLevel * card.Quantity; cost -= totalLevel; } //Forcemaster rule: Pay 3x for non-mind creatures if (magename == "Forcemaster" & "Creature" == Property(card, "Type")) { if (!school.Contains("Mind")) //"Mind" not in schools { if (school.Contains("+")) { foreach (var lev in Splitme(level, "+")) { spellbook += Convert.ToInt32(lev) * card.Quantity; // we just add 1 point per spell level as 2 points already have been added cost += Convert.ToInt32(lev); } } else //handle single school or "/" school cards { var lev = Splitme(level, "/"); spellbook += Convert.ToInt32(lev[0]) * card.Quantity; cost += Convert.ToInt32(lev[0]); } } } //Druid pays double for Water spells 2 and up if (magename == "Druid" && school.Contains("Water")) { string delimin = school.Contains("+") ? "+" : school.Contains("/") ? "/" : ""; var waterLevel = Convert.ToInt32(Splitme(level, delimin)[Splitme(school, delimin).ToList().IndexOf("Water")]); //whee if (waterLevel > 1) { spellbook += waterLevel * card.Quantity; cost += waterLevel; } } //check for multiples of Epic spells if (Property(card, "Traits").Contains("Epic") && card.Quantity > 1) { System.Windows.MessageBox.Show("Validation FAILED: Only one copy of Epic card " + card.Name + " is allowed.\n" + card.Quantity + " copies found in spellbook."); return; } //check for illegal school- or mage-specific spells if (Property(card, "Traits").Contains("Only")) { string[] traits = Property(card, "Traits").Split(','); List <string> onlyTraits = traits.Where(s => s.Contains("Only")).ToList(); if (onlyTraits.Count == 1) { string onlyPhrase = onlyTraits[0]; bool legal = false; //check mage restriction string mname = magename; if (mname.Contains("Beastmaster")) { mname = "Beastmaster"; } if (mname.Contains("Wizard")) { mname = "Wizard"; } if (mname.Contains("Warlock")) { mname = "Warlock"; } if (mname.Contains("Warlord")) { mname = "Warlord"; } if (mname.Contains("Priestess")) { mname = "Priestess"; } if (mname.Contains("Paladin")) { mname = "Paladin"; } if (mname.Contains("Siren")) { mname = "Siren"; } if (onlyPhrase.Contains(mname)) { legal = true; } //check class restriction foreach (string schoolKey in training.Keys) { if (training[schoolKey] == 1 && onlyPhrase.Contains(schoolKey + " Mage")) { legal = true; } } if (!legal) { System.Windows.MessageBox.Show("Validation FAILED: The card " + card.Name + " is not legal in a " + magename + " deck."); return; } } } // Check for correct number of cards int l = 0; if (level.Contains("+")) { var levArr = Splitme(level, "+"); foreach (string s in levArr) { l += Convert.ToInt32(s); } } else if (level.Contains("/")) { var levArr = Splitme(level, "/"); l = Convert.ToInt32(levArr[0]); } else { l = Convert.ToInt32(level); } if ((l == 1 && card.Quantity > 6 && (!card.Name.Contains("Shallow Sea") && magename.Contains("Siren")) || (l >= 2 && card.Quantity > 4))) { // too many System.Windows.MessageBox.Show("Validation FAILED: There are too many copies of " + card.Name + " in the deck."); return; } cardcount += card.Quantity; reporttxt += string.Format("{0} - {1} - {2}\n", totalLevel.ToString(), cost.ToString(), (cost * card.Quantity).ToString()); } //card has school and level } //foreach card } //foreach section foreach (var t in training) { spellbook += t.Value * levels[t.Key]; } string reporttmp = "A Mage Wars Spellbook, built using the OCTGN SBB " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + "\n\n"; reporttmp += string.Format("Spellbook points: {0} used of {0} allowed\n\n", spellbook, spellpoints); reporttmp += "Key: Quantity - Spell Name - Spell Level - Spellbook Cost - Total Spellbook Cost\n\n"; reporttmp += reporttxt; //System.Windows.MessageBox.Show(reporttmp); Clipboard.SetText(reporttmp); System.Windows.MessageBox.Show(String.Format("Validation result:\n{0} spellpoints in the deck using '{1}' as the mage. {2} spellpoints are allowed.\nDeck has been copied to the clipboard.", spellbook, magename, spellpoints)); if (spellbook <= spellpoints) { deckValidated = true; bookPoints = spellbook; totalCards = cardcount; validatedDeckHash = hashtotal; } }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { var curDeck = con.GetLoadedDeck(); if(curDeck != null) MessageBox.Show(String.Format("{0}",curDeck.CardCount())); // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.AllCards().Count() > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.AllCards().First(); var d = new Deck(); d.GameId = game.Id; // It's weird, but this is how you add a card. var multiCard = cm.ToMultiCard(1); var secArray = d.Sections.ToArray(); secArray[0].Cards.AddCard(multiCard); d.Sections = secArray; // Load that mother. con.LoadDeck(d); }
public void OnClick(IDeckBuilderPluginController controller) { //did they validate yet? var curDeck = controller.GetLoadedDeck(); int hashtotal = 0; foreach (var section in curDeck.Sections) { foreach (var card in section.Cards) { hashtotal += card.GetHashCode() + card.Quantity; } } if (!MageWarsValidator.deckValidated || MageWarsValidator.validatedDeckHash != hashtotal) { System.Windows.MessageBox.Show("You must successfully validate the current deck before exporting it to the AW SBB."); return; } if (curDeck.GameId.Equals(Guid.Parse("9acef3d0-efa8-4d3f-a10c-54812baecdda"))) //Is a Mage Wars deck loaded? { var secArray = curDeck.Sections.ToArray(); StringBuilder text = new StringBuilder(); //ignore spell counts text.AppendLine("1"); //ask for deck name string deckName = Prompt.ShowDialog("What is the name of this deck?", "Deck Name"); if (string.IsNullOrEmpty(deckName)) { deckName = "OCTGN Deck"; } text.AppendLine(deckName); //get mage name foreach (var section in secArray) { foreach (var card in section.Cards) { if (Property(card, "Subtype").Contains("Mage")) { text.AppendLine(card.Name); } } } //write spell set counts - one of each should be fine text.AppendLine("1,1,1,1,1,1"); //spellbook cost text.AppendLine(MageWarsValidator.bookPoints.ToString()); //cost per type - does this matter? text.AppendLine("120,120,120,120,120,120"); //cards in deck text.AppendLine(MageWarsValidator.totalCards.ToString()); //card ID and count bool promoFound = false; foreach (var section in secArray) { foreach (var card in section.Cards) { //skip mage cards and promos if (section.Name.Contains("Mage")) { continue; } if (Property(card, "CardID").Contains("MWPRO")) { promoFound = true; continue; } text.AppendLine(Property(card, "CardID") + "," + card.Quantity.ToString()); //and lower case until AW SBB is fixed text.AppendLine(Property(card, "CardID").ToLower() + "," + card.Quantity.ToString()); } } if (promoFound) { System.Windows.MessageBox.Show("There are one or more promos in this spellbook. They have been omitted from the export file because the AW SBB does not currently support them."); } //all done, ask for file location FolderBrowserDialog folderDialog = new FolderBrowserDialog(); folderDialog.Description = "Choose where to save the spellbook file."; if (folderDialog.ShowDialog() != DialogResult.OK) { return; } string writePath = folderDialog.SelectedPath; //write file StreamWriter writer = new StreamWriter(new FileStream(writePath + "\\" + deckName + ".sbb", FileMode.Create)); writer.Write(text.ToString()); writer.Close(); System.Windows.MessageBox.Show("File has been written to the specified location."); } }
public void OnClick(IDeckBuilderPluginController controller) { //did they validate yet? var curDeck = controller.GetLoadedDeck(); int hashtotal = 0; foreach (var section in curDeck.Sections) { foreach (var card in section.Cards) { hashtotal += card.GetHashCode() + card.Quantity; } } if (!MageWarsValidator.deckValidated || MageWarsValidator.validatedDeckHash != hashtotal) { System.Windows.MessageBox.Show("You must successfully validate the current deck before exporting it to a forum post."); return; } if (curDeck.GameId.Equals(Guid.Parse("9acef3d0-efa8-4d3f-a10c-54812baecdda"))) //Is a Mage Wars deck loaded? { //setup some stuff var secArray = curDeck.Sections.ToArray(); StringBuilder text = new StringBuilder(); //ask for the deck name string deckName = Prompt.ShowDialog("What is the name of this deck?", "Deck Name"); if (string.IsNullOrEmpty(deckName)) { deckName = "OCTGN Deck"; } //start the writing text.AppendLine("[spellbook]"); text.AppendLine("[spellbookheader]"); text.AppendLine("[spellbookname]" + deckName + "[/spellbookname]"); //get and write mage name foreach (var section in secArray) { foreach (var card in section.Cards) { if (Property(card, "Subtype").Contains("Mage")) { text.AppendLine("[mage]A " + card.Name + " Spellbook[/mage]"); //built by me! text.AppendLine("[mage]built by the OCTGN SBB[/mage]"); } } } text.AppendLine("[/spellbookheader]"); text.AppendLine("[spells]"); //do all the cards bool promoFound = false; foreach (var section in secArray) { if (section.Name.Contains("Mage")) { continue; } text.AppendLine("[spellclass]" + section.Name + "[/spellclass]"); foreach (var card in section.Cards) { text.AppendLine("[mwcard=" + Property(card, "CardID") + "]" + card.Quantity + " x " + card.Name + "[/mwcard]"); if (Property(card, "CardID").Contains("MWPRO")) { promoFound = true; } } } //wrap up text.AppendLine("[/spells]"); text.AppendLine("[cost]Total cost: " + MageWarsValidator.bookPoints + " pts[/cost]"); text.AppendLine("[/spellbook]"); //copy to clipboard Clipboard.SetText(text.ToString()); if (promoFound) { System.Windows.MessageBox.Show("Promos found in deck. Be aware that promos are not supported by the forum preview system."); } System.Windows.MessageBox.Show("Forum post containing deck has been copied to clipboard."); } }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { // Find the first game with cards in it. var game = con.Games.Games.FirstOrDefault(x => x.SelectCards(null).Rows.Count > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. con.SetLoadedGame(game); // Select a random card from the games card list. var cm = game.SelectRandomCardModels(1).FirstOrDefault(); var d = new Deck(game); // It's weird, but this is how you add a card. d.Sections[0].Cards.Add(new Deck.Element() { Card = cm, Quantity = (byte)1 }); // Load that mother. con.LoadDeck(d); }
/// <summary> /// Attempts to retrieve and return a reference to the MTG Game Definition from the IDeckBuilderPluginController. /// </summary> /// <param name="controller">The controller which is using this plugin. Usually it is OCTGN</param> /// <returns>Octgn Game object for MTG if installed, null otherwise.</returns> private static Game GetGameDefinition(IDeckBuilderPluginController controller) { if (controller == null) { throw new ArgumentNullException(); } return controller.Games.Games.FirstOrDefault(g => g.Id == Guid.Parse("A6C8D2E8-7CD8-11DD-8F94-E62B56D89593")); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="pluginController"></param> public void OnClick(IDeckBuilderPluginController pluginController) { // WHI: e1e11562-efce-4379-9701-534f9717391f // Find the first game with cards in it. var game = pluginController.Games.Games.FirstOrDefault(x => x.SelectCards(null).Rows.Count > 0); if (game == null) { MessageBox.Show("No Games Installed?!?!?"); return; } // Before we make a deck, we need to make sure we load the correct game for the deck. pluginController.SetLoadedGame(game); var window = new MainWindow(new MainViewModel(pluginController)); window.ShowDialog(); }
/// <summary> /// This happens when the menu item is clicked. /// </summary> /// <param name="con"></param> public void OnClick(IDeckBuilderPluginController con) { if (con.GetLoadedGame() == null || con.GetLoadedGame().Id.ToString() != "9acef3d0-efa8-4d3f-a10c-54812baecdda") { MessageBox.Show("You must have Mage Wars loaded to use this feature."); return; } var curDeck = con.GetLoadedDeck(); if (curDeck == null) { MessageBox.Show("You must have a Mage Wars deck loaded to use this feature."); return; } deckValidated = false; var secArray = curDeck.Sections.ToArray(); int cardcount = 0; int spellbook = 0; string magename = "none in deck"; int spellpoints = 0; string reporttxt = ""; bool Talos = false; int hashtotal = 0; //THIS COVERS THE UNIQUE TRAINING OF EXISTING MAGES. NOT FUTURE PROOFING SINCE FINAL SET BEING RELEASED, WILL MAKE 2.0 BETTER FUNCTIONALITY List <string> subtypeTrain = new List <string>(); List <string> comboTrain = new List <string>(); List <string> levelXTrain = new List <string>(); Dictionary <string, int> training = new Dictionary <string, int>() { { "Dark", 2 }, { "Holy", 2 }, { "Nature", 2 }, { "Mind", 2 }, { "Arcane", 2 }, { "War", 2 }, { "Earth", 2 }, { "Water", 2 }, { "Air", 2 }, { "Fire", 2 }, { "Creature", 0 } }; Dictionary <string, int> levels = new Dictionary <string, int>() { { "Dark", 0 }, { "Holy", 0 }, { "Nature", 0 }, { "Mind", 0 }, { "Arcane", 0 }, { "War", 0 }, { "Earth", 0 }, { "Water", 0 }, { "Air", 0 }, { "Fire", 0 }, { "Creature", 0 } }; foreach (var section in secArray) { foreach (var card in section.Cards) { char[] delimSubtypeChars = { ',', ' ' }; char[] delimSchoolChars = { '+', '/' }; string[] cardSubtypes = Array.ConvertAll(Property(card, "Subtype").Split(delimSubtypeChars, StringSplitOptions.RemoveEmptyEntries), p => p.Trim()); string[] cardSchools = Array.ConvertAll(Property(card, "School").Split(delimSchoolChars, StringSplitOptions.RemoveEmptyEntries), p => p.Trim()); string[] cardLevels = Array.ConvertAll(Property(card, "Level").Split(delimSchoolChars, StringSplitOptions.RemoveEmptyEntries), p => p.Trim()); bool subtypeFlag = false; bool comboTrainFlag = false; bool levelXFlag = false; hashtotal += card.GetHashCode() + card.Quantity; string Cname = Property(card, "Name"); //THIS PART IS THE EQUIVALENT OF statCardParse(deck) IN THE SBV //Get things like the Mage Name, Training, and Spellbook Limit if (Property(card, "Subtype").Contains("Mage") && Property(card, "Type").Contains("Creature")) { magename = card.Name; } if (Property(card, "Subtype").Contains("Mage") && Property(card, "Type").Contains("Magestats")) { // magename = card.Name.Split(' ')[0]; // mageName var mageschoolcost = Splitme(Property(card, "MageSchoolCost"), ","); // mageschoolcost IS THE EQUIVALENT OF 'spellbook' IN THE SpellbookValidator.py var magespellbooklimit = Splitme(Property(card, "Stats"), ","); // mageStats reporttxt += string.Format("{1}\n", card.Quantity.ToString(), card.Name); foreach (var msc in mageschoolcost) { foreach (var t in training.ToList()) { if (msc.Contains(t.Key)) //scan mageschoolcost for training info { var tlevel = Splitme(msc, "="); training[t.Key] = Convert.ToInt32(tlevel[1]); string messageStr = DictionaryToString(training); } } } //Figure out how many spellbook points are allowed by the mage from the "Stats" property foreach (var mstat in magespellbooklimit) { if (mstat.Contains("Spellbook")) { spellpoints = Convert.ToInt32(Splitme(mstat, "=")[1]); //spellPointsTotal } } char[] delimiterChars = { '-', '=', ' ' }; foreach (string msc in mageschoolcost) // for key in spellbook: { if (msc.StartsWith("S-") | (msc.StartsWith(" S-"))) // if key.startswith ('S-'): { string[] addStr = msc.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries); foreach (string tempStr in addStr) { int len = tempStr.Length; if (len > 1) { subtypeTrain.Add(tempStr); } } } else if (msc.StartsWith("C-") | (msc.StartsWith(" C-"))) // elif key.startswith ('C-'): { string[] addStr = msc.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries); foreach (string tempStr in addStr) { comboTrain.Add(tempStr); } } else if (msc.StartsWith("L-") | (msc.StartsWith(" L-"))) // elif key.startswith ('L-'): { string[] addStr = msc.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries); foreach (string tempStr in addStr) { if (tempStr.Length > 1) { training[tempStr] = 2; } levelXTrain.Add(tempStr); } } } continue; } // FROM HERE BELOW ARE THINGS WRAPPED UP IN cardPointCount FROM THE SBV. WILL NEED TO REWRITE WITH THE NEW METHODOLOGY if (HasProperty(card, "Traits")) { if (Property(card, "Traits").Contains("Novice")) //Novice spells always cost 1 point { cardcount += card.Quantity; spellbook += card.Quantity; var typestr = Property(card, "Type"); if (typestr.Equals("Conjuration-Wall")) { typestr = "Conjuration"; } if (!reporttxt.Contains(typestr)) // has this type been listed before?? { reporttxt += string.Format("\n--- {0} ---\n", typestr); } reporttxt += string.Format("{0} - {1} - 1 - 1 - {0}\n", card.Quantity.ToString(), card.Name); continue; } } if (card.Name.Contains("Talos")) { Talos = true; } else { Talos = false; } if (HasProperty(card, "School") & HasProperty(card, "Level")) { bool isEmptyLevelX = isEmpty(levelXTrain); var school = Property(card, "School"); var level = Property(card, "Level"); var typestr = Property(card, "Type"); if (typestr.Equals("Conjuration-Wall")) { typestr = "Conjuration"; } if (typestr.Equals("Conjuration-Terrain")) { typestr = "Conjuration"; } if (!reporttxt.Contains(typestr)) // has this type been listed before?? { reporttxt += string.Format("\n--- {0} ---\n", typestr); } reporttxt += string.Format("{0} - {1} - ", card.Quantity.ToString(), card.Name); //Calculate card's spell level int totalLevel = 0; string deli = level.Contains("+") ? "+" : level.Contains("/") ? "/" : ""; if (deli == "/") { string lev = level.Substring(0, 1); totalLevel = Convert.ToInt32(lev); } else if (deli == "+") { string[] levs = level.Split('+'); string[] schs = school.Split('+'); for (int i = 0; i < levs.Length; ++i) { totalLevel += Convert.ToInt32(levs[i]); } } else { totalLevel = Convert.ToInt32(level); } //calculate spell cost in book int cost = 0; if (!Talos) { bool isEmptySub = isEmpty(subtypeTrain); bool isEmptyCombo = isEmpty(comboTrain); if (!isEmptySub) { foreach (string sType in subtypeTrain) { foreach (string cSType in cardSubtypes) { if (sType == cSType) { subtypeFlag = true; } } } } if (!isEmptyCombo) { //I'm cheating on this part since Paladin's the only combo trained mage (Holy + Creature) that will exist in 1.0 as of 7/7/2020 //I'm going to just move on to the next edition project. I can fix if ever needed in the future foreach (string cSchool in cardSchools) { if (cSchool.Contains("Holy") & Property(card, "Type").Contains("Creature")) { comboTrainFlag = true; } } } if (!isEmptyLevelX) { foreach (string cSchool in cardSchools) { if (levelXTrain.Contains(cSchool)) { int Lx_ind = levelXTrain.IndexOf(cSchool); int trainLevel = Convert.ToInt32(levelXTrain[Lx_ind - 1]); int c_ind = Array.IndexOf(cardSchools, cSchool); int cLevel = Convert.ToInt32(cardLevels[c_ind]); if (cLevel <= trainLevel) { levelXFlag = true; } } } } if (subtypeFlag) { cost = totalLevel; //This is only built to handle if someone is trained in subtypes (vs Opposed training) since that's all that exists for MW 1. //It wouldn't be hard to adjust for opposed training, but probably isn't worth the effort at the moment } else if (comboTrainFlag) { cost = totalLevel; //This is only built to handle if someone is combo trained (vs combo Opposed training) since that's all that exists for MW 1. //It wouldn't be hard to adjust for opposed training, but probably isn't worth the effort at the moment } else if (levelXFlag) { //If the levelxflag is triggered and / in the cost, split the level and schools and just do cost = totalLevel if (school.Contains('/')) { cost = totalLevel; } else { foreach (string cSchool in cardSchools) { int curInd = Array.IndexOf(cardSchools, cSchool); int curLevel = Convert.ToInt32(cardLevels[curInd]); if (levelXTrain.Contains(cSchool)) { int Lx_ind = levelXTrain.IndexOf(cSchool); int trainLevel = Convert.ToInt32(levelXTrain[Lx_ind - 1]); if (curLevel <= trainLevel) { cost += curLevel; } else { cost += training[cSchool] * curLevel; } } else { cost += training[cSchool] * curLevel; } } } } else if ((magename.Contains("Forcemaster") & "Creature" == Property(card, "Type")) | (magename.Contains("Monk") & "Creature" == Property(card, "Type"))) { if (!school.Contains("Mind")) //"Mind" not in schools { if (school.Contains("+")) { foreach (var lev in Splitme(level, "+")) { cost += Convert.ToInt32(lev) * 3; } } else //handle single school or "/" school cards { var lev = Splitme(level, "/"); cost += Convert.ToInt32(lev[0]) * 3; } } else { if (school.Contains("+")) { foreach (var lev in Splitme(level, "+")) { cost += Convert.ToInt32(lev); } } else //handle single school or "/" school cards { var lev = Splitme(level, "/"); cost += Convert.ToInt32(lev[0]); } } } else if (school.Contains("+")) //add all spell levels { var lev = Splitme(level, "+"); int x = 0; foreach (var s in Splitme(school, "+")) { cost += Convert.ToInt32(lev[x]) * training[s]; levels[s] += Convert.ToInt32(lev[x]) * card.Quantity; x++; } } else if (school.Contains("/")) //add just the cheapest of these { if (magename == "none in deck") //no mage found yet { System.Windows.MessageBox.Show("Warning - No mage card has been found yet. This may lead to inaccurate calculations. Ensure that the first card in the deck is a mage"); } var lev = Splitme(level, "/")[0]; //just take the first value as each is the same var mincost = 3; string minschool = ""; foreach (var s in Splitme(school, "/")) { if (training[s] < mincost) { minschool = s; mincost = training[s]; } } cost += Convert.ToInt32(lev) * training[minschool]; levels[minschool] += Convert.ToInt32(lev) * card.Quantity; } else //Only one school in spell { if (training.ContainsKey(school)) { cost += Convert.ToInt32(level) * training[school]; levels[school] += Convert.ToInt32(level) * card.Quantity; } } } //check for multiples of Epic spells if (Property(card, "Traits").Contains("Epic") && card.Quantity > 1) { System.Windows.MessageBox.Show("Validation FAILED: Only one copy of Epic card " + card.Name + " is allowed.\n" + card.Quantity + " copies found in spellbook."); return; } //check for illegal school- or mage-specific spells if (Property(card, "Traits").Contains("Only")) { string[] traits = Property(card, "Traits").Split(','); List <string> onlyTraits = traits.Where(s => s.Contains("Only")).ToList(); if (onlyTraits.Count == 1) { string onlyPhrase = onlyTraits[0]; bool legal = false; //check mage restriction string mname = magename; if (mname.Contains("Beastmaster")) { mname = "Beastmaster"; } if (mname.Contains("Wizard")) { mname = "Wizard"; } if (mname.Contains("Warlock")) { mname = "Warlock"; } if (mname.Contains("Warlord")) { mname = "Warlord"; } if (mname.Contains("Priestess")) { mname = "Priestess"; } if (mname.Contains("Paladin")) { mname = "Paladin"; } if (mname.Contains("Siren")) { mname = "Siren"; } if (mname.Contains("Forcemaster")) { mname = "Forcemaster"; } if (mname.Contains("Monk")) { mname = "Monk"; } if (onlyPhrase.Contains(mname)) { legal = true; } //check class restriction foreach (string schoolKey in training.Keys) { if (training[schoolKey] == 1 && onlyPhrase.Contains(schoolKey + " Mage")) { legal = true; } else if (!isEmptyLevelX) { foreach (string cSchool in cardSchools) { if (levelXTrain.Contains(cSchool)) { int Lx_ind = levelXTrain.IndexOf(cSchool); int trainLevel = Convert.ToInt32(levelXTrain[Lx_ind - 1]); int c_ind = Array.IndexOf(cardSchools, cSchool); int cLevel = Convert.ToInt32(cardLevels[c_ind]); if (cLevel <= trainLevel) { legal = true; } } } } } if (!legal) { System.Windows.MessageBox.Show("Validation FAILED: The card " + card.Name + " is not legal in a " + magename + " deck."); return; } } } // Check for correct number of cards int l = 0; if (level.Contains("+")) { var levArr = Splitme(level, "+"); foreach (string s in levArr) { l += Convert.ToInt32(s); } } else if (level.Contains("/")) { var levArr = Splitme(level, "/"); l = Convert.ToInt32(levArr[0]); } else { l = Convert.ToInt32(level); } if ((l == 1 && card.Quantity > 6 && (!card.Name.Contains("Shallow Sea") && magename.Contains("Siren")) || (l >= 2 && card.Quantity > 4))) { // too many System.Windows.MessageBox.Show("Validation FAILED: There are too many copies of " + card.Name + " in the deck."); return; } cardcount += card.Quantity; reporttxt += string.Format("{0} - {1} - {2}\n", totalLevel.ToString(), cost.ToString(), (cost * card.Quantity).ToString()); spellbook += cost * card.Quantity; //System.Windows.MessageBox.Show(card.Name + "\nPoints:"+cost); } //card has school and level } //foreach card } //foreach section string reporttmp = "A Mage Wars Spellbook, built using the OCTGN SBB " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + "\n\n"; reporttmp += string.Format("Spellbook points: {0} used of {0} allowed\n\n", spellbook, spellpoints); reporttmp += "Key: Quantity - Spell Name - Spell Level - Spellbook Cost - Total Spellbook Cost\n\n"; reporttmp += reporttxt; Clipboard.SetText(reporttmp); if (magename == "none in deck") { System.Windows.MessageBox.Show("Validation result:\nNo mage is detected in the book"); } else { System.Windows.MessageBox.Show(String.Format("Validation result:\n{0} spellpoints in the deck using '{1}' as the mage. {2} spellpoints are allowed.\nDeck has been copied to the clipboard.", spellbook, magename, spellpoints)); } if (spellbook <= spellpoints) { deckValidated = true; bookPoints = spellbook; totalCards = cardcount; validatedDeckHash = hashtotal; } }