public static void List(string question, Dictionary <object, string> options, Action okay, bool allowEscape = false, bool doNotPush = false, string title = "", string icon = "") { fromWalkaround = NoxicoGame.Subscreen == null || Subscreens.PreviousScreen.Count == 0; if (!doNotPush) { Subscreens.PreviousScreen.Push(NoxicoGame.Subscreen); } NoxicoGame.Subscreen = MessageBox.Handler; type = BoxType.List; MessageBox.title = title; width = 46; foreach (var o in options.Values) { if (o.Length() + 2 > width) { width = o.Length() + 2; } } text = Toolkit.Wordwrap(question.Trim(), width); //.Split('\n'); option = 0; onYes = okay; MessageBox.options = options; MessageBox.allowEscape = allowEscape; MessageBox.icon = icon.IsBlank() ? null : new UIPNG(Mix.GetBitmap(icon)); NoxicoGame.Mode = UserMode.Subscreen; Subscreens.FirstDraw = true; }
private void CachePNGFont(Bitmap source = null) { if (source == null) { source = Mix.GetBitmap("fonts\\" + pngFont + ".png"); } var cWidth = source.Width / 32; var cHeight = source.Height / 32; fontData = new byte[1024, cWidth *cHeight]; palette = source.Palette.Entries; for (var ch = 0; ch < 1024; ch++) { var i = 0; var sX = (ch % 32) * cWidth; var sY = (ch / 32) * cHeight; for (var y = 0; y < cHeight; y++) { for (var x = 0; x < cWidth; x++) { //fontData[ch, i] = (byte)(source.GetPixel(sX + x, sY + y).R); // > 127 ? 1 : 0); var c = source.GetPixel(sX + x, sY + y); for (var p = 0; p < palette.Length; p++) { if (c == palette[p]) { fontData[ch, i] = (byte)p; break; } } i++; } } } }
public static void Init() { if (Sheet == null) { Sheet = Mix.GetBitmap("fonts\\8x16-bold.png"); } }
public static void Notice(string message, bool doNotPush = false, string title = "", string icon = "") { fromWalkaround = NoxicoGame.Subscreen == null || Subscreens.PreviousScreen.Count == 0; if (!doNotPush) { Subscreens.PreviousScreen.Push(NoxicoGame.Subscreen); } NoxicoGame.Subscreen = MessageBox.Handler; MessageBox.title = title; type = BoxType.Notice; width = 46; text = Toolkit.Wordwrap(message.Trim(), width); //.Split('\n'); MessageBox.icon = icon.IsBlank() ? null : new UIPNG(Mix.GetBitmap(icon)); NoxicoGame.Mode = UserMode.Subscreen; Subscreens.FirstDraw = true; }
/// <summary> /// Generic Subscreen handler. /// </summary> public static void TitleHandler() { var host = NoxicoGame.HostForm; if (Subscreens.FirstDraw) { Subscreens.FirstDraw = false; host.Clear(); var xScale = Program.Cols / 80f; var yScale = Program.Rows / 25f; var background = new Bitmap(Program.Cols, Program.Rows * 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var logo = Mix.GetBitmap("logo.png"); var titleOptions = Mix.GetFilesWithPattern("titles\\*.png"); var chosen = Mix.GetBitmap(titleOptions.PickOne()); //Given our random backdrop and fixed logo, draw them both onto background //because we can't -just- display alpha-blended PNGs. using (var gfx = Graphics.FromImage(background)) { gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; gfx.Clear(Color.Black); gfx.DrawImage(chosen, 0, 0, Program.Cols, Program.Rows * 2); gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; gfx.DrawImage(logo, 0, 0, logo.Width * xScale, logo.Height * yScale); } UIManager.Initialize(); titleBack = new UIPNGBackground(background); var subtitleLeft = (int)(10 * xScale); var subtitleTop = (int)((logo.Height * yScale) / 2) + 1; var subtitle = i18n.GetString("ts_subtitle"); var pressEnter = "\xC4\xC4\xC4\xC4\xB4 " + i18n.GetString("ts_pressentertobegin") + " <cGray>\xC3\xC4\xC4\xC4\xC4"; titleCaption = new UILabel(subtitle) { Top = subtitleTop, Left = subtitleLeft + 2, Foreground = Color.Teal, Darken = true }; titlePressEnter = new UILabel(pressEnter) { Top = subtitleTop + 2, Left = subtitleLeft, Foreground = Color.Gray, Darken = true }; UIManager.Elements.Add(titleBack); UIManager.Elements.Add(titleCaption); UIManager.Elements.Add(titlePressEnter); //UIManager.Elements.Add(new UILabel("\u015c") { Top = 6, Left = 50, Foreground = Color.Gray }); UIManager.Draw(); Options.FromTitle = true; } if (NoxicoGame.IsKeyDown(KeyBinding.Accept) || Subscreens.Mouse || Vista.Triggers != 0) { if (Subscreens.Mouse) { Subscreens.UsingMouse = true; } Subscreens.Mouse = false; Subscreens.FirstDraw = true; var rawSaves = Directory.GetDirectories(NoxicoGame.SavePath); var saves = new List <string>(); //Check each possible save's version. foreach (var s in rawSaves) { var verCheck = Path.Combine(s, "version"); if (!File.Exists(verCheck)) { continue; } var version = int.Parse(File.ReadAllText(verCheck)); if (version < 20) { continue; } if (File.Exists(Path.Combine(s, "global.bin"))) { saves.Add(s); } } NoxicoGame.ClearKeys(); Subscreens.Mouse = false; //Linq up a set of options for each save game. This returns the game's names as the keys. var options = saves.ToDictionary(new Func <string, object>(s => Path.GetFileName(s)), new Func <string, string>(s => { string p; var playerFile = Path.Combine(s, "player.bin"); if (File.Exists(playerFile)) { using (var f = new BinaryReader(File.OpenRead(playerFile))) { p = Player.LoadFromFile(f).Character.Name.ToString(true); } return(i18n.Format("ts_loadgame", p, Path.GetFileName(s))); } return(i18n.Format("ts_startoverinx", Path.GetFileName(s))); })); options.Add("~", i18n.GetString("ts_startnewgame")); options.Add("~~", i18n.GetString("ts_testingarena")); options.Add("~~~", i18n.GetString("ts_options")); //Display our list of saves. MessageBox.List(saves.Count == 0 ? i18n.GetString("ts_welcometonoxico") : i18n.GetString(saves.Count == 1 ? "ts_thereisasave" : "ts_therearesaves"), options, () => { if ((string)MessageBox.Answer == "~") { //Restore our title screen backdrop, since the MessageBox subscreen purged it. UIManager.Elements.Add(titleBack); UIManager.Elements.Add(titleCaption); UIManager.Elements.Add(titlePressEnter); UIManager.Draw(); MessageBox.Input("What name would you like for your new world?", NoxicoGame.RollWorldName(), () => { NoxicoGame.WorldName = (string)MessageBox.Answer; NoxicoGame.Mode = UserMode.Subscreen; NoxicoGame.Subscreen = Introduction.CharacterCreator; NoxicoGame.Immediate = true; } ); } else if ((string)MessageBox.Answer == "~~") { NoxicoGame.WorldName = "<Testing Arena>"; var env = Lua.Environment; Lua.RunFile("testarena.lua"); var testBoard = new Board(env.TestArena.ArenaWidth, env.TestArena.ArenaHeight); var me = NoxicoGame.Me; me.Boards.Add(testBoard); me.CurrentBoard = testBoard; me.CreatePlayerCharacter(env.TestArena.Name, env.TestArena.BioGender, env.TestArena.IdentifyAs, env.TestArena.Preference, env.TestArena.Bodyplan, new Dictionary <string, string>(), env.TestArena.BonusTrait); env.BuildTestArena(testBoard); me.Player.ParentBoard = testBoard; testBoard.EntitiesToAdd.Add(me.Player); NoxicoGame.InGameTime = new DateTime(740 + Random.Next(0, 20), 6, 26, 12, 0, 0); testBoard.UpdateLightmap(null, true); testBoard.AimCamera(); testBoard.Redraw(); testBoard.Draw(); Options.FromTitle = false; Subscreens.FirstDraw = true; NoxicoGame.Immediate = true; NoxicoGame.AddMessage(i18n.GetString("welcometest"), Color.Yellow); NoxicoGame.AddMessage(i18n.GetString("rememberhelp")); NoxicoGame.Mode = UserMode.Walkabout; } else if ((string)MessageBox.Answer == "~~~") { Options.FromTitle = true; //Restore our title screen backdrop, since the MessageBox subscreen purged it. UIManager.Initialize(); UIManager.Elements.Add(titleBack); UIManager.Elements.Add(titleCaption); UIManager.Elements.Add(titlePressEnter); Options.Open(); } else { Options.FromTitle = false; NoxicoGame.WorldName = (string)MessageBox.Answer; host.Noxico.LoadGame(); NoxicoGame.Me.CurrentBoard.Draw(); Subscreens.FirstDraw = true; NoxicoGame.Immediate = true; NoxicoGame.AddMessage(i18n.GetString("welcomeback"), Color.Yellow); NoxicoGame.AddMessage(i18n.GetString("rememberhelp")); //TextScroller.LookAt(NoxicoGame.Me.Player); NoxicoGame.Mode = UserMode.Walkabout; } } ); } }
private static Bitmap backdrop; //, backWithPortrait; /// <summary> /// Don't see a Subscreen with multiple handlers often... /// </summary> public static void CharacterCreator() { if (Subscreens.FirstDraw) { //Start creating the world as we work... if (worldgen == null) //Conditional added by Mat. { worldgen = new System.Threading.Thread(NoxicoGame.Me.CreateRealm); worldgen.Start(); } //Load all bonus traits. var traits = new List <string>(); var traitHelps = new List <string>(); var traitsDoc = Mix.GetTokenTree("bonustraits.tml"); foreach (var trait in traitsDoc.Where(t => t.Name == "trait")) { traits.Add(trait.GetToken("display").Text); traitHelps.Add(trait.GetToken("description").Text); } //Define the help texts for the standard controls. controlHelps = new Dictionary <string, string>() { { "back", i18n.GetString("cchelp_back") }, { "next", i18n.GetString("cchelp_next") }, { "play", Random.NextDouble() > 0.7 ? "FRUITY ANGELS MOLEST SHARKY" : "ENGAGE RIDLEY MOTHER F****R" }, { "name", i18n.GetString("cchelp_name") }, { "species", string.Empty }, { "sex", i18n.GetString("cchelp_sex") }, { "gid", i18n.GetString("cchelp_gid") }, { "pref", i18n.GetString("cchelp_pref") }, { "tutorial", i18n.GetString("cchelp_tutorial") }, { "easy", i18n.GetString("cchelp_easy") }, { "gift", traitHelps[0] }, }; var xScale = Program.Cols / 80f; var yScale = Program.Rows / 25f; //backdrop = Mix.GetBitmap("chargen.png"); backdrop = new Bitmap(Program.Cols, Program.Rows * 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var ccback = Mix.GetBitmap("ccback.png"); var ccpage = Mix.GetBitmap("ccpage.png"); var ccbars = Mix.GetBitmap("ccbars.png"); var pageLeft = Program.Cols - ccpage.Width - (int)(2 * yScale); var pageTop = Program.Rows - (ccpage.Height / 2); using (var gfx = Graphics.FromImage(backdrop)) { gfx.Clear(Color.Black); gfx.DrawImage(ccback, 0, 0, Program.Cols, Program.Rows * 2); gfx.DrawImage(ccpage, pageLeft, pageTop, ccpage.Width, ccpage.Height); var barsSrc = new System.Drawing.Rectangle(0, 3, ccbars.Width, 7); var barsDst = new System.Drawing.Rectangle(0, 0, Program.Cols, 7); gfx.DrawImage(ccbars, barsDst, barsSrc, GraphicsUnit.Pixel); barsSrc = new System.Drawing.Rectangle(0, 0, ccbars.Width, 5); barsDst = new System.Drawing.Rectangle(0, (Program.Rows * 2) - 5, Program.Cols, 5); gfx.DrawImage(ccbars, barsDst, barsSrc, GraphicsUnit.Pixel); } //Build the interface. var title = "\xB4 " + i18n.GetString("cc_title") + " \xC3"; var bar = new string('\xC4', 33); string[] sexoptions = { i18n.GetString("Male"), i18n.GetString("Female"), i18n.GetString("Herm"), i18n.GetString("Neuter") }; string[] prefoptions = { i18n.GetString("Male"), i18n.GetString("Female"), i18n.GetString("Either") }; var labelL = pageLeft + 5; var cntrlL = labelL + 2; var header = (pageTop / 2) + 3; var top = header + 2; var buttons = (pageTop / 2) + 20; controls = new Dictionary <string, UIElement>() { { "backdrop", new UIPNGBackground(backdrop) }, //backWithPortrait) }, { "headerline", new UILabel(bar) { Left = labelL, Top = header, Foreground = Color.Black } }, { "header", new UILabel(title) { Left = labelL + 17 - (title.Length() / 2), Top = header, Width = title.Length(), Foreground = Color.Black } }, { "back", new UIButton(i18n.GetString("cc_back"), null) { Left = labelL, Top = buttons, Width = 10, Height = 1 } }, { "next", new UIButton(i18n.GetString("cc_next"), null) { Left = labelL + 23, Top = buttons, Width = 10, Height = 1 } }, { "wait", new UILabel(i18n.GetString("cc_wait")) { Left = labelL + 23, Top = buttons, Foreground = Color.Silver } }, { "play", new UIButton(i18n.GetString("cc_play"), null) { Left = labelL + 23, Top = buttons, Width = 10, Height = 1, Hidden = true } }, { "nameLabel", new UILabel(i18n.GetString("cc_name")) { Left = labelL, Top = top, Foreground = Color.Gray } }, { "name", new UITextBox(string.Empty) { Left = cntrlL, Top = top + 1, Width = 24, Foreground = Color.Black, Background = Color.Transparent } }, { "nameRandom", new UILabel(i18n.GetString("cc_random")) { Left = cntrlL + 2, Top = top + 1, Foreground = Color.Gray } }, { "speciesLabel", new UILabel(i18n.GetString("cc_species")) { Left = labelL, Top = top + 3, Foreground = Color.Gray } }, { "species", new UISingleList() { Left = cntrlL, Top = top + 4, Width = 26, Foreground = Color.Black, Background = Color.Transparent } }, { "tutorial", new UIToggle(i18n.GetString("cc_tutorial")) { Left = labelL, Top = top + 6, Width = 24, Foreground = Color.Black, Background = Color.Transparent } }, { "easy", new UIToggle(i18n.GetString("cc_easy")) { Left = labelL, Top = top + 7, Width = 24, Foreground = Color.Black, Background = Color.Transparent } }, { "sexLabel", new UILabel(i18n.GetString("cc_sex")) { Left = labelL, Top = top, Foreground = Color.Gray } }, { "sex", new UIRadioList(sexoptions) { Left = cntrlL, Top = top + 1, Width = 24, Foreground = Color.Black, Background = Color.Transparent } }, { "gidLabel", new UILabel(i18n.GetString("cc_gid")) { Left = labelL, Top = top + 6, Foreground = Color.Gray } }, { "gid", new UISingleList(string.Empty, null, sexoptions.ToList(), 0) { Left = cntrlL, Top = top + 7, Width = 26, Foreground = Color.Black, Background = Color.Transparent } }, { "prefLabel", new UILabel(i18n.GetString("cc_pref")) { Left = labelL, Top = top + 9, Foreground = Color.Gray } }, { "pref", new UISingleList(string.Empty, null, prefoptions.ToList(), 1) { Left = cntrlL, Top = top + 10, Width = 26, Foreground = Color.Black, Background = Color.Transparent } }, { "giftLabel", new UILabel(i18n.GetString("cc_gift")) { Left = labelL, Top = top, Foreground = Color.Gray } }, { "gift", new UIList(string.Empty, null, traits) { Left = cntrlL, Top = top + 1, Width = 30, Height = 24, Foreground = Color.Black, Background = Color.Transparent } }, { "controlHelp", new UILabel(traitHelps[0]) { Left = 1, Top = 1, Width = pageLeft - 2, Height = 4, Foreground = Color.White, Darken = true } }, { "topHeader", new UILabel(i18n.GetString("cc_header")) { Left = 1, Top = 0, Foreground = Color.Silver } }, { "helpLine", new UILabel(i18n.GetString("cc_footer")) { Left = 1, Top = Program.Rows - 1, Foreground = Color.Silver } }, }; //Map the controls to pages. pages = new List <UIElement>[] { new List <UIElement>() { controls["backdrop"], controls["headerline"], controls["header"], controls["topHeader"], controls["helpLine"], controls["nameLabel"], controls["name"], controls["nameRandom"], controls["speciesLabel"], controls["species"], controls["tutorial"], controls["easy"], controls["controlHelp"], controls["next"], }, new List <UIElement>() { controls["backdrop"], controls["headerline"], controls["header"], controls["topHeader"], controls["helpLine"], controls["sexLabel"], controls["sex"], controls["gidLabel"], controls["gid"], controls["prefLabel"], controls["pref"], controls["controlHelp"], controls["back"], controls["next"], }, new List <UIElement>(), //Placeholder, filled in on-demand from PlayableRace.ColorItems. new List <UIElement>() { controls["backdrop"], controls["headerline"], controls["header"], controls["topHeader"], controls["helpLine"], controls["giftLabel"], controls["gift"], controls["controlHelp"], controls["back"], controls["wait"], controls["play"], }, }; CollectPlayables(); loadPage = new Action <int>(p => { UIManager.Elements.Clear(); UIManager.Elements.AddRange(pages[page]); UIManager.Highlight = UIManager.Elements[5]; //select whatever comes after helpLine. }); //Called when changing species. loadColors = new Action <int>(i => { var species = playables[i]; controlHelps["species"] = species.Bestiary; pages[2].Clear(); pages[2].AddRange(new[] { controls["backdrop"], controls["headerline"], controls["header"], controls["topHeader"], controls["helpLine"] }); pages[2].AddRange(species.ColorItems.Values); pages[2].AddRange(new[] { controls["controlHelp"], controls["back"], controls["next"] }); }); controls["back"].Enter = (s, e) => { page--; loadPage(page); UIManager.Draw(); }; controls["next"].Enter = (s, e) => { page++; loadPage(page); UIManager.Draw(); }; controls["play"].Enter = (s, e) => { var playerName = controls["name"].Text; var sex = ((UIRadioList)controls["sex"]).Value; var gid = ((UISingleList)controls["gid"]).Index; var pref = ((UISingleList)controls["pref"]).Index; var species = ((UISingleList)controls["species"]).Index; var tutorial = ((UIToggle)controls["tutorial"]).Checked; var easy = ((UIToggle)controls["easy"]).Checked; var bonus = ((UIList)controls["gift"]).Text; var colorMap = new Dictionary <string, string>(); foreach (var editable in playables[species].ColorItems) { if (editable.Key.StartsWith("lbl")) { continue; } var path = editable.Key; var value = ((UISingleList)editable.Value).Text; colorMap.Add(path, value); } NoxicoGame.Me.CreatePlayerCharacter(playerName.Trim(), (Gender)(sex + 1), (Gender)(gid + 1), pref, playables[species].ID, colorMap, bonus); if (tutorial) { NoxicoGame.Me.Player.Character.AddToken("tutorial"); } if (easy) { NoxicoGame.Me.Player.Character.AddToken("easymode"); } NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddYears(Random.Next(0, 10)); NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddDays(Random.Next(20, 340)); NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddHours(Random.Next(10, 54)); NoxicoGame.Me.CurrentBoard.UpdateLightmap(NoxicoGame.Me.Player, true); Subscreens.FirstDraw = true; NoxicoGame.Immediate = true; /* #if DEBUG * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("orgasm_denial_ring"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("baseballbat"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("really_kinky_panties"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("timertest"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("clit_regenring"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("gExtractor"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("strapon_ovi"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("strapon"); #if FREETESTPOTIONS * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("foxite"); // ok * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("odd_nip"); // ok * //NoxicoGame.Me.Player.Character.GetToken("items").AddToken("dogmorph"); no bodyplan * //NoxicoGame.Me.Player.Character.GetToken("items").AddToken("bunnymorph"); no bodyplan * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("chaos_potion"); // ok * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("enhanced_chaos_potion"); // ok * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("demonite_potion"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("tentacle_potion"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("cock_potion"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("corrupted_cock_potion"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("neutralizer_potion"); * NoxicoGame.Me.Player.Character.GetToken("items").AddToken("spidermorph"); #endif #endif */ NoxicoGame.AddMessage(i18n.GetString("welcometonoxico"), Color.Yellow); NoxicoGame.AddMessage(i18n.GetString("rememberhelp")); //Story(); }; ((UISingleList)controls["species"]).Items.Clear(); playables.ForEach(x => ((UISingleList)controls["species"]).Items.Add(x.Name.Titlecase())); ((UISingleList)controls["species"]).Index = 0; loadColors(0); ((UIRadioList)controls["sex"]).ItemsEnabled = playables[0].SexLocks; controls["species"].Change = (s, e) => { var speciesIndex = ((UISingleList)controls["species"]).Index; loadColors(speciesIndex); var playable = playables[speciesIndex]; controlHelps["species"] = playable.Bestiary; controls["controlHelp"].Text = playable.Bestiary.Wordwrap(controls["controlHelp"].Width); var sexList = (UIRadioList)controls["sex"]; sexList.ItemsEnabled = playable.SexLocks; if (!sexList.ItemsEnabled[sexList.Value]) { //Uh-oh. Select the first non-disabled item. for (var i = 0; i < sexList.ItemsEnabled.Length; i++) { if (sexList.ItemsEnabled[i]) { sexList.Value = i; break; } } } //redrawBackdrop(0); UIManager.Draw(); }; controls["sex"].Change = (s, e) => { //redrawBackdrop(0); UIManager.Draw(); }; controls["name"].Change = (s, e) => { controls["nameRandom"].Hidden = !controls["name"].Text.IsBlank(); UIManager.Draw(); }; controls["gift"].Change = (s, e) => { var giftIndex = ((UIList)controls["gift"]).Index; controls["controlHelp"].Text = traitHelps[giftIndex].Wordwrap(controls["controlHelp"].Width); controls["controlHelp"].Top = controls["gift"].Top + giftIndex; UIManager.Draw(); }; ((UIToggle)controls["tutorial"]).Checked = IniFile.GetValue("misc", "tutorial", true); ((UIToggle)controls["easy"]).Checked = IniFile.GetValue("misc", "easymode", false); UIManager.Initialize(); UIManager.HighlightChanged = (s, e) => { var c = controls.FirstOrDefault(x => x.Value == UIManager.Highlight); if (c.Key != null && controlHelps.ContainsKey(c.Key)) { controls["controlHelp"].Text = controlHelps[c.Key].Wordwrap(controls["controlHelp"].Width); controls["controlHelp"].Top = c.Value.Top; } else { controls["controlHelp"].Text = string.Empty; } UIManager.Draw(); }; loadPage(page); //redrawBackdrop(0); Subscreens.FirstDraw = false; Subscreens.Redraw = true; UIManager.HighlightChanged(null, null); NoxicoGame.Sound.PlayMusic("set://Character Creation", false); NoxicoGame.InGame = false; } if (Subscreens.Redraw) { UIManager.Draw(); Subscreens.Redraw = false; } if (WorldGenFinished) { WorldGenFinished = false; controls["play"].Hidden = false; UIManager.Draw(); } UIManager.CheckKeys(); }
/// <summary> /// Goes through bodyplans.tml to get a list of PlayableRaces. /// </summary> private static void CollectPlayables() { playables = new List <PlayableRace>(); Program.WriteLine("Collecting playables..."); foreach (var bodyPlan in Character.Bodyplans.Where(t => t.Name == "bodyplan")) { var id = bodyPlan.Text; var plan = bodyPlan.Tokens; if (!bodyPlan.HasToken("playable")) { continue; } Program.WriteLine(" * Parsing {0}...", id); var sexlocks = new[] { true, true, true, false }; if (bodyPlan.HasToken("normalgenders")) { sexlocks = new[] { true, true, false, false } } ; else if (bodyPlan.HasToken("maleonly")) { sexlocks = new[] { true, false, false, false } } ; else if (bodyPlan.HasToken("femaleonly")) { sexlocks = new[] { false, true, false, false } } ; else if (bodyPlan.HasToken("hermonly")) { sexlocks = new[] { false, false, true, false } } ; else if (bodyPlan.HasToken("neuteronly")) { sexlocks = new[] { false, false, false, true } } ; if (bodyPlan.HasToken("allowneuter")) { sexlocks[3] = true; } //Use the ID ("bodyplan: example") as the name, unless there's a "playable: proper name". var name = id.Replace('_', ' ').Titlecase(); if (!bodyPlan.GetToken("playable").Text.IsBlank()) { name = bodyPlan.GetToken("playable").Text; } var bestiary = bodyPlan.HasToken("bestiary") ? bodyPlan.GetToken("bestiary").Text : string.Empty; //Figure out what to put on page two. //By default, we assume skin and hair colors can be edited. //Most bodyplans will be different, though. var colorItems = new Dictionary <string, UIElement>(); var editables = "skin/color|Skin color, hair/color|Hair color"; //path|Label, path|Label... if (bodyPlan.HasToken("editable")) { editables = bodyPlan.GetToken("editable").Text; } var xScale = Program.Cols / 80f; var yScale = Program.Rows / 25f; var ccpage = Mix.GetBitmap("ccpage.png"); var pageLeft = Program.Cols - ccpage.Width - (int)(2 * yScale); var pageTop = Program.Rows - (ccpage.Height / 2); var labelL = pageLeft + 5; var cntrlL = labelL + 2; var top = (pageTop / 2) + 5; var width = 26; foreach (var aspect in editables.Split(',')) { if (aspect.IsBlank()) { continue; } var a = aspect.Trim().Split('|'); var path = a[0]; var label = a[1]; var t = bodyPlan.Path(path).Text; if (t.StartsWith("oneof")) { t = t.Substring(6); } var oneof = t.Split(',').ToList(); var items = new List <string>(); colorItems.Add("lbl-" + path, new UILabel(label) { Left = labelL, Top = top, Foreground = Color.Gray }); foreach (var i in oneof) { var iT = i.Trim(); iT = iT.IsBlank(i18n.GetString("[none]", false), iT.Titlecase()); if (!items.Contains(iT)) { items.Add(iT); } } if (label.EndsWith("color", StringComparison.InvariantCultureIgnoreCase)) { for (var i = 0; i < items.Count; i++) { items[i] = Color.NameColor(items[i]).Titlecase(); } colorItems.Add(path, new UIColorList() { Items = items, Left = cntrlL, Top = top + 1, Width = width, Foreground = Color.Black, Background = Color.Transparent, Index = 0 }); } else { colorItems.Add(path, new UISingleList() { Items = items, Left = cntrlL, Top = top + 1, Width = width, Foreground = Color.Black, Background = Color.Transparent, Index = 0 }); } top += 2; } playables.Add(new PlayableRace() { ID = id, Name = name, Bestiary = bestiary, ColorItems = colorItems, SexLocks = sexlocks }); } }
public void RestartGraphics(bool full) { pngFont = IniFile.GetValue("misc", "font", "8x16-bold"); if (!Mix.FileExists("fonts\\" + pngFont + ".png")) { pngFont = "8x16-bold"; if (!Mix.FileExists("fonts\\" + pngFont + ".png")) { SystemMessageBox.Show(this, "Could not find font bitmaps. Please redownload the game.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); return; } } var fontBitmap = Mix.GetBitmap("fonts\\" + pngFont + ".png"); cellWidth = fontBitmap.Width / 32; cellHeight = fontBitmap.Height / 32; IsSquare = cellWidth == cellHeight; Program.Cols = IniFile.GetValue("misc", "screencols", Program.Cols); Program.Rows = IniFile.GetValue("misc", "screenrows", Program.Rows); if (full) { image = new Cell[Program.Cols, Program.Rows]; previousImage = new Cell[Program.Cols, Program.Rows]; } CachePNGFont(fontBitmap); fourThirtySeven = IniFile.GetValue("misc", "437", false); youtube = IniFile.GetValue("misc", "youtube", false); ClientSize = new Size(Program.Cols * cellWidth, Program.Rows * cellHeight); if (youtube) { //Find nearest YT size var eW = Program.Cols * cellWidth; var eH = Program.Rows * cellHeight; if (eW <= 854 || eH <= 480) { ClientSize = new Size(854, 480); } else if (eW <= 1280 || eH <= 720) { ClientSize = new Size(1280, 720); } else { ClientSize = new Size(1920, 1080); } var prime = Screen.FromRectangle(ClientRectangle).Bounds; if (ClientSize.Width == prime.Width && ClientSize.Height == prime.Height) { FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; Left = Top = 0; } else { FormBorderStyle = IniFile.GetValue("misc", "border", true) ? System.Windows.Forms.FormBorderStyle.FixedSingle : System.Windows.Forms.FormBorderStyle.None; } youtubeRect = new System.Drawing.Rectangle((ClientSize.Width / 2) - (eW / 2), (ClientSize.Height / 2) - (eH / 2), eW, eH); } else { FormBorderStyle = IniFile.GetValue("misc", "border", true) ? System.Windows.Forms.FormBorderStyle.FixedSingle : System.Windows.Forms.FormBorderStyle.None; } Show(); Refresh(); backBuffer = new Bitmap(Program.Cols * cellWidth, Program.Rows * cellHeight, PixelFormat.Format24bppRgb); scrollBuffer = new Bitmap(Program.Cols * cellWidth, Program.Rows * cellHeight, PixelFormat.Format24bppRgb); for (int row = 0; row < Program.Rows; row++) { for (int col = 0; col < Program.Cols; col++) { previousImage[col, row].Character = '\uFFFE'; } } }
public static void Handler() { var host = NoxicoGame.HostForm; if (Subscreens.FirstDraw) { UIManager.Initialize(); Subscreens.FirstDraw = false; NoxicoGame.ClearKeys(); Subscreens.Redraw = true; var backdrop = new Bitmap(Program.Cols, Program.Rows * 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var ccback = Mix.GetBitmap("travelback.png"); var ccpage = Mix.GetBitmap("ccpage.png"); var ccbars = Mix.GetBitmap("ccbars.png"); var pageTop = Program.Rows - (ccpage.Height / 2); using (var gfx = Graphics.FromImage(backdrop)) { gfx.Clear(Color.Black); gfx.DrawImage(ccback, 0, 0, Program.Cols, Program.Rows * 2); gfx.DrawImage(ccpage, 0, pageTop, ccpage.Width, ccpage.Height); var barsSrc = new System.Drawing.Rectangle(0, 3, ccbars.Width, 7); var barsDst = new System.Drawing.Rectangle(0, 0, Program.Cols, 7); gfx.DrawImage(ccbars, barsDst, barsSrc, GraphicsUnit.Pixel); barsSrc = new System.Drawing.Rectangle(0, 0, ccbars.Width, 5); barsDst = new System.Drawing.Rectangle(0, (Program.Rows * 2) - 5, Program.Cols, 5); gfx.DrawImage(ccbars, barsDst, barsSrc, GraphicsUnit.Pixel); } var list = new UIList() { Left = 4, Top = (pageTop / 2) + 4, Width = 34, Height = (ccpage.Height / 2) - 6, Background = Color.White, Foreground = Color.Black, }; UIManager.Elements.Add(new UIPNGBackground(backdrop)); UIManager.Elements.Add(new UILabel(i18n.GetString("travel_header")) { Left = 1, Top = 0, Foreground = Color.Silver }); UIManager.Elements.Add(new UILabel(i18n.GetString("travel_footer")) { Left = 1, Top = Program.Rows - 1, Foreground = Color.Silver }); UIManager.Elements.Add(new UILabel(i18n.GetString("travel_current") + "\n \x07<cCyan> " + (host.Noxico.CurrentBoard.Name ?? "Somewhere")) { Left = 44, Top = (pageTop / 2) + 4, Width = Program.Cols - 46, Foreground = Color.Teal }); UIManager.Elements.Add(list); var targets = new List <int>(); foreach (var target in NoxicoGame.TravelTargets) { targets.Add(target.Key); } targets.Sort(); list.Items.AddRange(targets.Select(x => NoxicoGame.TravelTargets[x])); list.Index = 0; //fixes crash when pressing Enter right away list.Enter = (s, e) => { var newBoard = NoxicoGame.TravelTargets.First(tn => tn.Value == list.Text).Key; if (host.Noxico.CurrentBoard.BoardNum == newBoard) { return; } NoxicoGame.Mode = UserMode.Walkabout; Subscreens.FirstDraw = true; NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddDays(1); while (Toolkit.IsNight()) { NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddHours(Random.Next(1, 3)); } NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddMinutes(Random.Next(10, 50)); host.Noxico.Player.OpenBoard(newBoard); var hereNow = host.Noxico.Player.ParentBoard; if (hereNow.BoardType == BoardType.Dungeon) { //find the exit and place the player there //TODO: something similar for towns var dngExit = hereNow.Warps.FirstOrDefault(w => w.TargetBoard == -2); if (dngExit != null) { host.Noxico.Player.XPosition = dngExit.XPosition; host.Noxico.Player.YPosition = dngExit.YPosition; } } else { host.Noxico.Player.Reposition(); } }; if (host.Noxico.CurrentBoard.Name != null) { var thisBoard = NoxicoGame.TravelTargets.FirstOrDefault(tn => host.Noxico.CurrentBoard.Name.StartsWith(tn.Value)); if (thisBoard.Value != null) { list.Index = list.Items.FindIndex(i => thisBoard.Value.StartsWith(i)); } } } if (Subscreens.Redraw) { Subscreens.Redraw = false; UIManager.Draw(); } if (NoxicoGame.IsKeyDown(KeyBinding.Back) || Vista.Triggers == XInputButtons.B) { NoxicoGame.ClearKeys(); NoxicoGame.Immediate = true; host.Noxico.CurrentBoard.Redraw(); host.Noxico.CurrentBoard.Draw(true); host.Noxico.CurrentBoard.AimCamera(); NoxicoGame.Mode = UserMode.Walkabout; Subscreens.FirstDraw = true; } else { UIManager.CheckKeys(); } }
public void MergeBitmap(string fileName, string tiledefs) { var bitmap = Mix.GetBitmap(fileName); var tileset = new Token(); tileset.AddSet(Mix.GetTokenTree(tiledefs, true)); var width = Width; var height = Height; if (width > bitmap.Width) { width = bitmap.Width; } if (height > bitmap.Height) { height = bitmap.Height; } for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var color = bitmap.GetPixel(x, y); if (color.Name == "ff000000" || color.A == 0) { continue; } var key = color.Name.Substring(2).ToUpperInvariant(); if (!tileset.HasToken(key)) { continue; } var tile = tileset.GetToken(key); //Keep the original tile, but drain it. if (tile.Text == "drain") { this.Tilemap[x, y].Fluid = Fluids.Dry; continue; } this.Tilemap[x, y].Index = TileDefinition.Find(tile.Text).Index; if (tile.Text.StartsWith("doorway")) { var door = new Door() { XPosition = x, YPosition = y, ForegroundColor = this.Tilemap[x, y].Definition.Background, BackgroundColor = this.Tilemap[x, y].Definition.Background.Darken(), ID = "mergeBitmap_Door" + x + "_" + y, ParentBoard = this, Closed = tile.Text.EndsWith("Closed"), Glyph = '+' }; this.Entities.Add(door); } if (tile.HasToken("clutter")) { var nc = new Clutter() { XPosition = x, YPosition = y, ParentBoard = this }; this.Entities.Add(nc); var properties = tile.GetToken("clutter"); foreach (var property in properties.Tokens) { switch (property.Name) { case "id": nc.ID = property.Text; break; case "name": nc.Name = property.Text; break; case "desc": nc.Description = property.Text; break; case "glyph": nc.Glyph = (int)property.Value; break; case "fg": if (property.Text.StartsWith('#')) { nc.ForegroundColor = Color.FromCSS(property.Text); } else { nc.ForegroundColor = Color.FromName(property.Text); } break; case "bg": if (property.Text.StartsWith('#')) { nc.BackgroundColor = Color.FromCSS(property.Text); } else { nc.BackgroundColor = Color.FromName(property.Text); } break; case "block": nc.Blocking = true; break; case "burns": nc.CanBurn = true; break; } } } if (tile.HasToken("unique")) { var unique = tile.GetToken("unique"); var newChar = new BoardChar(Character.GetUnique(unique.Text)) { XPosition = x, YPosition = y, ParentBoard = this }; this.Entities.Add(newChar); newChar.AssignScripts(unique.Text); newChar.ReassignScripts(); } if (!tile.HasToken("fluid")) { this.Tilemap[x, y].Fluid = Fluids.Dry; } else { this.Tilemap[x, y].Fluid = (Fluids)Enum.Parse(typeof(Fluids), tile.GetToken("fluid").Text, true); } } } this.ResolveVariableWalls(); }
public static Board CreateDungeon(bool forTravel, string name) { var host = NoxicoGame.HostForm; var nox = host.Noxico; new UIPNGBackground(Mix.GetBitmap("makecave.png")).Draw(); host.Write("Generating dungeon. Please wait.", Color.Silver, Color.Transparent, 1, 2); host.Draw(); var dunGen = new StoneDungeonGenerator(); var caveGen = new CaveGenerator(); Func <Board, Warp> findWarpSpot = (b) => { var eX = 0; var eY = 0; var attempts = 0; var minSides = 1; while (true) { attempts++; if (attempts == 10) { minSides = 0; } eX = Random.Next(1, b.Width - 1); eY = Random.Next(1, b.Height - 1); //2013-03-07: prevent placing warps on same tile as clutter //<Ragath> Kawa, this is bad //<Ragath> that should be a .Any() call //if (b.Entities.FirstOrDefault(e => e.XPosition == eX && e.YPosition == eY) != null) if (b.Entities.Any(e => e.XPosition == eX && e.YPosition == eY)) { Program.WriteLine("Tried to place a warp below an entity -- rerolling..."); continue; } var sides = 0; if (b.IsSolid(eY - 1, eX)) { sides++; } if (b.IsSolid(eY + 1, eX)) { sides++; } if (b.IsSolid(eY, eX - 1)) { sides++; } if (b.IsSolid(eY, eX + 1)) { sides++; } if (sides < 3 && sides >= minSides) { break; } } return(new Warp() { XPosition = eX, YPosition = eY }); }; Warp originalExit = null; BiomeData.LoadBiomes(); var biomeData = BiomeData.Biomes[DungeonGeneratorBiome]; /* Step 1 - Randomize jagged array, make boards for each entry. * ------------------------------------------------------------ * ("goal" board is boss/treasure room, picked at random from bottom floor set.) * [EXIT] [ 01 ] [ 02 ] * [ 03 ] [ 04 ] * [ 05 ] [ 06 ] [ 07 ] [ 08 ] * [ 09 ] [ 10 ] [ 11 ] * [GOAL] [ 13 ] */ var levels = new List <List <Board> >(); var depth = Random.Next(3, 6); var boardWidths = new[] { 80, 80, 80, 40, 160, 120 }; var boardHeights = new[] { 50, 50, 50, 25, 100, 75 }; for (var i = 0; i < depth; i++) { levels.Add(new List <Board>()); var length = Random.Next(2, 5); for (var j = 0; j < length; j++) { var board = new Board(boardWidths.PickOne(), boardHeights.PickOne()); board.AllowTravel = false; board.Clear(DungeonGeneratorBiome); board.BoardNum = nox.Boards.Count; board.Coordinate = nox.Player.ParentBoard.Coordinate; if (i > 0) { board.AddToken("dark"); } nox.Boards.Add(board); levels[i].Add(board); } } //Decide which boards are the exit and goal var entranceBoard = levels[0].PickOne(); var goalBoard = levels[levels.Count - 1].PickOne(); //Generate content for each board for (var i = 0; i < levels.Count; i++) { for (var j = 0; j < levels[i].Count; j++) { var board = levels[i][j]; if (Random.NextDouble() > 0.7 || board == entranceBoard) { caveGen.Board = board; caveGen.Create(biomeData); caveGen.ToTilemap(ref board.Tilemap); } else { dunGen.Board = board; dunGen.Create(biomeData); dunGen.ToTilemap(ref board.Tilemap); } board.Name = string.Format("Level {0}-{1}", i + 1, (char)('A' + j)); if (!name.IsBlank()) { board.Name = string.Format("{0}, level {1}-{2}", name, i + 1, (char)('A' + j)); } board.ID = string.Format("Dng_{0}_{1}{2}", DungeonGeneratorEntranceBoardNum, i + 1, (char)('A' + j)); board.BoardType = BoardType.Dungeon; board.Music = "set://Dungeon"; var encounters = board.GetToken("encounters"); foreach (var e in biomeData.Encounters) { encounters.AddToken(e); } encounters.Value = biomeData.MaxEncounters; encounters.GetToken("stock").Value = encounters.Value * Random.Next(3, 5); board.RespawnEncounters(); //If this is the entrance board, add a warp back to the Overworld. if (board == entranceBoard) { var exit = findWarpSpot(board); originalExit = exit; exit.ID = "Dng_" + DungeonGeneratorEntranceBoardNum + "_Exit"; board.Warps.Add(exit); board.SetTile(exit.YPosition, exit.XPosition, "dungeonExit"); //board.SetTile(exit.YPosition, exit.XPosition, '<', Color.Silver, Color.Black); } } } /* Step 2 - Randomly add up/down links * ----------------------------------- * (imagine for the moment that each board can have more than one exit and that this goes for both directions.) * [EXIT] [ 01 ] [ 02 ] * | * [ 03 ] [ 04 ] * | * [ 05 ] [ 06 ] [ 07 ] [ 08 ] * | | * [ 09 ] [ 10 ] [ 11 ] * | * [GOAL] [ 13 ] */ var connected = new List <Board>(); for (var i = 0; i < levels.Count; i++) { var j = Random.Next(0, levels[i].Count); //while (connected.Contains(levels[i][j])) // j = Randomizer.Next(0, levels[i].Count); var up = false; var destLevel = i + 1; if (destLevel == levels.Count) { up = true; destLevel = i - 1; } var dest = Random.Next(0, levels[destLevel].Count); var boardHere = levels[i][j]; var boardThere = levels[destLevel][dest]; var here = findWarpSpot(boardHere); var there = findWarpSpot(boardThere); boardHere.Warps.Add(here); boardThere.Warps.Add(there); here.ID = boardHere.ID + boardHere.Warps.Count; there.ID = boardThere.ID + boardThere.Warps.Count; here.TargetBoard = boardThere.BoardNum; there.TargetBoard = boardHere.BoardNum; here.TargetWarpID = there.ID; there.TargetWarpID = here.ID; boardHere.SetTile(here.YPosition, here.XPosition, up ? "dungeonUpstairs" : "dungeonDownstairs"); //boardHere.SetTile(here.YPosition, here.XPosition, up ? '<' : '>', Color.Gray, Color.Black); boardThere.SetTile(there.YPosition, there.XPosition, up ? "dungeonDownstairs" : "dungeonUpstairs"); //boardThere.SetTile(there.YPosition, there.XPosition, !up ? '<' : '>', Color.Gray, Color.Black); Program.WriteLine("Connected {0} || {1}.", boardHere.ID, boardThere.ID); connected.Add(boardHere); connected.Add(boardThere); } /* Step 3 - Connect the Unconnected * -------------------------------- * [EXIT]=[ 01 ]=[ 02 ] * | * [ 03 ]=[ 04 ] * | * [ 05 ]=[ 06 ] [ 07 ]=[ 08 ] * | | * [ 09 ]=[ 10 ]=[ 11 ] * | * [GOAL]=[ 13 ] */ for (var i = 0; i < levels.Count; i++) { for (var j = 0; j < levels[i].Count - 1; j++) { //Don't connect if this board AND the right-hand neighbor are already connected. //if (connected.Contains(levels[i][j]) && connected.Contains(levels[i][j + 1])) // continue; var boardHere = levels[i][j]; var boardThere = levels[i][j + 1]; var here = findWarpSpot(boardHere); var there = findWarpSpot(boardThere); boardHere.Warps.Add(here); boardThere.Warps.Add(there); here.ID = boardHere.ID + boardHere.Warps.Count; there.ID = boardThere.ID + boardThere.Warps.Count; here.TargetBoard = boardThere.BoardNum; there.TargetBoard = boardHere.BoardNum; here.TargetWarpID = there.ID; there.TargetWarpID = here.ID; boardHere.SetTile(here.YPosition, here.XPosition, "dungeonSideexit"); //boardHere.SetTile(here.YPosition, here.XPosition, '\x2261', Color.Gray, Color.Black); boardThere.SetTile(there.YPosition, there.XPosition, "dungeonSideexit"); //boardThere.SetTile(there.YPosition, there.XPosition, '\x2261', Color.Gray, Color.Black); Program.WriteLine("Connected {0} -- {1}.", boardHere.ID, boardThere.ID); connected.Add(boardHere); connected.Add(boardThere); } } // Step 4 - place sick lewt in goalBoard var treasureX = 0; var treasureY = 0; while (true) { treasureX = Random.Next(1, goalBoard.Width - 1); treasureY = Random.Next(1, goalBoard.Height - 1); //2013-03-07: prevent treasure from spawning inside a wall if (goalBoard.IsSolid(treasureY, treasureX)) { continue; } //2013-03-07: prevent placing warps on same tile as clutter if (goalBoard.Entities.FirstOrDefault(e => e.XPosition == treasureX && e.YPosition == treasureY) != null) { Program.WriteLine("Tried to place cave treasure below an entity -- rerolling..."); continue; } var sides = 0; if (goalBoard.IsSolid(treasureY - 1, treasureX)) { sides++; } if (goalBoard.IsSolid(treasureY + 1, treasureX)) { sides++; } if (goalBoard.IsSolid(treasureY, treasureX - 1)) { sides++; } if (goalBoard.IsSolid(treasureY, treasureX + 1)) { sides++; } if (sides < 3 && sides > 1 && goalBoard.Warps.FirstOrDefault(w => w.XPosition == treasureX && w.YPosition == treasureY) == null) { break; } } var treasure = DungeonGenerator.GetRandomLoot("container", "dungeon_chest", new Dictionary <string, string>() { { "biome", BiomeData.Biomes[DungeonGenerator.DungeonGeneratorBiome].Name.ToLowerInvariant() }, }); var treasureChest = new Container(i18n.GetString("treasurechest"), treasure) { Glyph = 0x14A, XPosition = treasureX, YPosition = treasureY, ForegroundColor = Color.FromName("SaddleBrown"), BackgroundColor = Color.Black, ParentBoard = goalBoard, Blocking = false, }; goalBoard.Entities.Add(treasureChest); if (forTravel) { originalExit.TargetBoard = -2; //causes Travel menu to appear on use. return(entranceBoard); } var entrance = nox.CurrentBoard.Warps.Find(w => w.ID == DungeonGeneratorEntranceWarpID); entrance.TargetBoard = entranceBoard.BoardNum; //should be this one. entrance.TargetWarpID = originalExit.ID; originalExit.TargetBoard = nox.CurrentBoard.BoardNum; originalExit.TargetWarpID = entrance.ID; nox.CurrentBoard.EntitiesToRemove.Add(nox.Player); nox.CurrentBoard = entranceBoard; nox.Player.ParentBoard = entranceBoard; entranceBoard.Entities.Add(nox.Player); nox.Player.XPosition = originalExit.XPosition; nox.Player.YPosition = originalExit.YPosition; entranceBoard.UpdateLightmap(nox.Player, true); entranceBoard.Redraw(); entranceBoard.PlayMusic(); NoxicoGame.Immediate = true; NoxicoGame.Mode = UserMode.Walkabout; NoxicoGame.Me.SaveGame(); return(entranceBoard); }
public static void Engage(Character top, Character bottom, string name = "(start)") { if (sceneList == null) { sceneList = Mix.GetTokenTree("dialogue.tml", true); } SceneSystem.top = top; SceneSystem.bottom = bottom; SceneSystem.actors = new[] { top, bottom }; var dreaming = top.HasToken("dream"); if (name.Contains('\xE064')) { name = name.Remove(name.LastIndexOf('\xE064')); } var openings = sceneList.Where(x => x.Name == "scene" && x.GetToken("name").Text == name).ToList(); if (openings.Count == 0) { MessageBox.Notice(string.Format("Could not find a proper opening for scene name \"{0}\". Aborting.", name), true, "Uh-oh."); return; } var firstScene = openings.FirstOrDefault(i => SexManager.LimitsOkay(actors, i)); var scenes = new List <Token>() { firstScene }; if (firstScene.HasToken("random")) { var randomKey = firstScene.GetToken("random").Text; foreach (var s in openings.Where(i => i != firstScene && i.HasToken("random") && i.GetToken("random").Text == randomKey && SexManager.LimitsOkay(actors, i))) { scenes.Add(s); } } var scene = scenes.PickOne(); var message = i18n.Viewpoint(ExtractParagraphsAndScripts(scene), SceneSystem.top, SceneSystem.bottom); var actions = ExtractActions(scene); if (actions.Count == 1) { var target = actions.First().Key; actions.Clear(); actions.Add(target, "==>"); } if (bottom == NoxicoGame.Me.Player.Character && !letBottomChoose) { if (actions.Count == 0) { MessageBox.Notice(message, true, bottom.Name.ToString(true)); } else { var randomAction = actions.Keys.ToArray().PickOne(); actions.Clear(); actions.Add(randomAction, "==>"); MessageBox.List(message, actions, () => { Engage(SceneSystem.top, SceneSystem.bottom, (string)MessageBox.Answer); }, false, true, bottom.GetKnownName(true, true)); } } else { letBottomChoose = false; if (actions.Count == 0) { MessageBox.Notice(message, !dreaming, bottom.GetKnownName(true, true)); } else { MessageBox.List(message, actions, () => { Engage(SceneSystem.top, SceneSystem.bottom, (string)MessageBox.Answer); }, false, !dreaming, bottom.GetKnownName(true, true)); } } if (dreaming) { new UIPNGBackground(Mix.GetBitmap("dream.png")).Draw(); } else { NoxicoGame.Me.CurrentBoard.Redraw(); NoxicoGame.Me.CurrentBoard.Draw(); } }