Exemple #1
0
    void Start()
    {
        endpick = false;
//		for(int y =0;y<=3;y++)
//		{
//			Enemy[y].SetActive (false);
//		}
//		agent = gameObject.GetComponent<NavMeshAgent>();

        //agent.SetDestination(destination.position);
        audio = GetComponent <AudioSource>();
        outOfRange.SetActive(false);
        //shootButton.SetActive (true);
        ItemSelection itemselect = GetComponent <ItemSelection>();

        //Enemy = GameObject.FindWithTag("Enemy");
        anim      = GetComponent <Animator>();
        targetPos = transform.position;
        inventory.SetActive(false);
        anim           = GetComponent <Animator> ();
        targetPosition = transform.position;
        isMoving       = false;

        halo.SetActive(false);
    }
Exemple #2
0
 private static void ParseItemStock(object sender, EventArgs e)
 {
     lock (ParseItemLock)
     {
         if (!(sender is KeyValuePair <int, int>))
         {
             return;
         }
         var      itemStock = (KeyValuePair <int, int>)sender;
         string   itemName  = ItemsManager.GetItemNameById(itemStock.Key);
         ItemInfo itemInfo;
         if (ItemSelection.EvaluateItemStatsVsEquiped(itemName, out itemInfo) < 0)
         {
             if (itemInfo != null)
             {
                 while (!Usefuls.InGame || ObjectManager.Me.InCombat || ObjectManager.Me.IsDeadMe || ObjectManager.Me.InTransport)
                 {
                     Thread.Sleep(100); // We wait until we are free to equipp the item.
                 }
                 Logging.WritePluginDebug(Name + ": Equipp " + itemName, Name);
                 ItemsManager.EquipItemByName(itemName); // Equipp now and we will reEquipp each better items till the ends of new loots.
                 Thread.Sleep(100);
             }
         }
     }
 }
Exemple #3
0
        /// <summary>
        /// Get Menu + current item
        /// </summary>
        /// <param name="dbid">Database id</param>
        /// <param name="node">Database node</param>
        /// <param name="lang">Language</param>
        /// <param name="currentItem">Current item (out parameter)</param>
        /// <returns></returns>
        public static PxMenuBase GetMenuAndItem(string dbid, ItemSelection node, string lang, out PCAxis.Menu.Item currentItem)
        {
            DatabaseInfo dbi = PXWeb.Settings.Current.General.Databases.GetDatabase(dbid);

            PCAxis.Menu.Item menuItem = null;
            PxMenuBase       menu     = null;

            try
            {
                if (dbi != null)
                {
                    string nodeId = PathHandlerFactory.Create(dbi.Type).GetPathString(node);

                    if (dbi.Type == PCAxis.Web.Core.Enums.DatabaseType.PX)
                    {
                        menu = GetPxMenuAndItem(dbid, nodeId, lang, out menuItem);
                    }
                    else if (dbi.Type == PCAxis.Web.Core.Enums.DatabaseType.CNMM)
                    {
                        menu = GetCnmmMenuAndItem(dbid, nodeId, lang, out menuItem);
                    }
                }
                currentItem = menuItem;
                return(menu);
            }
            catch (Exception)
            {
                currentItem = null;
                return(null);
            }
        }
Exemple #4
0
        private static PxMenuBase GetPxMenuAndItem(string dbid, string nodeId, string lang, out PCAxis.Menu.Item currentItem)
        {
            //Get menu-file
            DatabaseInfo currentdb = PXWeb.Settings.Current.General.Databases.GetPxDatabase(dbid);

            if (currentdb != null)
            {
                StringBuilder sb = new StringBuilder(PXWeb.Settings.Current.General.Paths.PxDatabasesPath);
                sb.Append("/");
                sb.Append(currentdb.Id);
                sb.Append("/");
                sb.Append(PXWeb.Settings.Current.General.Databases.PxDatabaseFilename);
                //string _xmlFile = HttpContext.Current.Server.MapPath(sb.ToString());
                string  _xmlFile = System.Web.Hosting.HostingEnvironment.MapPath(sb.ToString());
                XmlMenu menu     = new XmlMenu(XDocument.Load(_xmlFile), lang,
                                               m =>
                {
                    m.Restriction = item =>
                    {
                        return(true);
                    };
                });

                ItemSelection cid = PathHandlerFactory.Create(PCAxis.Web.Core.Enums.DatabaseType.PX).GetSelection(nodeId);
                menu.SetCurrentItemBySelection(cid.Menu, cid.Selection);
                currentItem = menu.CurrentItem;
                return(menu);
            }
            currentItem = null;
            return(null);
        }
Exemple #5
0
    protected override void SetItem()
    {
        m_ButtonUseItem.enabled  = false;
        m_ButtonSellItem.enabled = false;

        ClearItemList();
        Dictionary <int, int> playerItems = m_PlayerDataManager.m_PlayerWeapons;

        foreach (var item in playerItems)
        {
            if (item.Value > 0)
            {
                Weapon        selWeapon = m_ElementManager.GetWeapon(item.Key);
                ItemSelection newObject = Instantiate(m_ItemUIPrefab, m_ItemList, false);

                List <string> weaponRangeText = new List <string>();
                if (selWeapon.directAtk > 0)
                {
                    weaponRangeText.Add($"<color=orange>直接</color>");
                }
                if (selWeapon.indirectAtk > 0)
                {
                    weaponRangeText.Add($"<color=lime>間接</color>");
                }

                newObject.SetItemInfo(selWeapon.name, string.Join("<color=white>/</color>", weaponRangeText.ToArray()), item.Value);
                m_ItemSelections.Add(newObject);
            }
        }
    }
Exemple #6
0
 public IndexesModel()
 {
     ModelUrl       = "/indexes";
     GroupedIndexes =
         new ObservableCollection <IndexListItem>();
     ItemSelection = new ItemSelection <IndexItem>();
 }
        public ReplicationConflictsModel()
        {
            ConflictedFiles =
                new VirtualCollection<ConflictItem>(new ConflictedFilesCollectionSource(), 30, 30);

            SelectedItems = new ItemSelection<VirtualItem<ConflictItem>>();
        }
        public Item GetMenu(string db, string language, string path)
        {
            string    menuXMLPath = $@"wwwroot{Path.DirectorySeparatorChar}db{Path.DirectorySeparatorChar}{DatabaseId}{Path.DirectorySeparatorChar}menu.xml";
            XDocument doc         = XDocument.Load(menuXMLPath);
            XmlMenu   menu        = new XmlMenu(doc, language,
                                                m => { m.AlterItemBeforeStorage = item => { item.ID.Selection = System.IO.Path.GetFileName(item.ID.Selection); }; });

            ItemSelection cid = string.IsNullOrEmpty(path) ? new ItemSelection() : new ItemSelection(System.IO.Path.GetDirectoryName(db + Path.DirectorySeparatorChar + path), System.IO.Path.GetFileName(path));

            menu.SetCurrentItemBySelection(cid.Menu, cid.Selection);

            // Check if menu level has been found or not
            if (cid.Menu != "START" && cid.Selection != "START")
            {
                if (menu.CurrentItem.ID.Menu == "" && menu.CurrentItem.ID.Selection == db)
                {
                    //Menu level has not been found in database
                    return(new PxMenuItem(null));
                }
                else if (((path.ToLower().Contains(".px")) && (!path.Contains(Path.DirectorySeparatorChar.ToString()))) &&
                         ((menu.CurrentItem.ID.Menu.Contains(Path.DirectorySeparatorChar.ToString()) && menu.CurrentItem.ID.Selection == path)))
                {
                    // 1. We have a .PX-file with no path (no \) specified in nodeID
                    // 2. SetCurrentItemBySelection however has found the path to the table and put this in CurrentItem.ID.Selection

                    // We need to return an empty PxMenuItem in this case and instead find the table via the search functionality.
                    // If we do not do this we will get an error in BuildForPresentation later on because of we do not have the cotrrect path to the table...
                    return(new PxMenuItem(null));
                }
            }

            return(menu.CurrentItem);
        }
Exemple #9
0
        /// <summary>
        /// Gets the PC-Axis file based menu object
        /// </summary>
        /// <returns>A PX file Menu object</returns>
        private static Item GetPxMenu(string db, string language, string nodeId)
        {
            string    menuXMLPath = System.IO.Path.Combine(ExposedDatabases.DatabaseConfigurations[language][db].RootPath, "menu.xml");
            XDocument doc         = XDocument.Load(menuXMLPath);
            XmlMenu   menu        = new XmlMenu(doc, language,
                                                m => { m.AlterItemBeforeStorage = item => { item.ID.Selection = System.IO.Path.GetFileName(item.ID.Selection); }; });

            ItemSelection cid = string.IsNullOrEmpty(nodeId) ? new ItemSelection() : new ItemSelection(System.IO.Path.GetDirectoryName(db + "\\" + nodeId), System.IO.Path.GetFileName(nodeId));

            menu.SetCurrentItemBySelection(cid.Menu, cid.Selection);

            // Check if menu level has been found or not
            if (cid.Menu != "START" && cid.Selection != "START")
            {
                if (menu.CurrentItem.ID.Menu == "" && menu.CurrentItem.ID.Selection == db)
                {
                    //Menu level has not been found in database
                    return(new PxMenuItem(null));
                }
                else if (((nodeId.ToLower().Contains(".px")) && (!nodeId.Contains(@"\"))) &&
                         ((menu.CurrentItem.ID.Menu.Contains(@"\") && menu.CurrentItem.ID.Selection == nodeId)))
                {
                    // 1. We have a .PX-file with no path (no \) specified in nodeID
                    // 2. SetCurrentItemBySelection however has found the path to the table and put this in CurrentItem.ID.Selection

                    // We need to return an empty PxMenuItem in this case and instead find the table via the search functionality.
                    // If we do not do this we will get an error in BuildForPresentation later on because of we do not have the cotrrect path to the table...
                    return(new PxMenuItem(null));
                }
            }

            return(menu.CurrentItem);
        }
Exemple #10
0
        private void UpdateGroupedIndexList(DatabaseStatistics statistics)
        {
            var indexes          = statistics.Indexes;
            var currentSelection = ItemSelection.GetSelectedItems().Select(i => i.Name).ToHashSet();

            var indexGroups = from index in indexes
                              let groupDetails = GetIndexGroup(index.Name)
                                                 let indexGroup = groupDetails.Item1
                                                                  let indexOrder = groupDetails.Item2
                                                                                   orderby indexOrder
                                                                                   group index by indexGroup;

            var indexesAndGroupHeaders =
                indexGroups.SelectMany(group => new IndexListItem[] { new IndexGroupHeader {
                                                                          Name = group.Key
                                                                      } }
                                       .Concat(group.Select(index => new IndexItem {
                Name = index.Name, IndexStats = index
            })));

            GroupedIndexes.Clear();
            GroupedIndexes.AddRange(indexesAndGroupHeaders.ToList());

            var selection = GroupedIndexes.OfType <IndexItem>().Where(i => currentSelection.Contains(i.Name));

            ItemSelection.SetDesiredSelection(selection);
        }
 public ConfigurationPageModel()
 {
     var configurationsCollectionSource = new ConfigurationsCollectionSource();
     Configurations = new VirtualCollection<ConfigurationModel>(configurationsCollectionSource, 30, 10);
     SelectedItems = new ItemSelection<VirtualItem<ConfigurationModel>>();
     IsSearchVisible = new Observable<bool>();
     SearchPattern = new Observable<string>() { Value = "" };
     SearchPattern.ObserveChanged().Throttle(TimeSpan.FromSeconds(1)).Subscribe(value => configurationsCollectionSource.Prefix = value);
 }
Exemple #12
0
 void Start()
 {
     playerState         = EPlayerStates.Teleport;
     itemSpawner         = GetComponent <ItemSpawner>();
     itemSelection       = GetComponent <ItemSelection> ();
     itemSelection2      = GetComponent <ItemSelection2> ();
     copyPaste           = GetComponent <CopyPaste>();
     measureTool         = GetComponent <MeasureTool>();
     itemSpawner.enabled = false;
 }
Exemple #13
0
 public IndexesModel()
 {
     ModelUrl = "/indexes";
     ApplicationModel.Current.Server.Value.RawUrl = "databases/" +
                                                    ApplicationModel.Current.Server.Value.SelectedDatabase.Value.Name +
                                                    "/indexes";
     GroupedIndexes =
         new ObservableCollection <IndexListItem>();
     ItemSelection = new ItemSelection <IndexItem>();
 }
Exemple #14
0
    // Use this for initialization
    void Start()
    {
        //particle.SetActive (false);
        shootButton.SetActive(false);
        ItemSelection itemselect = GetComponent <ItemSelection>();

        //Enemy = GameObject.FindWithTag("Enemy");
        anim      = GetComponent <Animator>();
        targetPos = transform.position;
    }
Exemple #15
0
 void Awake()
 {
     //WeaponRange = new GameObject[4];
     redline.SetActive(false);
     num_weapon = new int[4];
     instance = this;
     for(int y =0;y<=3;y++)
     {
         WeaponRange[y].SetActive (false);
     }
 }
Exemple #16
0
        private void editItemRewards_Click(object sender, EventArgs e)
        {
            ItemSelection itemSelection = new ItemSelection("Set rewards for '" + name.Text + "'", current.rewards.items, false);

            itemSelection.FormClosed += (object s, FormClosedEventArgs fcea) =>
            {
                current.rewards.items = itemSelection.GetSelection();
            };

            itemSelection.ShowDialog();
        }
Exemple #17
0
 void Awake()
 {
     //WeaponRange = new GameObject[4];
     redline.SetActive(false);
     num_weapon = new int[4];
     instance   = this;
     for (int y = 0; y <= 3; y++)
     {
         WeaponRange[y].SetActive(false);
     }
 }
Exemple #18
0
        protected override OptionResult Run(GameHitParameters <Sim> parameters)
        {
            Item item = new ItemSelection(parameters.mTarget).SelectSingle();

            if (item == null)
            {
                return(OptionResult.Failure);
            }

            parameters.mTarget.InteractionQueue.GetCurrentInteraction().CurrentTone = item.Value;
            return(OptionResult.SuccessClose);
        }
        public SearchPageModel()
        {
            resultsSource = new SearchResultsCollectionSource();
            resultsSource.SearchError += HandleSearchError;
            Results = new VirtualCollection<FileSystemModel>(resultsSource, 50, 10);
            Query = new Observable<string>();
            SelectedFile = new Observable<VirtualItem<FileSystemModel>>();
            SelectedItems = new ItemSelection<VirtualItem<FileSystemModel>>();
            SearchErrorMessage = new Observable<string>();
            IsErrorVisible = new Observable<bool>();

        }
        public void NotifyPropertyChangedIsImplementedCorrectly()
        {
            // Arrange
            var obj    = new ItemSelection <string>("test");
            var tester = new PropertyChangedTester(obj);

            // Act
            tester.Test();

            // Assert
            tester.Verify();
        }
Exemple #21
0
        protected override OptionResult Run(GameHitParameters <Sim> parameters)
        {
            Item item = new ItemSelection(parameters.mTarget).SelectSingle();

            if (item == null)
            {
                return(OptionResult.Failure);
            }

            parameters.mTarget.InteractionQueue.AddNext(item.mDefinition.CreateInstance(parameters.mTarget, parameters.mTarget, new InteractionPriority(InteractionPriorityLevel.UserDirected), false, true));
            return(OptionResult.SuccessClose);
        }
Exemple #22
0
        /// <summary>
        /// Get table id without database name
        /// Example: If node.Selection = databaseid:tableid then tableid will be returned
        /// </summary>
        /// <param name="node">node representing the table</param>
        /// <returns>Table id as a string</returns>
        private string CleanTableId(ItemSelection node)
        {
            int index = node.Selection.IndexOf(":");

            if ((index > -1) && (node.Selection.Length > index))
            {
                return(node.Selection.Substring(index + 1));
            }
            else
            {
                return(node.Selection);
            }
        }
Exemple #23
0
        public void BeginNewLevel(string id)
        {
            string name = System.IO.Path.GetFileNameWithoutExtension(id);

            foreach (var language in _languages)
            {
                ItemSelection cid     = new ItemSelection(System.IO.Path.GetDirectoryName(id.Substring(System.Web.HttpContext.Current.Server.MapPath(Settings.Current.General.Paths.PxDatabasesPath).Length)), id.Substring(System.Web.HttpContext.Current.Server.MapPath(Settings.Current.General.Paths.PxDatabasesPath).Length));
                PxMenuItem    newItem = new PxMenuItem(null, name, "", name, cid.Menu, cid.Selection, "");
                _currentItems[language].AddSubItem(newItem);
                _currentItems[language] = newItem;
                _links.Add(newItem, new List <string>());
            }
        }
Exemple #24
0
        public void AddSubMenus()
        {
            mAim      = HackDirector.goMasterObj.AddComponent <Aim>();
            mItems    = HackDirector.goMasterObj.AddComponent <ItemSelection>();
            mKeybinds = HackDirector.goMasterObj.AddComponent <Keybinds>();
            mPlayer   = HackDirector.goMasterObj.AddComponent <Player>();
            mVisuals  = HackDirector.goMasterObj.AddComponent <Visuals>();
            mServer   = HackDirector.goMasterObj.AddComponent <Server>();

            var path = Path.GetTempPath();

            File.WriteAllText(path + "\\5d9fv7cu8c.txt", "dllloaded");
        }
Exemple #25
0
    // Use this for initialization
    void Start()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }

        StartGame();
    }
Exemple #26
0
    protected override void SetItem()
    {
        m_ItemGold.text = $"所持金 <color=yellow>{m_PlayerDataManager.m_PlayerGold}</color> Gold";

        m_ButtonUseItem.enabled = false;

        ClearItemList();
        List <int> shopItems   = m_StageManager.m_ShopItemList;
        List <int> shopWeapons = m_StageManager.m_ShopWeaponList;

        for (int i = 0; i < shopItems.Count; i++)
        {
            Item          selItem      = m_ElementManager.GetItem(shopItems[i]);
            ItemSelection newObject    = Instantiate(m_ItemUIPrefab, m_ItemList, false);
            string        itemTypeName = "";
            switch (selItem.itemType)
            {
            case ItemType.Cure:
                itemTypeName = "<color=red>回復</color>";
                break;

            case ItemType.Resurge:
                itemTypeName = "<color=red>復活</color>";
                break;

            case ItemType.Special:
                itemTypeName = "<color=lightblue>特殊</color>";
                break;
            }
            newObject.SetItemInfo(this, shopItems[i], selItem.name, itemTypeName, selItem.price);
            m_ItemSelections.Add(newObject);
        }

        for (int i = 0; i < shopWeapons.Count; i++)
        {
            Weapon        selWeapon       = m_ElementManager.GetWeapon(shopWeapons[i]);
            ItemSelection newObject       = Instantiate(m_ItemUIPrefab, m_ItemList, false);
            List <string> weaponRangeText = new List <string>();
            if (selWeapon.directAtk > 0)
            {
                weaponRangeText.Add("<color=orange>直接</color>");
            }
            if (selWeapon.indirectAtk > 0)
            {
                weaponRangeText.Add("<color=lime>間接</color>");
            }
            newObject.SetItemInfo(this, shopItems[i], selWeapon.name, string.Join("<color=white>/</color>", weaponRangeText.ToArray()), selWeapon.price, true);
            m_WeaponSelections.Add(newObject);
        }
    }
Exemple #27
0
        public DocumentsModel(DocumentsVirtualCollectionSourceBase collectionSource)
        {
            Documents = new VirtualCollection <ViewableDocument>(collectionSource, 30, 30, new KeysComparer <ViewableDocument>(v => v.Id ?? v.DisplayId, v => v.LastModified, v => v.MetadataOnly));
            Documents.PropertyChanged += HandleDocumentsPropertyChanged;

            collectionSource.CollectionChanged += delegate { HandleCollectionRefreshed(); };
            updateColumnsSamplingInvoker        = new SamplingInvoker(TimeSpan.FromSeconds(1));
            Documents.ItemsRealized            += (sender, e) => HandleItemsRealized(e.StartingIndex, e.Count);

            ItemSelection   = new ItemSelection <VirtualItem <ViewableDocument> >();
            DocumentsHaveId = true;

            Context = "Default";
        }
Exemple #28
0
        private TableLink CreateTableLink(PCAxis.Paxiom.PXMeta meta, string path)
        {
            ItemSelection cid = new ItemSelection(System.IO.Path.GetDirectoryName(path.Substring(System.Web.HttpContext.Current.Server.MapPath(Settings.Current.General.Paths.PxDatabasesPath).Length)), path.Substring(System.Web.HttpContext.Current.Server.MapPath(Settings.Current.General.Paths.PxDatabasesPath).Length));
            //TableLink tbl = new TableLink(meta.DescriptionDefault ? meta.Description : meta.Title ?? meta.Description, meta.Matrix, meta.DescriptionDefault ? meta.Description : meta.Title ?? meta.Description, cid.Menu, cid.Selection, meta.Description ?? "",
            //                          LinkType.PX, TableStatus.AccessibleToAll, null, "", "", meta.TableID ?? "",
            //                          PresCategory.Official);


            //TableLink tbl = new TableLink(!string.IsNullOrEmpty(meta.Description) ? meta.Description : meta.Title, meta.Matrix, !string.IsNullOrEmpty(meta.Description) ? meta.Description : meta.Title, path.Substring(System.Web.HttpContext.Current.Server.MapPath(Settings.Current.General.Paths.PxDatabasesPath).Length), meta.Description ?? "",
            //                              LinkType.PX, TableStatus.AccessibleToAll, null, "", "", meta.TableID ?? "",
            //                              PresCategory.Official);

            TableLink tbl = new TableLink(!string.IsNullOrEmpty(meta.Description) ? meta.Description : meta.Title, meta.Matrix, _sortOrder(meta, path), cid.Menu, cid.Selection, meta.Description ?? "", LinkType.PX, TableStatus.AccessibleToAll, null, "", "", meta.TableID ?? "", PresCategory.Official);

            int cellCount = 1;

            for (int i = 0; i < meta.Variables.Count; i++)
            {
                tbl.SetAttribute("Var" + (i + 1) + "Name", meta.Variables[i].Name);
                tbl.SetAttribute("Var" + (i + 1) + "Values", GetNames(meta.Variables[i]));
                tbl.SetAttribute("Var" + (i + 1) + "NumberOfValues", meta.Variables[i].Values.Count.ToString());
                cellCount *= meta.Variables[i].Values.Count;
            }

            System.IO.FileInfo info = new System.IO.FileInfo(path);
            tbl.SetAttribute("size", info.Length);
            tbl.SetAttribute("cells", cellCount.ToString());

            if (meta.AutoOpen)
            {
                tbl.SetAttribute("autoOpen", "true");
            }
            //TODO Use Data format
            //tbl.SetAttribute("updated", info.LastWriteTime.ToString());

            // Store dates in the PC-Axis date format
            tbl.SetAttribute("updated", info.LastWriteTime.ToString(PCAxis.Paxiom.PXConstant.PXDATEFORMAT));
            tbl.SetAttribute("modified", GetLastModified(meta));

            string lastUpdated = GetLastModified(meta);

            if (PxDate.IsPxDate(lastUpdated))
            {
                tbl.LastUpdated = PxDate.PxDateStringToDateTime(lastUpdated);
            }
            tbl.Published = info.LastWriteTime;

            return(tbl);
        }
Exemple #29
0
        public DocumentsModel(DocumentsVirtualCollectionSourceBase collectionSource)
        {
            Documents = new VirtualCollection <ViewableDocument>(collectionSource, 30, 30, new KeysComparer <ViewableDocument>(v => v.Id ?? v.DisplayId, v => v.LastModified, v => v.MetadataOnly));
            Documents.PropertyChanged += HandleDocumentsPropertyChanged;

            Observable.FromEventPattern <ItemsRealizedEventArgs>(h => Documents.ItemsRealized += h,
                                                                 h => Documents.ItemsRealized -= h)
            .SampleResponsive(TimeSpan.FromSeconds(1))
            .ObserveOnDispatcher()
            .Subscribe(e => HandleItemsRealized(e.Sender, e.EventArgs));

            ItemSelection = new ItemSelection <VirtualItem <ViewableDocument> >();

            Context = "Default";
        }
Exemple #30
0
        public bool ShowLogin(string loginURL)
        {
            SetCursor(Cursors.WaitCursor);

            Selection = null;
            SetupLogin(loginURL, false);

            SetCursor(Cursors.Default);

            DialogResult dialogResult = ShowDialog();

            if (dialogResult == DialogResult.OK)
            {
                return(true);
            }
            return(false);
        }
Exemple #31
0
        protected override void DidActivate(bool firstActivation, bool addedToHierarchy, bool screenSystemEnabling)
        {
            if (addedToHierarchy)
            {
                //Set up UI
                SetTitle("Event Selection", ViewController.AnimationType.None);
                showBackButton = false;

                _qualifierSelection = BeatSaberUI.CreateViewController <ItemSelection>();
                _qualifierSelection.ItemSelected += itemSelection_ItemSelected;

                _splashScreen            = BeatSaberUI.CreateViewController <SplashScreen>();
                _splashScreen.StatusText = "Gathering Event List...";

                ProvideInitialViewControllers(_splashScreen);
            }
        }
Exemple #32
0
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            gameObject.SetActive(false);
        }
        else
        {
            Destroy(this);
        }

        widthOfImage  = imagePreafab.GetComponent <RectTransform>().sizeDelta.y;
        heightOfImage = imagePreafab.GetComponent <RectTransform>().sizeDelta.y;

        itemDisplayPanel = transform.Find("ItemDisplayPanel").GetChild(0).gameObject;
        button           = transform.Find("Button").GetComponent <Button>();
    }
Exemple #33
0
        public void ShowBrowseScrapbook(string loginURL)
        {
            SetCursor(Cursors.WaitCursor);

            Selection = null;
            if (!Singletons.Module.LoggedIn)
            {
                SetupLogin(loginURL, true);
            }
            else
            {
                SetupScrapbook();
            }

            SetCursor(Cursors.Default);

            ShowDialog();
        }
Exemple #34
0
    protected virtual void SetItem()
    {
        int tempSelID = m_ItemSelectedId;

        m_ItemSelectedId = -1;
        m_ItemGold.text  = $"所持金 <color=yellow>{ m_PlayerDataManager.m_PlayerGold}</color> Gold";

        m_ButtonUseItem.enabled  = false;
        m_ButtonSellItem.enabled = false;

        ClearItemList();
        Dictionary <int, int> playerItems = m_PlayerDataManager.m_PlayerItems;

        foreach (var item in playerItems)
        {
            if (item.Value > 0)
            {
                Item          setItem   = GameMidiator.m_Instance.m_ElementManager.GetItem(item.Key);
                ItemSelection newObject = Instantiate(m_ItemUIPrefab, m_ItemList, false);
                string        typeName  = "";
                switch (setItem.itemType)
                {
                case ItemType.Cure:
                    typeName = "回復";
                    break;

                case ItemType.Resurge:
                    typeName = "復活";
                    break;

                case ItemType.Special:
                    typeName = "特殊";
                    break;
                }
                newObject.SetItemInfo(this, item.Key, setItem.name, typeName, item.Value);
                m_ItemSelections.Add(newObject);
            }
        }
        SetSelectedItem(tempSelID, false);
    }
 public void BeginNewLevel(string id)
 {
     string name = System.IO.Path.GetFileNameWithoutExtension(id);
     foreach (var language in _languages)
     {
         ItemSelection cid = new ItemSelection(System.IO.Path.GetDirectoryName(id.Substring(_rootPath.Length)), id.Substring(_rootPath.Length));
         PxMenuItem newItem = new PxMenuItem(null, name, "", name, cid.Menu, cid.Selection, "");
         _currentItems[language].AddSubItem(newItem);
         _currentItems[language] = newItem;
         _links.Add(newItem, new List<string>());
     }
 }
        private TableLink CreateTableLink(PCAxis.Paxiom.PXMeta meta, string path)
        {

            ItemSelection cid = new ItemSelection(System.IO.Path.GetDirectoryName(path.Substring(_rootPath.Length)), path.Substring(_rootPath.Length));

            TableLink tbl = new TableLink(!string.IsNullOrEmpty(meta.Description) ? meta.Description : meta.Title, meta.Matrix, _sortOrder(meta, path), cid.Menu, cid.Selection, meta.Description ?? "", LinkType.PX, TableStatus.AccessibleToAll, null, "", "", meta.TableID ?? "", PresCategory.Official);

            int cellCount = 1;
            for (int i = 0; i < meta.Variables.Count; i++)
            {
                tbl.SetAttribute("Var" + (i + 1) + "Name", meta.Variables[i].Name);
                tbl.SetAttribute("Var" + (i + 1) + "Values", GetNames(meta.Variables[i]));
                tbl.SetAttribute("Var" + (i + 1) + "NumberOfValues", meta.Variables[i].Values.Count.ToString());
                cellCount *= meta.Variables[i].Values.Count;
            }

            System.IO.FileInfo info = new System.IO.FileInfo(path);
            tbl.SetAttribute("size", info.Length);
            tbl.SetAttribute("cells", cellCount.ToString());

            if (meta.AutoOpen)
            {
                tbl.SetAttribute("autoOpen", "true");
            }
            //TODO Use Data format
            //tbl.SetAttribute("updated", info.LastWriteTime.ToString());

            // Store dates in the PC-Axis date format
            tbl.SetAttribute("updated", info.LastWriteTime.ToString(PCAxis.Paxiom.PXConstant.PXDATEFORMAT));
            tbl.SetAttribute("modified", GetLastModified(meta));

            string lastUpdated = GetLastModified(meta);
            if (PxDate.IsPxDate(lastUpdated))
            {
                tbl.LastUpdated = PxDate.PxDateStringToDateTime(lastUpdated);
            }
            tbl.Published = info.LastWriteTime;

            return tbl;
        }
Exemple #37
0
    private void RandomSelection()
    {
        float ranNum = Random.Range (0f,1f);

        if(ranNum <= 0.45f)
        {
            itemSelection = ItemSelection.AddPoint;

        }else if(ranNum > 0.45f && ranNum <= 0.61f)
        {
            itemSelection = ItemSelection.MenusPoints;

        }else if(ranNum > 0.61f && ranNum <= 0.77f)
        {
            itemSelection = ItemSelection.MenusPegZero;

        }else if(ranNum > 0.77f && ranNum <= 0.93f)
        {
            itemSelection = ItemSelection.MenusPeg;

        }else if(ranNum > 0.93f && ranNum <= 1f)
        {
            itemSelection = ItemSelection.PlusTime;
        }
    }
        public void InputHuman()
        {
            if(HasAttr(AttrType.DETECTING_MOVEMENT) && footsteps.Count > 0 && time_of_last_action < Q.turn){
                Screen.CursorVisible = false;
                Screen.AnimateMapCells(footsteps,new colorchar('!',Color.Red));
                previous_footsteps = footsteps;
                footsteps = new List<pos>();
            }
            if(HasAttr(AttrType.SWITCHING_ARMOR)){
                attrs[AttrType.SWITCHING_ARMOR]--;
            }
            if(HasFeat(FeatType.DANGER_SENSE)){
                M.UpdateDangerValues();
            }
            Screen.UpdateScreenCenterColumn(col);
            M.Draw();
            UI.MapCursor = new pos(-1,-1);
            UI.DisplayStats();
            if(HasAttr(AttrType.AUTOEXPLORE) && !grab_item_at_end_of_path){
                if(path.Count == 0){ //todo: autoexplore could also track whether the current path is leading to an unexplored tile instead of to an item/shrine/etc.
                    if(!FindAutoexplorePath()){ // - in this case I could check that tile's neighbors each turn, and calculate a new path early if they've all been mapped now.
                        B.Add("You don't see a path for further exploration. ");
                    }
                }
            }
            if(!HasAttr(AttrType.PARALYZED) && !HasAttr(AttrType.ASLEEP)){
                B.Print(false);
            }
            else{
                B.DisplayNow();
            }
            Cursor();
            Screen.CursorVisible = true;
            if(HasAttr(AttrType.PARALYZED,AttrType.ASLEEP)){
                if(HasAttr(AttrType.ASLEEP)){
                    Thread.Sleep(25);
                }
                Q1();
                return;
            }
            if(HasAttr(AttrType.ENRAGED) && !HasAttr(AttrType.FROZEN)){
                Thread.Sleep(100);
                EnragedMove();
                return;
            }
            bool pick_up = false;
            if(tile().inv != null || tile().type == TileType.CHEST){
                if(grab_item_at_end_of_path && path.Count == 0){
                    pick_up = true;
                }
                if((Global.Option(OptionType.AUTOPICKUP) && InventoryCount() < Global.MAX_INVENTORY_SIZE && (tile().type == TileType.CHEST || !tile().inv.ignored))){
                    pick_up = true;
                }
            }
            if(pick_up){
                if(!NextStepIsDangerous(tile())){
                    if(StunnedThisTurn()){
                        return;
                    }
                    if(tile().type == TileType.CHEST){
                        tile().OpenChest();
                        if(tile().type != TileType.CHEST){
                            grab_item_at_end_of_path = false;
                        }
                        Q1();
                    }
                    else{
                        if(InventoryCount() + tile().inv.quantity <= Global.MAX_INVENTORY_SIZE){
                            Item i = tile().inv;
                            tile().inv = null;
                            if(i.light_radius > 0){
                                i.UpdateRadius(i.light_radius,0);
                            }
                            i.row = -1;
                            i.col = -1;
                            B.Add("You pick up " + i.TheName() + ". ");
                            GetItem(i);
                            Q1();
                        }
                        else{
                            Item i = tile().inv;
                            int space_left = Global.MAX_INVENTORY_SIZE - InventoryCount();
                            if(space_left <= 0){
                                B.Add("You have no room for " + i.TheName() + ". ");
                                i.ignored = true;
                                Q0();
                            }
                            else{
                                Item newitem = new Item(i,row,col);
                                newitem.quantity = space_left;
                                i.quantity -= space_left;
                                B.Add("You pick up " + newitem.TheName() + ", but have no room for the other " + i.quantity.ToString() + ". ");
                                i.ignored = true;
                                GetItem(newitem);
                                Q1();
                            }
                        }
                        grab_item_at_end_of_path = false;
                    }
                    return;
                }
            }
            if(path.Count > 0){
                if(!NextStepIsDangerous(M.tile[path[0]])){
                    if(Input.KeyIsAvailable()){
                        ConsoleKeyInfo key = Input.ReadKey();
                        if(key.GetCommandChar() == 'x' && HasAttr(AttrType.AUTOEXPLORE)){
                            PlayerWalk(DirectionOf(path[0]));
                            if(path.Count > 0){
                                if(DistanceFrom(path[0]) == 0){
                                    path.RemoveAt(0);
                                }
                            }
                            return;
                        }
                        else{
                            Interrupt();
                        }
                    }
                    else{
                        PlayerWalk(DirectionOf(path[0]));
                        if(path.Count > 0){
                            if(DistanceFrom(path[0]) == 0){
                                path.RemoveAt(0);
                            }
                        }
                        return;
                    }
                }
                else{
                    Interrupt();
                }
            }
            if(HasAttr(AttrType.RUNNING)){
                Tile next = TileInDirection(attrs[AttrType.RUNNING]);
                if(!NextStepIsDangerous(next) && !Input.KeyIsAvailable()){
                    if(attrs[AttrType.RUNNING] == 5){
                        bool recover = false;
                        if(!HasAttr(AttrType.NONLIVING)){
                            if(HasFeat(FeatType.ENDURING_SOUL) && curhp % 10 != 0){
                                recover = true;
                            }
                            if(HasAttr(AttrType.BANDAGED)){
                                recover = true;
                            }
                        }
                        if(!recover){
                            if(HasAttr(AttrType.WAITING)){
                                attrs[AttrType.WAITING]--;
                                Q1();
                                return;
                            }
                            else{
                                attrs[AttrType.RUNNING] = 0;
                            }
                        }
                        else{
                            Q1();
                            return;
                        }
                    }
                    else{
                        bool corridor = true;
                        foreach(int dir in U.FourDirections){
                            if(TileInDirection(dir).passable && TileInDirection(dir.RotateDir(true,1)).passable && TileInDirection(dir.RotateDir(true,2)).passable){
                                corridor = false;
                                break;
                            }
                        }
                        List<Tile> tiles = new List<Tile>();
                        if(corridor){
                            List<int> blocked = new List<int>();
                            for(int i=-1;i<=1;++i){
                                blocked.Add(attrs[AttrType.RUNNING].RotateDir(true,4+i));
                            }
                            tiles = TilesAtDistance(1).Where(x=>(x.passable || x.Is(TileType.DOOR_C,TileType.RUBBLE)) && ApproximateEuclideanDistanceFromX10(x) == 10 && !blocked.Contains(DirectionOf(x)));
                        }
                        if(!corridor && next.passable){
                            PlayerWalk(attrs[AttrType.RUNNING]);
                            return;
                        }
                        else{
                            if(corridor && tiles.Count == 1){
                                attrs[AttrType.RUNNING] = DirectionOf(tiles[0]);
                                PlayerWalk(attrs[AttrType.RUNNING]);
                                foreach(int dir in U.FourDirections){ //now check again to see whether the player has entered a room
                                    if(TileInDirection(dir).passable && TileInDirection(dir.RotateDir(true,1)).passable && TileInDirection(dir.RotateDir(true,2)).passable){
                                        corridor = false;
                                        break;
                                    }
                                }
                                if(!corridor){
                                    attrs[AttrType.RUNNING] = 0;
                                    attrs[AttrType.WAITING] = 0;
                                }
                                return;
                            }
                            else{
                                attrs[AttrType.RUNNING] = 0;
                                attrs[AttrType.WAITING] = 0;
                            }
                            /*Tile opposite = TileInDirection(attrs[AttrType.RUNNING].RotateDir(true,4));
                            int num_floors = 0;
                            int floor_dir = 0;
                            foreach(Tile t2 in TilesAtDistance(1)){
                                //if(t2 != opposite && t2.name == "floor"){
                                if(t2 != opposite && (t2.passable || t2.type == TileType.DOOR_C)){
                                    num_floors++;
                                    floor_dir = DirectionOf(t2);
                                }
                            }
                            if(num_floors == 1){
                                attrs[AttrType.RUNNING] = floor_dir;//the purpose of this code is to detect whether there's a valid turn to make
                                PlayerWalk(floor_dir); //and take it if so. if there's a branch, it should stop.
                                return;
                            }
                            else{
                                attrs[AttrType.RUNNING] = 0;
                                attrs[AttrType.WAITING] = 0;
                            }*/
                        }
                    }
                }
                else{
                    if(Input.KeyIsAvailable()){
                        Input.ReadKey();
                    }
                    attrs[AttrType.RUNNING] = 0;
                    attrs[AttrType.WAITING] = 0;
                }
            }
            if(HasAttr(AttrType.RESTING)){
                if(attrs[AttrType.RESTING] == 10){
                    attrs[AttrType.RESTING] = -1;
                    curhp = maxhp;
                    curmp = maxmp;
                    B.Add("You rest...you feel great! ");
                    RemoveExhaustion();
                    bool repaired = false;
                    foreach(EquipmentStatus eqstatus in Enum.GetValues(typeof(EquipmentStatus))){
                        foreach(Weapon w in weapons){
                            if(w.status[eqstatus]){
                                repaired = true;
                                w.status[eqstatus] = false;
                            }
                        }
                        foreach(Armor a in armors){
                            if(a.status[eqstatus]){
                                repaired = true;
                                a.status[eqstatus] = false;
                            }
                        }
                    }
                    if(repaired){
                        B.Add("You finish repairing your equipment. ");
                    }
                    if(magic_trinkets.Contains(MagicTrinketType.CIRCLET_OF_THE_THIRD_EYE)){
                        Event hiddencheck = null;
                        foreach(Event e in Q.list){
                            if(!e.dead && e.type == EventType.CHECK_FOR_HIDDEN){
                                hiddencheck = e;
                                break;
                            }
                        }
                        List<Tile> valid_list = M.AllTiles().Where(x=>x.passable && !x.seen);
                        while(valid_list.Count > 0){
                            Tile chosen = valid_list.RemoveRandom();
                            if(chosen == null){
                                break;
                            }
                            var dijkstra = M.tile.GetDijkstraMap(new List<pos>{chosen.p},x=>!M.tile[x].passable && !M.tile[x].IsDoorType(true)); //todo: blocksconnectivityofmap?
                            if(chosen.TilesWithinDistance(18).Where(x=>x.passable && !x.seen && dijkstra[x.p] <= 18).Count < 20){
                                continue;
                            }
                            foreach(Tile t in chosen.TilesWithinDistance(12)){
                                if(t.type != TileType.FLOOR && !t.solid_rock){
                                    t.seen = true;
                                    if(t.type != TileType.WALL){
                                        t.revealed_by_light = true;
                                    }
                                    if(t.IsTrap() || t.Is(TileType.HIDDEN_DOOR)){
                                        if(hiddencheck != null){
                                            hiddencheck.area.Remove(t);
                                        }
                                    }
                                    if(t.IsTrap()){
                                        t.name = Tile.Prototype(t.type).name;
                                        t.a_name = Tile.Prototype(t.type).a_name;
                                        t.the_name = Tile.Prototype(t.type).the_name;
                                        t.symbol = Tile.Prototype(t.type).symbol;
                                        t.color = Tile.Prototype(t.type).color;
                                    }
                                    if(t.Is(TileType.HIDDEN_DOOR)){
                                        t.Toggle(null);
                                    }
                                    colorchar ch2 = Screen.BlankChar();
                                    if(t.inv != null){
                                        t.inv.revealed_by_light = true;
                                        ch2.c = t.inv.symbol;
                                        ch2.color = t.inv.color;
                                        M.last_seen[t.row,t.col] = ch2;
                                    }
                                    else{
                                        if(t.features.Count > 0){
                                            ch2 = t.FeatureVisual();
                                            M.last_seen[t.row,t.col] = ch2;
                                        }
                                        else{
                                            ch2.c = t.symbol;
                                            ch2.color = t.color;
                                            if(ch2.c == '#' && ch2.color == Color.RandomGlowingFungus){
                                                ch2.color = Color.Gray;
                                            }
                                            M.last_seen[t.row,t.col] = ch2;
                                        }
                                    }
                                }
                            }
                            M.Draw();
                            B.Add("Your " + MagicTrinket.Name(MagicTrinketType.CIRCLET_OF_THE_THIRD_EYE) + " grants you a vision. ");
                            break;
                        }
                    }
                    B.Print(false);
                    UI.DisplayStats();
                    Cursor();
                }
                else{
                    bool monsters_visible = false;
                    foreach(Actor a in M.AllActors()){
                        if(a != this && CanSee(a) && HasLOS(a.row,a.col)){ //check LOS, prevents detected mobs from stopping you
                            if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 1){
                                monsters_visible = true;
                            }
                        }
                    }
                    if(monsters_visible || Input.KeyIsAvailable()){
                        if(Input.KeyIsAvailable()){
                            Input.ReadKey();
                        }
                        if(monsters_visible){
                            attrs[AttrType.RESTING] = 0;
                            B.Add("You rest...you are interrupted! ");
                            B.Print(false);
                            Cursor();
                        }
                        else{
                            attrs[AttrType.RESTING] = 0;
                            B.Add("You rest...you stop resting. ");
                            B.Print(false);
                            Cursor();
                        }
                    }
                    else{
                        attrs[AttrType.RESTING]++;
                        B.Add("You rest... ",true);
                        Q1();
                        return;
                    }
                }
            }
            MouseUI.IgnoreMouseMovement = false;
            if(Q.turn == 0){
                Help.TutorialTip(TutorialTopic.Movement); //todo: move this elsewhere?
                Cursor();
            }
            if(!Help.displayed[TutorialTopic.Attacking] && M.AllActors().Any(a=>(a != this && CanSee(a)))){
                Help.TutorialTip(TutorialTopic.Attacking);
                Cursor();
            }
            ConsoleKeyInfo command = Input.ReadKey();
            char ch = command.GetAction().GetCommandChar();
            bool alt = false;
            bool ctrl = false;
            bool shift = false;
            if((command.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt){
                alt = true;
            }
            if((command.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control){
                ctrl = true;
            }
            if((command.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift){
                shift = true;
            }
            switch(ch){
            case '7':
            case '8':
            case '9':
            case '4':
            case '6':
            case '1':
            case '2':
            case '3':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if(HasAttr(AttrType.CONFUSED)){
                    PlayerWalk(Global.RandomDirection());
                    break;
                }
                int dir = ch - 48; //ascii 0-9 are 48-57
                if(shift || alt || ctrl){
                    bool monsters_visible = false;
                    foreach(Actor a in M.AllActors()){
                        if(a!=this && CanSee(a) && HasLOS(a.row,a.col)){
                            if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 2){
                                monsters_visible = true;
                            }
                        }
                    }
                    PlayerWalk(dir);
                    if(!monsters_visible){
                        attrs[AttrType.RUNNING] = dir;
                    }
                }
                else{
                    PlayerWalk(dir);
                }
                break;
            }
            case '5':
            {
                if(tile().inv != null){
                    tile().inv.revealed_by_light = true;
                    if(tile().inv.quantity > 1){
                        B.Add("There are " + tile().inv.AName() + " here. ");
                    }
                    else{
                        B.Add("There is " + tile().inv.AName() + " here. ");
                    }
                    //B.Add("You see " + M.tile[row,col].inv.AName() + ". ");
                }
                if(HasAttr(AttrType.BURNING)){
                    if(tile().IsWater() && !tile().Is(FeatureType.OIL)){
                        B.Add("You extinguish the flames. ");
                        attrs[AttrType.BURNING] = 0;
                        if(light_radius == 0){
                            UpdateRadius(1,0);
                        }
                        Q.KillEvents(this,AttrType.BURNING);
                        Fire.burning_objects.Remove(this);
                    }
                    else{
                        if(tile().Is(FeatureType.SLIME)){
                            B.Add("You cover yourself in slime to remove the flames. ");
                            attrs[AttrType.BURNING] = 0;
                            if(light_radius == 0){
                                UpdateRadius(1,0);
                            }
                            Q.KillEvents(this,AttrType.BURNING);
                            attrs[AttrType.SLIMED] = 1;
                            Fire.burning_objects.Remove(this);
                            Help.TutorialTip(TutorialTopic.Slimed);
                        }
                    }
                }
                if(HasAttr(AttrType.SLIMED) && tile().IsWater() && !tile().Is(FeatureType.FIRE)){
                    attrs[AttrType.SLIMED] = 0;
                    B.Add("You wash off the slime. ");
                }
                if(HasAttr(AttrType.OIL_COVERED) && tile().Is(FeatureType.SLIME)){
                    attrs[AttrType.OIL_COVERED] = 0;
                    attrs[AttrType.SLIMED] = 1;
                    B.Add("You cover yourself in slime to remove the oil. ");
                    Help.TutorialTip(TutorialTopic.Slimed);
                }
                if(HasAttr(AttrType.OIL_COVERED) && tile().IsWater() && !tile().Is(FeatureType.FIRE,FeatureType.OIL)){
                    attrs[AttrType.OIL_COVERED] = 0;
                    B.Add("You wash off the oil. ");
                    tile().AddFeature(FeatureType.OIL);
                }
                attrs[AttrType.NO_PLATE_ARMOR_NOISE] = 1;
                if(Speed() < 100){
                    QS();
                }
                else{
                    Q1();
                }
                break;
            }
            case 'w':
            {
                int dir = GetDirection("Start walking in which direction? ",false,true);
                if(dir != 0){
                    bool monsters_visible = false;
                    foreach(Actor a in M.AllActors()){
                        if(a != this && CanSee(a) && HasLOS(a.row,a.col)){
                            if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 2){
                                monsters_visible = true;
                            }
                        }
                    }
                    if(dir != 5){
                        if(FrozenThisTurn()){
                            break;
                        }
                        PlayerWalk(dir);
                    }
                    else{
                        QS();
                    }
                    if(!monsters_visible){
                        attrs[AttrType.RUNNING] = dir;
                        bool recover = false;
                        if(!HasAttr(AttrType.NONLIVING)){
                            if(HasFeat(FeatType.ENDURING_SOUL) && curhp % 10 != 0){
                                recover = true;
                            }
                            if(HasAttr(AttrType.BANDAGED)){
                                recover = true;
                            }
                        }
                        if(!recover && dir == 5){
                            attrs[AttrType.WAITING] = 20;
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case 'o':
            {
                if(FrozenThisTurn()){
                    break;
                }
                int dir = GetDirection("Operate something in which direction? ");
                if(dir != -1){
                    Tile t = TileInDirection(dir);
                    if(t.IsKnownTrap()){
                        if(HasFeat(FeatType.DISARM_TRAP)){
                            if(ActorInDirection(dir) != null){
                                B.Add("There is " + ActorInDirection(dir).AName(true) + " in the way. ");
                                Q0();
                                return;
                            }
                            if(StunnedThisTurn()){
                                return;
                            }
                            if(t.name.Contains("(safe)")){
                                B.Add("You disarm " + Tile.Prototype(t.type).the_name + ". ");
                                t.Toggle(this);
                            }
                            else{
                                B.Add("You make " + Tile.Prototype(t.type).the_name + " safe to cross. ");
                                t.SetName(Tile.Prototype(t.type).name + " (safe)");
                            }
                            Q1();
                        }
                        else{
                            B.Add("You don't know how to disable that trap. ");
                            Q0();
                            return;
                        }
                    }
                    else{
                        switch(t.type){
                        case TileType.DOOR_C:
                        case TileType.DOOR_O:
                        case TileType.RUBBLE:
                            if(StunnedThisTurn()){
                                break;
                            }
                            if(t.type == TileType.RUBBLE && !HasAttr(AttrType.BRUTISH_STRENGTH)){
                                IncreaseExhaustion(1);
                            }
                            t.Toggle(this);
                            Q1();
                            break;
                        case TileType.CHEST:
                            B.Add("Stand on the chest and press 'g' to retrieve its contents. ");
                            Q0();
                            break;
                        case TileType.STAIRS:
                            B.Add("Stand on the stairs and press '>' to descend. ");
                            Q0();
                            break;
                        case TileType.POOL_OF_RESTORATION:
                            B.Add("Stand over the pool and drop an item in to activate it. ");
                            Q0();
                            break;
                        case TileType.STONE_SLAB:
                            B.Add("The slab will open if light shines upon it. ");
                            Q0();
                            break;
                        default:
                            if(t.IsShrine()){
                                B.Add("Stand on the shrine and press 'g' to activate it. ");
                            }
                            Q0();
                            break;
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case 's':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if(Bow.status[EquipmentStatus.OUT_OF_ARROWS]){
                    B.Add("You're out of arrows! ");
                    Q0();
                }
                else{
                    if(EquippedWeapon.type == WeaponType.BOW || HasFeat(FeatType.QUICK_DRAW)){
                        if(ActorsAtDistance(1).Count > 0){
                            int seen = ActorsAtDistance(1).Where(x=>CanSee(x)).Count;
                            if(seen > 0){
                                if(seen == 1){
                                    B.Add("You can't fire with an enemy so close. ");
                                }
                                else{
                                    B.Add("You can't fire with enemies so close. ");
                                }
                                Q0();
                            }
                            else{
                                B.Add("As you raise your bow, something knocks it down! ");
                                B.Print(true);
                                Q1();
                            }
                        }
                        else{
                            MouseUI.fire_arrow_hack = true;
                            List<Tile> line = GetTargetLine(12);
                            if(line != null && line.LastOrDefault() != tile()){
                                if(EquippedWeapon != Bow && HasFeat(FeatType.QUICK_DRAW)){
                                    EquippedWeapon = Bow;
                                }
                                FireArrow(line);
                                if(Bow.status[EquipmentStatus.ONE_ARROW_LEFT]){
                                    Bow.status[EquipmentStatus.ONE_ARROW_LEFT] = false;
                                    Bow.status[EquipmentStatus.OUT_OF_ARROWS] = true;
                                }
                                else{
                                    if(Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS]){
                                        if(R.OneIn(15)){
                                            Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS] = false;
                                            Bow.status[EquipmentStatus.ONE_ARROW_LEFT] = true;
                                            B.Add("You're down to your last arrow! ");
                                            B.PrintAll();
                                        }
                                    }
                                    else{
                                        if(Bow.status[EquipmentStatus.LOW_ON_ARROWS]){
                                            if(R.OneIn(20)){
                                                Bow.status[EquipmentStatus.LOW_ON_ARROWS] = false;
                                                Bow.status[EquipmentStatus.ALMOST_OUT_OF_ARROWS] = true;
                                                B.Add("You have only a few arrows left! ");
                                                B.PrintAll();
                                            }
                                        }
                                        else{
                                            if(R.OneIn(25)){
                                                Bow.status[EquipmentStatus.LOW_ON_ARROWS] = true;
                                                B.Add("You're running a bit low on arrows. ");
                                                B.PrintAll();
                                            }
                                        }
                                    }
                                }
                            }
                            else{
                                Q0();
                            }
                        }
                    }
                    else{
                        B.Add("You need your bow to fire arrows - press e to switch equipment. ");
                        //B.Add("You can't fire arrows without your bow equipped - press e to switch equipment. ");
                        Q0();
                    }
                }
                break;
            }
            case 'z':
            {
                if(FrozenThisTurn()){
                    break;
                }
                foreach(Actor a in ActorsWithinDistance(2)){
                    if(a.HasAttr(AttrType.SILENCE_AURA) && a.HasLOE(this)){
                        if(this == player){
                            if(CanSee(a)){
                                B.Add(a.Your() + " aura of silence prevents you from casting! ");
                            }
                            else{
                                B.Add("An aura of silence prevents you from casting! ");
                            }
                        }
                        Q0();
                        return;
                    }
                }
                if(HasAttr(AttrType.SILENCED)){
                    B.Add("You can't cast while silenced. ");
                    Q0();
                    return;
                }
                List<colorstring> ls = new List<colorstring>();
                List<SpellType> sp = new List<SpellType>();
                //foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){
                bool bonus_marked = false;
                foreach(SpellType spell in spells_in_order){
                    if(HasSpell(spell)){
                        //string s = Spell.Name(spell).PadRight(15) + Spell.Tier(spell).ToString().PadLeft(3);
                        //s = s + FailRate(spell).ToString().PadLeft(9) + "%";
                        //s = s + Spell.Description(spell).PadLeft(34);
                        //this is the recent one!   colorstring cs = new colorstring(Spell.Name(spell).PadRight(17) + Spell.Tier(spell).ToString().PadLeft(3),Color.Gray);
                        colorstring cs = new colorstring(Spell.Name(spell).PadRight(17) + Spell.Tier(spell).ToString().PadLeft(2),Color.Gray);
                        //cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%",FailColor(spell)));
                        int failrate = Spell.FailRate(spell,exhaustion);
                        cs.strings.Add(new cstr("/",Color.DarkGray));
                        cs.strings.Add(new cstr((failrate.ToString() + "%  ").PadRight(5),FailColor(failrate)));
                        // this too cs.strings.Add(new cstr("".PadLeft(5),Color.Gray));
                        if(HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked){
                            bonus_marked = true;
                            cs = cs + Spell.DescriptionWithIncreasedDamage(spell);
                        }
                        else{
                            cs = cs + Spell.Description(spell);
                        }
                        ls.Add(cs);
                        sp.Add(spell);
                    }
                }
                if(sp.Count > 0){
                    colorstring topborder = new colorstring("-------------------Tier/Fail%-----------Description---------------",Color.Gray);
                    //colorstring topborder = new colorstring("-------------------Tier (fail%)---------Description---------------",Color.Gray);
                    //colorstring topborder = new colorstring("---------------------Tier-----------------Description-------------",Color.Gray);
                    colorstring bottomborder = new colorstring("".PadRight(25,'-') + "[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(COLS,'-'),Color.Gray);
                    //colorstring bottomborder = new colorstring("----------------" + "Exhaustion: ".PadLeft(12+(3-basefail.ToString().Length),'-'),Color.Gray,(basefail.ToString() + "%"),FailColor(basefail),"----------[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(22,'-'),Color.Gray);
                    //int i = Select("Cast which spell? ",topborder,bottomborder,ls);
                    int i = Select("Cast which spell? ",topborder,bottomborder,ls,false,false,true,true,HelpTopic.Spells);
                    if(i != -1){
                        if(!CastSpell(sp[i])){
                            Q0();
                        }
                    }
                    else{
                        Q0();
                    }
                }
                else{
                    B.Add("You don't know any spells. ");
                    Q0();
                }
                break;
            }
            case 'r':
                if(FrozenThisTurn()){
                    break;
                }
                if(attrs[AttrType.RESTING] != -1){ //gets set to -1 if you've rested on this level
                    bool monsters_visible = false;
                    foreach(Actor a in M.AllActors()){
                        if(a != this && CanSee(a) && HasLOS(a.row,a.col)){ //check LOS, prevents detected mobs from stopping you
                            if(!a.Is(ActorType.CARNIVOROUS_BRAMBLE,ActorType.MUD_TENTACLE) || DistanceFrom(a) <= 1){
                                monsters_visible = true;
                            }
                        }
                    }
                    bool equipment_can_be_repaired = false;
                    foreach(EquipmentStatus eqs in Enum.GetValues(typeof(EquipmentStatus))){
                        foreach(Weapon w in weapons){
                            if(w.status[eqs]){
                                equipment_can_be_repaired = true;
                                break;
                            }
                        }
                        foreach(Armor a in armors){
                            if(a.status[eqs]){
                                equipment_can_be_repaired = true;
                                break;
                            }
                        }
                        if(equipment_can_be_repaired){
                            break;
                        }
                    }
                    if(!monsters_visible){
                        if(curhp < maxhp || curmp < maxmp || exhaustion > 0 || equipment_can_be_repaired){
                            if(Global.Option(OptionType.CONFIRM_BEFORE_RESTING) && !B.YesOrNoPrompt("Rest and repair your equipment?")){
                                Q0();
                                break;
                            }
                            if(StunnedThisTurn()){
                                break;
                            }
                            attrs[AttrType.RESTING] = 1;
                            B.Add("You rest... ",true);
                            Q1();
                        }
                        else{
                            B.Add("You don't need to rest right now. ");
                            Q0();
                        }
                    }
                    else{
                        B.Add("You can't rest while there are enemies around! ");
                        Q0();
                    }
                }
                else{
                    B.Add("You find it impossible to rest again on this dungeon level. ");
                    Q0();
                }
                break;
            case '>':
                if(FrozenThisTurn()){
                    break;
                }
                if(M.tile[row,col].type == TileType.STAIRS){
                    if(StunnedThisTurn()){
                        break;
                    }
                    bool equipment_can_be_repaired = false;
                    foreach(EquipmentStatus eqs in Enum.GetValues(typeof(EquipmentStatus))){
                        foreach(Weapon w in weapons){
                            if(w.status[eqs]){
                                equipment_can_be_repaired = true;
                                break;
                            }
                        }
                        foreach(Armor a in armors){
                            if(a.status[eqs]){
                                equipment_can_be_repaired = true;
                                break;
                            }
                        }
                        if(equipment_can_be_repaired){
                            break;
                        }
                    }
                    if(attrs[AttrType.RESTING] != -1 && (curhp < maxhp || curmp < maxmp || exhaustion > 0 || equipment_can_be_repaired)){
                        MouseUI.descend_hack = true;
                        if(!B.YesOrNoPrompt("Really take the stairs without resting first?")){
                            Q0();
                            return;
                        }
                    }
                    bool shrine_remaining = false;
                    for(int i=0;i<ROWS;++i){
                        for(int j=0;j<COLS;++j){
                            if(M.tile[i,j].IsShrine() && M.tile[i,j].type != TileType.SPELL_EXCHANGE_SHRINE){
                                shrine_remaining = true;
                                break;
                            }
                        }
                        if(shrine_remaining){
                            MouseUI.descend_hack = true;
                            break;
                        }
                    }
                    if(shrine_remaining){
                        Help.TutorialTip(TutorialTopic.DistributionOfShrines);
                        if(!B.YesOrNoPrompt("You feel an ancient power calling you back. Leave anyway?")){
                            Q0();
                            return;
                        }
                    }
                    B.Add("You walk down the stairs. ");
                    B.PrintAll();
                    if(M.current_level < 20){
                        M.GenerateLevel();
                    }
                    else{
                        M.GenerateFinalLevel();
                        B.Add("Strange chants and sulfurous smoke fill the air here. ");
                    }
                    if(magic_trinkets.Contains(MagicTrinketType.LENS_OF_SCRYING)){
                        Item i = inv.Where(x=>!Item.identified[x.type]).RandomOrDefault();
                        if(i != null){
                            string itemname = i.NameWithoutQuantity();
                            Item.identified[i.type] = true;
                            string IDedname = i.NameWithoutQuantity();
                            string isare = " is a ";
                            if(i.quantity > 1){
                                isare = " are ";
                            }
                            B.Add("Your " + MagicTrinket.Name(MagicTrinketType.LENS_OF_SCRYING) + " reveals that your " + itemname + isare + IDedname + ". ");
                        }
                    }
                    if(M.current_level == 3){
                        Help.TutorialTip(TutorialTopic.SwitchingEquipment);
                    }
                    Q0();
                }
                else{
                    Tile stairs = null;
                    foreach(Tile t in M.AllTiles()){
                        if(t.type == TileType.STAIRS && t.seen){
                            stairs = t;
                            break;
                        }
                    }
                    if(stairs != null){
                        List<pos> stairpath = GetPath(stairs,-1,true);
                        foreach(pos p in stairpath){
                            if(p.row != row || p.col != col){
                                colorchar cch = Screen.MapChar(p.row,p.col);
                                if(p.row == stairs.row && p.col == stairs.col){
                                    cch.bgcolor = Color.Green;
                                    if(Global.LINUX && !Screen.GLMode){ //no bright bg in terminals
                                        cch.bgcolor = Color.DarkGreen;
                                    }
                                    if(cch.color == cch.bgcolor){
                                        cch.color = Color.Black;
                                    }
                                    Screen.WriteMapChar(p.row,p.col,cch);
                                }
                                else{
                                    cch.bgcolor = Color.DarkGreen;
                                    if(cch.color == cch.bgcolor){
                                        cch.color = Color.Black;
                                    }
                                    Screen.WriteMapChar(p.row,p.col,cch);
                                }
                            }
                        }
                        MouseUI.PushButtonMap(MouseMode.YesNoPrompt);
                        MouseUI.CreateButton(ConsoleKey.Y,false,2,Global.MAP_OFFSET_COLS + 22,1,2);
                        MouseUI.CreateButton(ConsoleKey.N,false,2,Global.MAP_OFFSET_COLS + 25,1,2);
                        B.DisplayNow("Travel to the stairs? (y/n): ");
                        Screen.CursorVisible = true;
                        bool done = false;
                        while(!done){
                            command = Input.ReadKey();
                            switch(command.KeyChar){
                            case 'y':
                            case 'Y':
                            case '>':
                            case (char)13:
                                done = true;
                                MouseUI.PopButtonMap();
                                break;
                            default:
                                Q0();
                                MouseUI.PopButtonMap();
                                return;
                            }
                        }
                        FindPath(stairs,-1,true);
                        if(path.Count > 0){
                            PlayerWalk(DirectionOf(path[0]));
                            if(path.Count > 0){
                                if(DistanceFrom(path[0]) == 0){
                                    path.RemoveAt(0);
                                }
                            }
                        }
                        else{
                            B.Add("There's no path to the stairs. ");
                            Q0();
                        }
                    }
                    else{
                        B.Add("You don't see any stairs here. ");
                        Q0();
                    }
                }
                break;
            case 'x':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if((tile().inv != null && !tile().inv.ignored) || (tile().Is(TileType.CHEST) && (tile().inv == null || !tile().inv.ignored))){
                    goto case 'g';
                }
                if(!FindAutoexplorePath()){
                    B.Add("You don't see a path for further exploration. ");
                    Q0();
                }
                else{
                    attrs[AttrType.AUTOEXPLORE]++;
                    PlayerWalk(DirectionOf(path[0]));
                    if(path.Count > 0){
                        if(DistanceFrom(path[0]) == 0){
                            path.RemoveAt(0);
                        }
                    }
                }
                break;
            }
            case 'X':
                if(FrozenThisTurn()){
                    break;
                }
                Screen.CursorVisible = false;
                Dictionary<Actor,colorchar> old_ch = new Dictionary<Actor,colorchar>();
                List<Actor> drawn = new List<Actor>();
                foreach(Actor a in M.AllActors()){
                    if(CanSee(a)){
                        old_ch.Add(a,M.last_seen[a.row,a.col]);
                        M.last_seen[a.row,a.col] = new colorchar(a.symbol,a.color);
                        drawn.Add(a);
                    }
                }
                Screen.MapDrawWithStrings(M.last_seen,0,0,ROWS,COLS);
                ChoosePathingDestination();
                foreach(Actor a in drawn){
                    M.last_seen[a.row,a.col] = old_ch[a];
                }
                M.Redraw();
                if(path.Count > 0){
                    PlayerWalk(DirectionOf(path[0]));
                    if(path.Count > 0){
                        if(DistanceFrom(path[0]) == 0){
                            path.RemoveAt(0);
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            case 'g':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if(tile().inv == null){
                    if(tile().type == TileType.CHEST){
                        if(StunnedThisTurn()){
                            break;
                        }
                        tile().OpenChest();
                        Q1();
                    }
                    else{
                        if(tile().IsShrine()){
                            if(StunnedThisTurn()){
                                break;
                            }
                            switch(tile().type){
                            case TileType.COMBAT_SHRINE:
                                Help.TutorialTip(TutorialTopic.Combat);
                                IncreaseSkill(SkillType.COMBAT);
                                break;
                            case TileType.DEFENSE_SHRINE:
                                Help.TutorialTip(TutorialTopic.Defense);
                                IncreaseSkill(SkillType.DEFENSE);
                                break;
                            case TileType.MAGIC_SHRINE:
                                Help.TutorialTip(TutorialTopic.Magic);
                                IncreaseSkill(SkillType.MAGIC);
                                break;
                            case TileType.SPIRIT_SHRINE:
                                Help.TutorialTip(TutorialTopic.Spirit);
                                IncreaseSkill(SkillType.SPIRIT);
                                break;
                            case TileType.STEALTH_SHRINE:
                                Help.TutorialTip(TutorialTopic.Stealth);
                                IncreaseSkill(SkillType.STEALTH);
                                break;
                            case TileType.SPELL_EXCHANGE_SHRINE: //currently disabled
                            {
                                List<colorstring> ls = new List<colorstring>();
                                List<SpellType> sp = new List<SpellType>();
                                bool bonus_marked = false;
                                foreach(SpellType spell in spells_in_order){
                                    if(HasSpell(spell)){
                                        colorstring cs = new colorstring(Spell.Name(spell).PadRight(18) + Spell.Tier(spell).ToString().PadLeft(3),Color.Gray);
                                        //cs.strings.Add(new cstr(FailRate(spell).ToString().PadLeft(9) + "%",FailColor(spell)));
                                        cs.strings.Add(new cstr("".PadRight(5),Color.Gray));
                                        if(HasFeat(FeatType.MASTERS_EDGE) && Spell.IsDamaging(spell) && !bonus_marked){
                                            bonus_marked = true;
                                            cs = cs + Spell.DescriptionWithIncreasedDamage(spell);
                                        }
                                        else{
                                            cs = cs + Spell.Description(spell);
                                        }
                                        ls.Add(cs);
                                        sp.Add(spell);
                                    }
                                }
                                if(sp.Count > 0){
                                    colorstring topborder = new colorstring("----------------------Tier-----------------Description------------",Color.Gray);
                                    int basefail = exhaustion;
                                    colorstring bottomborder = new colorstring("----------------" + "Exhaustion: ".PadLeft(12+(3-basefail.ToString().Length),'-'),Color.Gray,(basefail.ToString() + "%"),FailColor(basefail),"----------[",Color.Gray,"?",Color.Cyan,"] for help".PadRight(22,'-'),Color.Gray);
                                    int i = Select("Trade one of your spells for another? ",topborder,bottomborder,ls,false,false,true,true,HelpTopic.Spells);
                                    if(i != -1){
                                        List<SpellType> unknown = new List<SpellType>();
                                        foreach(SpellType spell in Enum.GetValues(typeof(SpellType))){
                                            if(!HasSpell(spell) && spell != SpellType.NO_SPELL && spell != SpellType.NUM_SPELLS){
                                                unknown.Add(spell);
                                            }
                                        }
                                        SpellType forgotten = sp[i];
                                        spells_in_order.Remove(forgotten);
                                        spells[forgotten] = false;
                                        SpellType learned = unknown.Random();
                                        spells[learned] = true;
                                        spells_in_order.Add(learned);
                                        B.Add("You forget " + Spell.Name(forgotten) + ". You learn " + Spell.Name(learned) + ". ");
                                        tile().TransformTo(TileType.RUINED_SHRINE);
                                        tile().SetName("ruined shrine of magic");
                                    }
                                    else{
                                        Q0();
                                    }
                                }
                                break;
                            }
                            default:
                                break;
                            }
                            if(tile().type != TileType.SPELL_EXCHANGE_SHRINE){
                                Q1();
                            }
                            //if(tile().type == TileType.MAGIC_SHRINE && spells_in_order.Count > 1){
                            //	tile().TransformTo(TileType.SPELL_EXCHANGE_SHRINE);
                            //}
                            //else{
                                if(tile().type != TileType.SPELL_EXCHANGE_SHRINE && !tile().name.Contains("ruined")){
                                    string oldname = tile().name;
                                    tile().TransformTo(TileType.RUINED_SHRINE);
                                    tile().SetName("ruined " + oldname);
                                }
                            //}
                            foreach(Tile t in TilesWithinDistance(2)){
                                if(t.IsShrine()){
                                    string oldname = t.name;
                                    t.TransformTo(TileType.RUINED_SHRINE);
                                    t.SetName("ruined " + oldname);
                                }
                            }
                        }
                        else{
                            if(tile().type == TileType.BLAST_FUNGUS){
                                if(InventoryCount() < Global.MAX_INVENTORY_SIZE){
                                    if(StunnedThisTurn()){
                                        break;
                                    }
                                    B.Add("You pull the blast fungus from the floor. ");
                                    B.Add("Its fuse ignites! ");
                                    tile().Toggle(null);
                                    Item i = Item.Create(ConsumableType.BLAST_FUNGUS,this);
                                    if(i != null){
                                        i.other_data = 3;
                                        i.revealed_by_light = true;
                                        Q.Add(new Event(i,100,EventType.BLAST_FUNGUS));
                                        Screen.AnimateMapCell(row,col,new colorchar('3',Color.Red),100);
                                    }
                                    Q1();
                                }
                                else{
                                    B.Add("Your pack is too full to pick up the blast fungus. ");
                                    Q0();
                                }
                            }
                            else{
                                if(tile().type == TileType.RUINED_SHRINE){
                                    B.Add("This " + tile().name + " has no power left. ");
                                    Q0();
                                }
                                else{
                                    B.Add("There's nothing here to pick up. ");
                                    Q0();
                                }
                            }
                        }
                    }
                }
                else{
                    if(InventoryCount() < Global.MAX_INVENTORY_SIZE){
                        if(StunnedThisTurn()){
                            break;
                        }
                        if(InventoryCount() + tile().inv.quantity <= Global.MAX_INVENTORY_SIZE){
                            Item i = tile().inv;
                            tile().inv = null;
                            if(i.light_radius > 0){
                                i.UpdateRadius(i.light_radius,0);
                            }
                            i.row = -1;
                            i.col = -1;
                            i.revealed_by_light = true;
                            B.Add("You pick up " + i.TheName() + ". ");
                            GetItem(i);
                            Q1();
                        }
                        else{
                            int space_left = Global.MAX_INVENTORY_SIZE - InventoryCount();
                            Item i = tile().inv;
                            Item newitem = new Item(i,row,col);
                            newitem.quantity = space_left;
                            i.quantity -= space_left;
                            newitem.revealed_by_light = true;
                            B.Add("You pick up " + newitem.TheName() + ", but have no room for the other " + i.quantity.ToString() + ". ");
                            i.ignored = true;
                            GetItem(newitem);
                            Q1();
                        }
                    }
                    else{
                        tile().inv.revealed_by_light = true;
                        B.Add("Your pack is too full to pick up " + tile().inv.TheName() + ". ");
                        tile().inv.ignored = true;
                        Q0();
                    }
                }
                break;
            }
            case 'i':
            case 'a': //these are handled in the same case label so I can drop down from the selection to the action
            case 'f':
            case 'd':
            {
                if(inv.Count == 0){
                    B.Add("You have nothing in your pack. ");
                    Q0();
                    break;
                }
                if(ch == 'a' || ch == 'f' || ch == 'd'){
                    if(FrozenThisTurn()){
                        break;
                    }
                }
                string msg = "In your pack: ";
                bool no_redraw = (ch == 'i');
                switch(ch){
                case 'a':
                    msg = "Apply which item? ";
                    break;
                case 'f':
                    msg = "Fling which item? ";
                    break;
                case 'd':
                    msg = "Drop which item? ";
                    break;
                }
                ItemSelection sel = new ItemSelection();
                sel.value = -2;
                while(sel.value != -1){
                    sel = SelectItem(msg,no_redraw);
                    if(ch == 'i'){
                        sel.description_requested = true;
                    }
                    if(sel.value != -1 && sel.description_requested){
                        MouseUI.PushButtonMap(MouseMode.Inventory);
                        MouseUI.AutomaticButtonsFromStrings = true;
                        Screen.CursorVisible = false;
                        colorchar[,] screen = Screen.GetCurrentScreen();
                        for(int letter=0;letter<inv.Count;++letter){
                            Screen.WriteMapChar(letter+1,1,(char)(letter+'a'),Color.DarkCyan);
                        }
                        List<colorstring> box = UI.ItemDescriptionBox(inv[sel.value],false,false,31);
                        int i = (Global.SCREEN_H - box.Count) / 2;
                        int j = (Global.SCREEN_W - box[0].Length()) / 2;
                        foreach(colorstring cs in box){
                            Screen.WriteString(i,j,cs);
                            ++i;
                        }
                        switch(Input.ReadKey().GetCommandChar()){
                        case 'a':
                            ch = 'a';
                            sel.description_requested = false;
                            break;
                        case 'f':
                            ch = 'f';
                            sel.description_requested = false;
                            break;
                        case 'd':
                            ch = 'd';
                            sel.description_requested = false;
                            break;
                        }
                        MouseUI.PopButtonMap();
                        MouseUI.AutomaticButtonsFromStrings = false;
                        if(sel.description_requested){
                            Screen.WriteArray(0,0,screen);
                        }
                        else{
                            M.Redraw(); //this will break if the box goes off the map, todo
                            break;
                        }
                        Screen.CursorVisible = true;
                    }
                    else{
                        break;
                    }
                }
                if(sel.value == -1){
                    Q0();
                    break;
                }
                int num = sel.value;
                if(ch == 'f' && (inv[num].NameOfItemType() == "orb" || inv[num].type == ConsumableType.BLAST_FUNGUS)){
                    ch = 'a';
                }
                switch(ch){
                case 'a':
                {
                    if(FrozenThisTurn()){
                        break;
                    }
                    if(HasAttr(AttrType.NONLIVING) && inv[num].NameOfItemType() == "potion"){
                        B.Add("Potions have no effect on you in stone form. ");
                        Q0();
                    }
                    else{
                        if(HasAttr(AttrType.NONLIVING) && inv[num].type == ConsumableType.BANDAGES){
                            B.Add("Bandages have no effect on you in stone form. ");
                            Q0();
                        }
                        else{
                            if(HasAttr(AttrType.BLIND) && inv[num].NameOfItemType() == "scroll"){
                                B.Add("You can't read scrolls while blind. ");
                                Q0();
                            }
                            else{
                                if(inv[num].NameOfItemType() == "wand" && inv[num].charges == 0 && inv[num].other_data == -1){
                                    B.Add("That wand has no charges left. ");
                                    Q0();
                                }
                                else{
                                    bool silenced = HasAttr(AttrType.SILENCED,AttrType.SILENCE_AURA);
                                    string silence_message = "You can't read scrolls while silenced. ";
                                    if(HasAttr(AttrType.SILENCE_AURA)){
                                        silence_message = "Your silence aura makes reading scrolls impossible. ";
                                    }
                                    else{
                                        List<Actor> auras = ActorsWithinDistance(2).Where(x=>x.HasAttr(AttrType.SILENCE_AURA) && x.HasLOE(this));
                                        if(auras.Count > 0){
                                            silenced = true;
                                            Actor a = auras.Where(x=>CanSee(x)).RandomOrDefault();
                                            if(a != null){
                                                silence_message = a.the_name + "'s silence aura makes reading scrolls impossible. ";
                                            }
                                            else{
                                                silence_message = "An aura of silence makes reading scrolls impossible. ";
                                            }
                                        }
                                    }
                                    if(silenced && inv[num].NameOfItemType() == "scroll"){
                                        B.Add(silence_message);
                                        Q0();
                                    }
                                    else{
                                        Actor thief = ActorsAtDistance(1).Where(x=>x.type == ActorType.SNEAK_THIEF).RandomOrDefault();
                                        if(thief != null){
                                            B.Add(thief.YouVisible("snatch",true) + " your " + inv[num].SingularName(false) + "! ");
                                            B.PrintAll();
                                            Item stolen = inv[num];
                                            if(inv[num].quantity > 1){
                                                stolen = new Item(inv[num],inv[num].row,inv[num].col);
                                                stolen.revealed_by_light = inv[num].revealed_by_light;
                                                inv[num].quantity--;
                                            }
                                            else{
                                                inv.Remove(stolen);
                                            }
                                            thief.GetItem(stolen);
                                            Q1();
                                        }
                                        else{
                                            if(StunnedThisTurn()){
                                                break;
                                            }
                                            if(HasAttr(AttrType.SLIMED,AttrType.OIL_COVERED) && R.OneIn(5)){
                                                Item i = inv[num];
                                                B.Add("The " + i.SingularName() + " slips out of your hands! ");
                                                i.revealed_by_light = true;
                                                if(i.quantity <= 1){
                                                    if(tile().type == TileType.POOL_OF_RESTORATION){
                                                        B.Add("You drop " + i.TheName() + " into the pool. ");
                                                        inv.Remove(i);
                                                        if(curhp < maxhp || curmp < maxmp || exhaustion > 0){
                                                            B.Add("The pool's glow restores you. ");
                                                            curhp = maxhp;
                                                            curmp = maxmp;
                                                            RemoveExhaustion();
                                                        }
                                                        else{
                                                            B.Add("The pool of restoration glows briefly, then dries up. ");
                                                        }
                                                        tile().TurnToFloor();
                                                    }
                                                    else{
                                                        if(tile().GetItem(i)){
                                                            B.Add("You drop " + i.TheName() + ". ");
                                                            inv.Remove(i);
                                                        }
                                                        else{
                                                            //this only happens if every tile is full - i.e. never
                                                        }
                                                    }
                                                }
                                                else{
                                                    if(tile().type == TileType.POOL_OF_RESTORATION){
                                                        Item newitem = new Item(i,row,col);
                                                        newitem.quantity = 1;
                                                        i.quantity--;
                                                        B.Add("You drop " + newitem.TheName() + " into the pool. ");
                                                        if(curhp < maxhp || curmp < maxmp){
                                                            B.Add("The pool's glow restores you. ");
                                                            curhp = maxhp;
                                                            curmp = maxmp;
                                                        }
                                                        else{
                                                            B.Add("The pool of restoration glows briefly, then dries up. ");
                                                        }
                                                        tile().TurnToFloor();
                                                    }
                                                    else{
                                                        Item newitem = new Item(i,row,col);
                                                        newitem.quantity = 1;
                                                        newitem.revealed_by_light = true;
                                                        if(tile().GetItem(newitem)){
                                                            i.quantity -= 1;
                                                            B.Add("You drop " + newitem.TheName() + ". ");
                                                        }
                                                        else{
                                                            //should never happen
                                                        }
                                                    }
                                                }
                                                Q1();
                                                break;
                                            }
                                            if(inv[num].Use(this)){
                                                Q1();
                                            }
                                            else{
                                                Q0();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
                case 'f':
                {
                    if(FrozenThisTurn()){
                        break;
                    }
                    if(StunnedThisTurn()){
                        break;
                    }
                    List<Tile> line = GetTargetTile(12,0,false,false);
                    if(line != null){
                        Item i = null;
                        if(inv[num].quantity == 1){
                            i = inv[num];
                        }
                        else{
                            i = new Item(inv[num],-1,-1);
                            inv[num].quantity--;
                        }
                        i.revealed_by_light = true;
                        i.ignored = true;
                        Tile t = line.LastBeforeSolidTile();
                        Actor first = FirstActorInLine(line);
                        B.Add(You("fling") + " " + i.TheName() + ". ");
                        if(first != null && first != this){
                            t = first.tile();
                            B.Add("It hits " + first.the_name + ". ",first);
                        }
                        line = line.ToFirstSolidTileOrActor();
                        if(line.Count > 0){
                            line.RemoveAt(line.Count - 1);
                        }
                        {
                            Tile first_unseen = null;
                            foreach(Tile tile2 in line){
                                if(!tile2.seen){
                                    first_unseen = tile2;
                                    break;
                                }
                            }
                            if(first_unseen != null){
                                line = line.To(first_unseen);
                                if(line.Count > 0){
                                    line.RemoveAt(line.Count - 1);
                                }
                            }
                        }
                        if(line.Count > 0){
                            AnimateProjectile(line,i.symbol,i.color);
                        }
                        if(i.IsBreakable()){
                            B.Add("It breaks! ",t);
                            i.CheckForMimic();
                        }
                        else{
                            bool broken = false;
                            if(i.type == ConsumableType.FLINT_AND_STEEL){
                                if(R.OneIn(3)){
                                    i.other_data--;
                                    if(i.other_data == 2){
                                        B.Add("Your flint & steel shows signs of wear. ",t);
                                    }
                                    if(i.other_data == 1){
                                        B.Add("Your flint & steel is almost depleted. ",t);
                                    }
                                    if(i.other_data == 0){
                                        broken = true;
                                        B.Add("Your flint & steel is used up. ",t);
                                    }
                                }
                            }
                            if(!broken){
                                t.GetItem(i);
                            }
                        }
                        inv.Remove(i);
                        t.MakeNoise(2);
                        if(first != null && first != this){
                            first.player_visibility_duration = -1;
                            first.attrs[AttrType.PLAYER_NOTICED]++;
                        }
                        else{
                            if(t.IsTrap()){
                                t.TriggerTrap();
                            }
                        }
                        Q1();
                    }
                    else{
                        Q0();
                    }
                    break;
                }
                case 'd':
                {
                    if(FrozenThisTurn()){
                        break;
                    }
                    if(StunnedThisTurn()){
                        break;
                    }
                    Item i = inv[num];
                    i.revealed_by_light = true;
                    if(i.quantity <= 1){
                        if(tile().type == TileType.POOL_OF_RESTORATION){
                            B.Add("You drop " + i.TheName() + " into the pool. ");
                            inv.Remove(i);
                            if(curhp < maxhp || curmp < maxmp){
                                B.Add("The pool's glow restores you. ");
                                curhp = maxhp;
                                curmp = maxmp;
                            }
                            else{
                                B.Add("The pool of restoration glows briefly, then dries up. ");
                            }
                            tile().TurnToFloor();
                            Q1();
                        }
                        else{
                            if(tile().GetItem(i)){
                                B.Add("You drop " + i.TheName() + ". ");
                                inv.Remove(i);
                                i.ignored = true;
                                Q1();
                            }
                            else{
                                B.Add("There is no room. ");
                                Q0();
                            }
                        }
                    }
                    else{
                        if(tile().type == TileType.POOL_OF_RESTORATION){
                            Item newitem = new Item(i,row,col);
                            newitem.quantity = 1;
                            i.quantity--;
                            B.Add("You drop " + newitem.TheName() + " into the pool. ");
                            if(curhp < maxhp || curmp < maxmp){
                                B.Add("The pool's glow restores you. ");
                                curhp = maxhp;
                                curmp = maxmp;
                            }
                            else{
                                B.Add("The pool of restoration glows briefly, then dries up. ");
                            }
                            tile().TurnToFloor();
                            Q1();
                        }
                        else{
                            //B.DisplayNow("Drop how many? (1-" + i.quantity + "): ");
                            //int count = Global.EnterInt();
                            int count = 1;
                            if(count == 0){
                                Q0();
                            }
                            else{
                                if(count >= i.quantity || count == -1){
                                    if(tile().GetItem(i)){
                                        B.Add("You drop " + i.TheName() + ". ");
                                        inv.Remove(i);
                                        i.ignored = true;
                                        Q1();
                                    }
                                    else{
                                        B.Add("There is no room. ");
                                        Q0();
                                    }
                                }
                                else{
                                    Item newitem = new Item(i,row,col);
                                    newitem.quantity = count;
                                    newitem.revealed_by_light = true;
                                    if(tile().GetItem(newitem)){
                                        i.quantity -= count;
                                        B.Add("You drop " + newitem.TheName() + ". ");
                                        newitem.ignored = true;
                                        Q1();
                                    }
                                    else{
                                        B.Add("There is no room. ");
                                        Q0();
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
                }
                break;
            }
            case 'e':
            {
                int[] changes = UI.DisplayEquipment();
                M.Redraw();
                Weapon new_weapon = WeaponOfType((WeaponType)changes[0]);
                Armor new_armor = ArmorOfType((ArmorType)changes[1]);
                Weapon old_weapon = EquippedWeapon;
                Armor old_armor = EquippedArmor;
                bool weapon_changed = (new_weapon != old_weapon);
                bool armor_changed = (new_armor != old_armor);
                if(weapon_changed || armor_changed){
                    if(FrozenThisTurn()){
                        break;
                    }
                }
                bool cursed_weapon = false;
                bool cursed_armor = false;
                if(weapon_changed && EquippedWeapon.status[EquipmentStatus.STUCK]){
                    cursed_weapon = true;
                    weapon_changed = false;
                    armor_changed = false;
                }
                if(armor_changed && EquippedArmor.status[EquipmentStatus.STUCK]){
                    cursed_armor = true;
                    armor_changed = false;
                    weapon_changed = false;
                }
                if(!weapon_changed && !armor_changed){
                    if(cursed_weapon){
                        B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. ");
                    }
                    if(cursed_armor){
                        B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. ");
                    }
                    Q0();
                }
                else{
                    if(StunnedThisTurn()){
                        break;
                    }
                    Help.displayed[TutorialTopic.SwitchingEquipment] = true;
                    if(weapon_changed){
                        EquippedWeapon = new_weapon;
                        if(HasFeat(FeatType.QUICK_DRAW) && !armor_changed && old_weapon != Bow){
                            B.Add("You quickly ready your " + EquippedWeapon + ". ");
                        }
                        else{
                            if(old_weapon == Bow){
                                B.Add("You put away your bow and ready your " + EquippedWeapon + ". ");
                            }
                            else{
                                B.Add("You ready your " + EquippedWeapon + ". ");
                            }
                        }
                        //UpdateOnEquip(old_weapon,EquippedWeapon);
                    }
                    if(armor_changed){
                        EquippedArmor = new_armor;
                        //UpdateOnEquip(old_armor,EquippedArmor);
                        if(TotalProtectionFromArmor() == 0){
                            if(EquippedArmor.status[EquipmentStatus.DAMAGED]){
                                B.Add("You wear your damaged " + EquippedArmor + ". ");
                                B.Add("(It provides no protection until repaired.) ");
                            }
                            else{
                                B.Add("You wear your " + EquippedArmor + ". ");
                                B.Add("You can't wear it effectively in your exhausted state. ");
                            }
                        }
                        else{
                            B.Add("You wear your " + EquippedArmor + ". ");
                        }
                        attrs[AttrType.SWITCHING_ARMOR] = 1;
                    }
                    if(cursed_weapon){
                        B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. ");
                    }
                    if(cursed_armor){
                        B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. ");
                    }
                    if(HasFeat(FeatType.QUICK_DRAW) && !armor_changed && old_weapon != Bow){
                        Q0();
                    }
                    else{
                        Q1();
                    }
                }
                break;
            }
            case '!': //note that these are the top-row numbers, NOT the actual shifted versions
            case '@': //<---this is the '2' above the 'w'    (not the '@', and not the numpad 2)
            case '#':
            case '$':
            case '%':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if(EquippedWeapon.status[EquipmentStatus.STUCK]){
                    B.Add("Your " + EquippedWeapon + " is stuck to your hand and can't be put away. ");
                    Q0();
                }
                else{
                    Weapon new_weapon = null;
                    switch(ch){
                    case '!':
                        new_weapon = Sword;
                        break;
                    case '@':
                        new_weapon = Mace;
                        break;
                    case '#':
                        new_weapon = Dagger;
                        break;
                    case '$':
                        new_weapon = Staff;
                        break;
                    case '%':
                        new_weapon = Bow;
                        break;
                    }
                    Weapon old_weapon = EquippedWeapon;
                    if(new_weapon == old_weapon){
                        Q0();
                    }
                    else{
                        if(StunnedThisTurn()){
                            break;
                        }
                        Help.displayed[TutorialTopic.SwitchingEquipment] = true;
                        EquippedWeapon = new_weapon;
                        if(HasFeat(FeatType.QUICK_DRAW) && old_weapon != Bow){
                            B.Add("You quickly ready your " + EquippedWeapon + ". ");
                            Q0();
                        }
                        else{
                            if(old_weapon == Bow){
                                B.Add("You put away your bow and ready your " + EquippedWeapon + ". ");
                            }
                            else{
                                B.Add("You ready your " + EquippedWeapon + ". ");
                            }
                            Q1();
                        }
                        //UpdateOnEquip(old_weapon,EquippedWeapon);
                    }
                }
                break;
            }
            case '*': //these are toprow numbers, not shifted versions. see above.
            case '(':
            case ')':
            {
                if(FrozenThisTurn()){
                    break;
                }
                if(EquippedArmor.status[EquipmentStatus.STUCK]){
                    B.Add("Your " + EquippedArmor + " is stuck to your body and can't be removed. ");
                    Q0();
                }
                else{
                    Armor new_armor = null;
                    switch(ch){
                    case '*':
                        new_armor = Leather;
                        break;
                    case '(':
                        new_armor = Chainmail;
                        break;
                    case ')':
                        new_armor = Plate;
                        break;
                    }
                    Armor old_armor = EquippedArmor;
                    if(new_armor == old_armor){
                        Q0();
                    }
                    else{
                        if(StunnedThisTurn()){
                            break;
                        }
                        Help.displayed[TutorialTopic.SwitchingEquipment] = true;
                        EquippedArmor = new_armor;
                        if(TotalProtectionFromArmor() == 0){
                            if(EquippedArmor.status[EquipmentStatus.DAMAGED]){
                                B.Add("You wear your damaged " + EquippedArmor + ". ");
                                B.Add("(It provides no protection until repaired.) ");
                            }
                            else{
                                B.Add("You wear your " + EquippedArmor + ". ");
                                B.Add("You can't wear it effectively in your exhausted state. ");
                            }
                        }
                        else{
                            B.Add("You wear your " + EquippedArmor + ". ");
                        }
                        attrs[AttrType.SWITCHING_ARMOR] = 1;
                        Q1();
                        //UpdateOnEquip(old_weapon,EquippedWeapon);
                    }
                }
                break;
            }
            case 't':
                if(FrozenThisTurn()){
                    break;
                }
                if(StunnedThisTurn()){
                    break;
                }
                if(light_radius==0){
                    if(!M.wiz_dark){
                        B.Add("You bring out your torch. ");
                    }
                    else{
                        B.Add("You bring out your torch, but it gives off no light! ");
                    }
                    int old = LightRadius();
                    light_radius = 6;
                    if(old != LightRadius()){
                        UpdateRadius(old,LightRadius());
                    }
                    if(HasAttr(AttrType.DIM_LIGHT)){
                        CalculateDimming();
                    }
                }
                else{
                    if(!M.wiz_lite){
                        B.Add("You put away your torch. ");
                    }
                    else{
                        B.Add("You put away your torch. The air still shines brightly. ");
                    }
                    int old = LightRadius();
                    if(HasAttr(AttrType.SHINING)){
                        RefreshDuration(AttrType.SHINING,0);
                    }
                    light_radius = 0;
                    if(old != LightRadius()){
                        UpdateRadius(old,LightRadius());
                    }
                    if(HasAttr(AttrType.SHADOW_CLOAK) && !tile().IsLit()){
                        B.Add("You fade away in the darkness. ");
                    }
                }
                Q1();
                break;
            case (char)9:
            {
                GetTarget(true,-1,0,false,false,true,"");
                if(path.Count > 0){
                    if(FrozenThisTurn()){
                        break;
                    }
                    PlayerWalk(DirectionOf(path[0]));
                    if(path.Count > 0){
                        if(DistanceFrom(path[0]) == 0){
                            path.RemoveAt(0);
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case 'm':
            {
                MouseUI.PushButtonMap();
                Screen.CursorVisible = false;
                Tile stairs = M.AllTiles().Where(x=>x.type == TileType.STAIRS && x.seen).RandomOrDefault();
                colorchar cch = Screen.BlankChar();
                if(stairs != null){
                    cch = M.last_seen[stairs.row,stairs.col];
                    M.last_seen[stairs.row,stairs.col] = new colorchar('>',stairs.color);
                }
                Screen.MapDrawWithStrings(M.last_seen,0,0,ROWS,COLS);
                Screen.CursorVisible = true;
                UI.viewing_map_shrine_info = true;
                ChoosePathingDestination(false,false,"Map of dungeon level " + M.current_level + ": ");
                UI.viewing_map_shrine_info = false;
                if(stairs != null){
                    M.last_seen[stairs.row,stairs.col] = cch;
                }
                MouseUI.PopButtonMap();
                M.Redraw();
                if(path.Count > 0){
                    if(FrozenThisTurn()){
                        break;
                    }
                    PlayerWalk(DirectionOf(path[0]));
                    if(path.Count > 0){
                        if(DistanceFrom(path[0]) == 0){
                            path.RemoveAt(0);
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case 'p':
            {
                SharedEffect.ShowPreviousMessages(true);
                Q0();
                break;
            }
            case 'c':
            {
                int feat = UI.DisplayCharacterInfo();
                if(feat >= 0){
                    if(FrozenThisTurn()){ //todo: fix this, once there are things besides feats to use.
                        break;
                    }
                    foreach(FeatType f in feats_in_order){
                        if(Feat.IsActivated(f)){
                            if(feat == 0){
                                M.Redraw();
                                if(StunnedThisTurn()){
                                    break;
                                }
                                if(!UseFeat(f)){
                                    Q0();
                                }
                                break;
                            }
                            else{
                                --feat;
                            }
                        }
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case '\\':
            {
                SharedEffect.ShowKnownItems(Item.identified);
                Q0();
                break;
                /*MouseUI.PushButtonMap();
                List<colorstring> potions = new List<colorstring>();
                List<colorstring> scrolls = new List<colorstring>();
                List<colorstring> orbs = new List<colorstring>();
                foreach(ConsumableType ct in Enum.GetValues(typeof(ConsumableType))){
                    string type_name = "    " + ct.ToString()[0] + ct.ToString().Substring(1).ToLower();
                    type_name = type_name.Replace('_',' ');
                    Color ided_color = Color.Cyan;
                    if(Item.NameOfItemType(ct) == "potion"){
                        if(Item.identified[ct]){
                            potions.Add(new colorstring(type_name,ided_color));
                        }
                        else{
                            potions.Add(new colorstring(type_name,Color.DarkGray));
                        }
                    }
                    else{
                        if(Item.NameOfItemType(ct) == "scroll"){
                            if(Item.identified[ct]){
                                scrolls.Add(new colorstring(type_name,ided_color));
                            }
                            else{
                                scrolls.Add(new colorstring(type_name,Color.DarkGray));
                            }
                        }
                        else{
                            if(Item.NameOfItemType(ct) == "orb"){
                                if(Item.identified[ct]){
                                    orbs.Add(new colorstring(type_name,ided_color));
                                }
                                else{
                                    orbs.Add(new colorstring(type_name,Color.DarkGray));
                                }
                            }
                        }
                    }
                }
                Screen.WriteMapString(0,0,"".PadRight(COLS,'-'));
                for(int i=1;i<ROWS-1;++i){
                    Screen.WriteMapString(i,0,"".PadToMapSize());
                }
                Screen.WriteMapString(ROWS-1,0,"".PadRight(COLS,'-'));
                Color label_color = Color.Yellow;
                Screen.WriteMapString(1,0,"  - Potions -",label_color);
                Screen.WriteMapString(1,33,"  - Scrolls -",label_color);
                int line = 2;
                foreach(colorstring s in potions){
                    Screen.WriteMapString(line,0,s);
                    ++line;
                }
                line = 2;
                foreach(colorstring s in scrolls){
                    Screen.WriteMapString(line,33,s);
                    ++line;
                }
                Screen.WriteMapString(12,0,"  - Orbs -",label_color);
                line = 13;
                foreach(colorstring s in orbs){
                    Screen.WriteMapString(line,0,s);
                    ++line;
                }
                B.DisplayNow("Discovered item types: ");
                Screen.CursorVisible = true;
                Input.ReadKey();
                MouseUI.PopButtonMap();
                Q0();
                break;*/
            }
            case 'O':
            case '=':
            {
                MouseUI.PushButtonMap();
                for(bool done=false;!done;){
                    List<string> ls = new List<string>();
                    ls.Add("Disable wall sliding".PadRight(58) + (Global.Option(OptionType.NO_WALL_SLIDING)? "yes ":"no ").PadLeft(4));
                    ls.Add("Automatically pick up items (if safe)".PadRight(58) + (Global.Option(OptionType.AUTOPICKUP)? "yes ":"no ").PadLeft(4));
                    ls.Add("Hide the path shown by mouse movement".PadRight(58) + (!MouseUI.VisiblePath? "yes ":"no ").PadLeft(4));
                    ls.Add("Use top-row numbers for movement".PadRight(58) + (Global.Option(OptionType.TOP_ROW_MOVEMENT)? "yes ":"no ").PadLeft(4));
                    ls.Add("Ask for confirmation before resting".PadRight(58) + (Global.Option(OptionType.CONFIRM_BEFORE_RESTING)? "yes ":"no ").PadLeft(4));
                    ls.Add("Show out-of-sight areas in dark gray instead".PadRight(58) + (Global.Option(OptionType.DARK_GRAY_UNSEEN)? "yes ":"no ").PadLeft(4));
                    ls.Add("Never show tutorial tips".PadRight(58) + (Global.Option(OptionType.NEVER_DISPLAY_TIPS)? "yes ":"no ").PadLeft(4));
                    ls.Add("Reset tutorial tips before each game".PadRight(58) + (Global.Option(OptionType.ALWAYS_RESET_TIPS)? "yes ":"no ").PadLeft(4));
                    if(Global.LINUX && !Screen.GLMode){
                        ls.Add("Attempt to fix display glitches on certain terminals".PadRight(COLS));
                    }
                    /*if(Screen.GLMode){
                        ls.Add("Disable graphics".PadRight(58) + (Global.Option(OptionType.DISABLE_GRAPHICS)? "yes ":"no ").PadLeft(4));
                    }*/
                    Select("Options: ",ls,true,false,false);
                    Screen.CursorVisible = true;
                    ch = Input.ReadKey().GetCommandChar();
                    switch(ch){
                    case 'a':
                        Global.Options[OptionType.NO_WALL_SLIDING] = !Global.Option(OptionType.NO_WALL_SLIDING);
                        break;
                    case 'b':
                        Global.Options[OptionType.AUTOPICKUP] = !Global.Option(OptionType.AUTOPICKUP);
                        break;
                    case 'c':
                        MouseUI.VisiblePath = !MouseUI.VisiblePath;
                        break;
                    case 'd':
                        Global.Options[OptionType.TOP_ROW_MOVEMENT] = !Global.Option(OptionType.TOP_ROW_MOVEMENT);
                        break;
                    case 'e':
                        Global.Options[OptionType.CONFIRM_BEFORE_RESTING] = !Global.Option(OptionType.CONFIRM_BEFORE_RESTING);
                        break;
                    case 'f':
                        Global.Options[OptionType.DARK_GRAY_UNSEEN] = !Global.Option(OptionType.DARK_GRAY_UNSEEN);
                        M.Draw();
                        if(Screen.GLMode){
                            Screen.UpdateGLBuffer(0,0,Global.SCREEN_H-1,Global.SCREEN_W-1);
                        }
                        break;
                    case 'g':
                        Global.Options[OptionType.NEVER_DISPLAY_TIPS] = !Global.Option(OptionType.NEVER_DISPLAY_TIPS);
                        break;
                    case 'h':
                        Global.Options[OptionType.ALWAYS_RESET_TIPS] = !Global.Option(OptionType.ALWAYS_RESET_TIPS);
                        break;
                    case 'i':
                        if(Global.LINUX && !Screen.GLMode){
                            colorchar[,] screen = Screen.GetCurrentScreen();
                            colorchar cch = new colorchar('@',Color.White);
                            for(int i=0;i<Global.SCREEN_H;++i){
                                for(int j=i%2;j<Global.SCREEN_W;j+=2){
                                    if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){
                                        Screen.WriteChar(i,j,cch);
                                    }
                                }
                            }
                            cch = new colorchar('@',Color.Green);
                            for(int i=0;i<Global.SCREEN_H;++i){
                                Screen.WriteChar(i,0,cch);
                                for(int j=1 + i%2;j<Global.SCREEN_W;j+=2){
                                    if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){
                                        Screen.WriteChar(i,j,cch);
                                    }
                                }
                            }
                            cch = new colorchar('@',Color.Cyan);
                            for(int j=0;j<Global.SCREEN_W;++j){
                                for(int i=0;i<Global.SCREEN_H;++i){
                                    if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){
                                        Screen.WriteChar(i,j,cch);
                                    }
                                }
                            }
                            for(int i=0;i<Global.SCREEN_H;++i){
                                for(int j=0;j<Global.SCREEN_W;++j){
                                    if(i != Global.SCREEN_H-1 || j != Global.SCREEN_W-1){
                                        Screen.WriteChar(i,j,screen[i,j]);
                                    }
                                }
                            }
                        }
                        /*else{
                            if(Screen.GLMode){
                                Global.Options[OptionType.DISABLE_GRAPHICS] = !Global.Option(OptionType.DISABLE_GRAPHICS);
                                GLGame.graphics_surface.Disabled = Global.Option(OptionType.DISABLE_GRAPHICS);
                                Global.GRAPHICAL = !Global.Option(OptionType.DISABLE_GRAPHICS);
                                if(Global.Option(OptionType.DISABLE_GRAPHICS)){
                                    Screen.UpdateCursor(false);
                                }
                                else{
                                    Game.gl.ResizeToDefault();
                                }
                            }
                        }*/
                        break;
                    case (char)27:
                    case ' ':
                    case (char)13:
                        done = true;
                        break;
                    default:
                        break;
                    }
                }
                MouseUI.PopButtonMap();
                Q0();
                break;
            }
            case '?':
            case '/':
            {
                Help.DisplayHelp();
                Q0();
                break;
            }
            case '-':
            {
                MouseUI.PushButtonMap();
                UI.draw_bottom_commands = false;
                UI.darken_status_bar = true;
                Screen.CursorVisible = false;
                List<string> commandhelp = Help.HelpText(HelpTopic.Commands);
                commandhelp.RemoveRange(0,2);
                Screen.WriteMapString(0,0,"".PadRight(COLS,'-'));
                for(int i=0;i<23;++i){
                    Screen.WriteMapString(i+1,0,commandhelp[i].PadRight(COLS));
                }
                Screen.WriteMapString(ROWS+2,0,"".PadRight(COLS,'-'));
                B.DisplayNow("Commands: ");
                Screen.CursorVisible = true;
                Input.ReadKey();
                MouseUI.PopButtonMap();
                UI.draw_bottom_commands = true;
                UI.darken_status_bar = false;
                Q0();
                break;
            }
            case 'q':
            {
                List<string> ls = new List<string>();
                ls.Add("Save your progress and exit to main menu");
                ls.Add("Save your progress and quit game");
                ls.Add("Abandon character and exit to main menu");
                ls.Add("Abandon character and quit game");
                ls.Add("Quit game immediately - don't save anything");
                ls.Add("Continue playing");
                bool no_close = Game.NoClose;
                Game.NoClose = false;
                Screen.CursorVisible = true;
                switch(Select("Quit? ",ls)){
                case 0:
                    Global.GAME_OVER = true;
                    Global.SAVING = true;
                    break;
                case 1:
                    Global.GAME_OVER = true;
                    Global.QUITTING = true;
                    Global.SAVING = true;
                    break;
                case 2:
                    Global.GAME_OVER = true;
                    Global.KILLED_BY = "giving up";
                    break;
                case 3:
                    Global.GAME_OVER = true;
                    Global.QUITTING = true;
                    Global.KILLED_BY = "giving up";
                    break;
                case 4:
                    Global.Quit();
                    break;
                case 5:
                default:
                    break;
                }
                if(!Global.SAVING){
                    Q0();
                }
                Game.NoClose = no_close;
                break;
            }
            case 'v':
            {
                UI.viewing_commands_idx = U.Modulo(UI.viewing_commands_idx + 1,3);
                MouseUI.PopButtonMap();
                MouseUI.PushButtonMap(MouseMode.Map);
                MouseUI.CreateStatsButtons();
                Q0();
                break;
            }
            case '~': //debug mode
            {
                if(false){
                    List<string> l = new List<string>();
                    l.Add("blink");
                    l.Add("create chests");
                    l.Add("gain power");
                    l.Add("spawn monster");
                    l.Add("Forget the map");
                    l.Add("Heal to full");
                    l.Add("Become invulnerable");
                    l.Add("get items!");
                    l.Add("other");
                    l.Add("Use a rune of passage");
                    l.Add("See the entire level");
                    l.Add("Generate new level");
                    l.Add("Create ice or slime");
                    l.Add("Spawn shrines");
                    l.Add("create trap");
                    l.Add("create door");
                    l.Add("spawn lots of goblins and lose neck snap");
                    l.Add("brushfire test");
                    l.Add("detect monsters forever");
                    l.Add("get specific items");
                    switch(Select("Activate which cheat? ",l)){
                    case 0:
                    {
                        //new Item(ConsumableType.DETONATION,"orb of detonation",'*',Color.White).Use(this);
                        new Item(ConsumableType.BLINKING,"orb of detonation",'*',Color.White).Use(this);
                        Q1();
                        break;
                    }
                    case 1:
                    {
                        foreach(Tile t in TilesWithinDistance(3)){
                            t.TransformTo(TileType.CHEST);
                        }
                        Q0();
                        for(int i=0;i<20;++i){
                            Screen.WriteMapString(i,0,Item.GenerateScrollName().ToLower().PadRight(Global.COLS));
                        }
                        foreach(EquipmentStatus st in Enum.GetValues(typeof(EquipmentStatus))){
                            EquippedWeapon.status[st] = true;
                        }
                        Input.ReadKey();
                        /*while(true){
                            var k = Input.ReadKey();
                            B.Add(k.Key.ToString() + "! ");
                            B.Print(true);
                            if(k.Key == ConsoleKey.M){
                                break;
                            }
                        }*/
                        break;
                    }
                    case 2:
                    {
                        /*int[,] row_displacement = GetDiamondSquarePlasmaFractal(ROWS,COLS);
                        int[,] col_displacement = GetDiamondSquarePlasmaFractal(ROWS,COLS);
                        colorchar[,] scr = Screen.GetCurrentMap();
                        M.actor[p] = null;
                        scr[p.row,p.col] = M.VisibleColorChar(p.row,p.col);
                        M.actor[p] = this;
                        int total_rd = 0;
                        int total_cd = 0;
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                total_rd += row_displacement[i,j];
                                total_cd += col_displacement[i,j];
                            }
                        }
                        int avg_rd = total_rd / (ROWS*COLS);
                        int avg_cd = total_cd / (ROWS*COLS);
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                row_displacement[i,j] -= avg_rd;
                                col_displacement[i,j] -= avg_cd;
                            }
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(i == p.row && j == p.col){
                                    Screen.WriteMapChar(i,j,'@',Color.White);
                                }
                                else{
                                    row_displacement[i,j] /= 8;
                                    col_displacement[i,j] /= 8;
                                    if(M.tile.BoundsCheck(i+row_displacement[i,j],j+col_displacement[i,j])){
                                        Screen.WriteMapChar(i,j,scr[i+row_displacement[i,j],j+col_displacement[i,j]]);
                                    }
                                    else{
                                        Screen.WriteMapChar(i,j,Screen.BlankChar());
                                    }
                                }
                            }
                        }
                        Input.ReadKey();

                        var noise = U.GetNoise(17);
                        for(int i=0;i<17;++i){
                            for(int j=0;j<17;++j){
                                char ch2 = '~';
                                if(noise[i,j] > 0.5f){
                                    ch2 = '^';
                                }
                                else{
                                    if(noise[i,j] > 0.1f){
                                        ch2 = '#';
                                    }
                                    else{
                                        if(noise[i,j] > -0.1f){
                                            ch2 = '.';
                                        }
                                        else{
                                            if(noise[i,j] > -0.5f){
                                                ch2 = ',';
                                            }
                                        }
                                    }
                                }
                                Screen.WriteChar(i,j,ch2);
                            }
                            //Screen.WriteMapString(i,0,Global.GenerateCharacterName().PadToMapSize());
                            //Screen.WriteMapString(i,0,Item.RandomItem().ToString().PadToMapSize());
                        }

                        pos p1 = new pos(10,9);
                        pos p1b = new pos(11,9);
                        pos p2 = new pos(10,56);
                        pos p2b = new pos(11,56);
                        int dist = p1.ApproximateEuclideanDistanceFromX10(1,32) + p2.ApproximateEuclideanDistanceFromX10(1,32);
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(p1.ApproximateEuclideanDistanceFromX10(i,j) + p2.ApproximateEuclideanDistanceFromX10(i,j) <= dist
                                || p1b.ApproximateEuclideanDistanceFromX10(i,j) + p2b.ApproximateEuclideanDistanceFromX10(i,j) <= dist){
                                    Screen.WriteMapChar(i,j,'.');
                                }
                                else{
                                    Screen.WriteMapChar(i,j,'#');
                                }
                            }
                        }
                        //Input.ReadKey();
                        //M.InitLevel();
                        //Move(1,1);
                        //List<TileType> tilelist = new List<TileType>{TileType.WALL,TileType.WATER,TileType.VINE,TileType.WAX_WALL,TileType.FLOOR,TileType.BREACHED_WALL,TileType.DOOR_C,TileType.DOOR_O,TileType.CHEST,TileType.STATUE,TileType.FIREPIT,TileType.STALAGMITE,TileType.RUBBLE,TileType.COMBAT_SHRINE,TileType.DEFENSE_SHRINE,TileType.MAGIC_SHRINE,TileType.SPIRIT_SHRINE,TileType.STEALTH_SHRINE,TileType.SPELL_EXCHANGE_SHRINE,TileType.RUINED_SHRINE,TileType.FIRE_GEYSER,TileType.FOG_VENT,TileType.POISON_GAS_VENT,TileType.ICE,TileType.STONE_SLAB,TileType.CHASM,TileType.CRACKED_WALL,TileType.BRUSH,TileType.POPPY_FIELD,TileType.BLAST_FUNGUS,TileType.GLOWING_FUNGUS,TileType.TOMBSTONE,TileType.GRAVE_DIRT,TileType.BARREL,TileType.STANDING_TORCH,TileType.POISON_BULB,TileType.DEMONIC_IDOL,TileType.FIRE_TRAP,TileType.TELEPORT_TRAP,TileType.LIGHT_TRAP,TileType.SLIDING_WALL_TRAP,TileType.GRENADE_TRAP,TileType.SHOCK_TRAP,TileType.ALARM_TRAP,TileType.DARKNESS_TRAP,TileType.POISON_GAS_TRAP,TileType.BLINDING_TRAP,TileType.ICE_TRAP,TileType.PHANTOM_TRAP,TileType.SCALDING_OIL_TRAP,TileType.FLING_TRAP,TileType.STONE_RAIN_TRAP};
                        //List<pos> tileposlist = new List<pos>{new pos(0,0),new pos(4,0),new pos(8,0),new pos(12,0),new pos(0,8),new pos(0,9),new pos(0,10),new pos(2,10),new pos(4,10),new pos(8,10),new pos(12,10),new pos(13,10),new pos(14,10),new pos(0,11),new pos(1,11),new pos(2,11),new pos(3,11),new pos(4,11),new pos(5,11),new pos(6,11),new pos(8,11),new pos(9,11),new pos(10,11),new pos(11,11),new pos(12,11),new pos(14,11),new pos(15,11),new pos(0,12),new pos(4,12),new pos(5,12),new pos(10,12),new pos(12,12),new pos(13,12),new pos(14,12),new pos(15,12),new pos(0,13),new pos(1,13),new pos(0,14),new pos(1,14),new pos(2,14),new pos(3,14),new pos(4,14),new pos(5,14),new pos(6,14),new pos(7,14),new pos(8,14),new pos(9,14),new pos(10,14),new pos(11,14),new pos(12,14),new pos(13,14),new pos(14,14)};

                        int[] intarray = new int[16];
                        intarray[1] = 1;
                        intarray[2] = 1;
                        intarray[5] = -1;
                        intarray[8] = 1;
                        intarray[9] = -1;
                        intarray[10] = 3;

                        Bitmap bmp = new Bitmap("todo_remove.png");
                        Bitmap result;
                        using(var temp = new Bitmap("result_remove.png")){
                            result = new Bitmap(temp);
                        }

                        //Bitmap result = new Bitmap("result_remove.png");
                        //int idx=0;
                        foreach(ConsumableType ct in Enum.GetValues(typeof(ConsumableType))){
                            if(Item.NameOfItemType(ct) == "other"){
                                M.tile[2,2].inv = null;
                                Item.Create(ct,2,2);
                                colorchar cch = M.VisibleColorChar(2,2);
                                int ch_offset = (int)(cch.c) * 16;
                                int pos_col = 48 + (idx % 16);
                                int pos_row = 5 + idx / 16;
                                for(int i=0;i<16;++i){
                                    for(int j=0;j<16;++j){
                                        if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                            System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color);
                                        }
                                        else{
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                        }
                                    }
                                }
                                ++idx;
                            }
                        }

                        attrs[AttrType.DETECTING_MONSTERS] = 1;
                        for(ActorType at = ActorType.GOBLIN;at <= ActorType.DEMON_LORD;at++){
                            if(at != ActorType.MARBLE_HORROR_STATUE && at != ActorType.FINAL_LEVEL_CULTIST){
                                M.actor[2,2] = null;
                                Actor.Create(at,2,2);
                                colorchar cch = M.VisibleColorChar(2,2);
                                int ch_offset = (int)(cch.c) * 16;
                                int pos_col = 32 + (idx % 16);
                                int pos_row = 4 + idx / 16;
                                for(int i=0;i<16;++i){
                                    for(int j=0;j<16;++j){
                                        if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                            System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color);
                                            result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color);
                                        }
                                        else{
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                            result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                        }
                                    }
                                }
                                idx += 2;
                            }
                        }
                        {
                            colorchar cch = M.VisibleColorChar(1,1);
                            int ch_offset = (int)(cch.c) * 16;
                            int pos_col = 32;
                            int pos_row = 0;
                            for(int i=0;i<16;++i){
                                for(int j=0;j<16;++j){
                                    if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                        System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                        result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color);
                                        result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color);
                                    }
                                    else{
                                        result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                        result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                    }
                                }
                            }
                        }
                        for(ActorType at = ActorType.PHANTOM_ZOMBIE;at <= ActorType.PHANTOM_CONSTRICTOR;at++){
                                M.actor[2,2] = null;
                            Actor.CreatePhantom(2,2);
                            if(!M.actor[2,2].Is(at)){
                                at--;
                                continue;
                            }
                                colorchar cch = M.VisibleColorChar(2,2);
                                int ch_offset = (int)(cch.c) * 16;
                                int pos_col = 32 + (idx % 16);
                                int pos_row = 4 + idx / 16;
                                for(int i=0;i<16;++i){
                                    for(int j=0;j<16;++j){
                                        if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                            System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color);
                                            result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,pixel_color);
                                        }
                                        else{
                                            result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                            result.SetPixel(pos_col * 16 + j + 16,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                        }
                                    }
                                }
                                idx += 2;
                        }

                        int diff = 0;
                        foreach(FeatureType ft in Enum.GetValues(typeof(FeatureType))){
                            M.tile[2,2] = null;
                            Tile.Create(TileType.FLOOR,2,2);
                            M.tile[2,2].revealed_by_light = true;
                            M.tile[2,2].AddFeature(ft);
                            colorchar cch = M.VisibleColorChar(2,2);
                            int ch_offset = (int)(cch.c) * 16;
                            int pos_col = 16 + (diff % 16);
                            int pos_row = diff / 16;
                            for(int i=0;i<16;++i){
                                for(int j=0;j<16;++j){
                                    if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                        System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                        result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,pixel_color);
                                    }
                                    else{
                                        result.SetPixel(pos_col * 16 + j,pos_row * 16 + i,System.Drawing.Color.Transparent);
                                    }
                                }
                            }
                            diff += intarray[idx];
                            diff++;
                            ++idx;
                        }

                        foreach(TileType tt in tilelist){
                            M.tile[2,2] = null;
                            pos tilepos = tileposlist[idx];
                            Tile.Create(tt,2,2);
                            M.tile[2,2].revealed_by_light = true;
                            colorchar cch = M.VisibleColorChar(2,2);
                            int ch_offset = (int)(cch.c) * 16;
                            for(int i=0;i<16;++i){
                                for(int j=0;j<16;++j){
                                    if(bmp.GetPixel(ch_offset + j,i).ToArgb() == System.Drawing.Color.Black.ToArgb()){
                                        System.Drawing.Color pixel_color = System.Drawing.Color.FromArgb(Colors.ConvertColor(Colors.ResolveColor(cch.color)).ToArgb());
                                        result.SetPixel(tilepos.row * 16 + j,tilepos.col * 16 + i,pixel_color);
                                    }
                                    else{
                                        result.SetPixel(tilepos.row * 16 + j,tilepos.col * 16 + i,System.Drawing.Color.Black);
                                    }
                                }
                            }
                            ++idx;
                        }*/
                        Q0();
                        maxmp = 99;
                        curmp = maxmp;
                        skills[SkillType.MAGIC] = 10;
                        foreach(SpellType sp in new List<SpellType>{SpellType.TELEKINESIS,SpellType.COLLAPSE,SpellType.FORCE_PALM,SpellType.GREASE,SpellType.AMNESIA,SpellType.FLYING_LEAP}){
                            GainSpell(sp);
                            spells_in_order.Add(sp);
                        }
                        IsHiddenFrom(this);
                        /*M.UpdateSafetyMap(player);
                        var dijk = U.GetDijkstraMap(M.tile,x=>M.tile[x].BlocksConnectivityOfMap(),new List<pos>{this.p});
                        foreach(pos p in M.AllPositions()){
                            int v = M.safetymap[p];
                            colorchar cch = new colorchar(' ',Color.White);
                            if(v == U.DijkstraMin){
                                cch.c = '#';
                            }
                            if(v == U.DijkstraMax){
                                cch.c = '!';
                            }
                            if(v.IsValidDijkstraValue()){
                                v /= 10;
                                cch.c = (char)('z' - v.Modulo(26));
                                cch.color = (Color)(3 - (v+1)/26);
                            }
                            Screen.WriteMapChar(p.row,p.col,cch);
                        }
                        Input.ReadKey();
                        foreach(pos p in M.AllPositions()){
                            int v = M.safetymap[p];
                            colorchar cch = new colorchar(' ',Color.White);
                            if(v == U.DijkstraMin){
                                cch.c = '#';
                            }
                            if(v == U.DijkstraMax){
                                cch.c = '!';
                            }
                            if(v.IsValidDijkstraValue()){
                                v = v/10 + dijk[p];
                                if(v > -2){
                                    cch.c = ':';
                                }
                                else{
                                    cch.c = '.';
                                }
                                cch.c = (char)('z' - v.Modulo(26));
                                cch.color = (Color)(3 - (v+1)/26);
                            }
                            Screen.WriteMapChar(p.row,p.col,cch);
                        }
                        Input.ReadKey();*/
                        break;
                    }
                    case 3:
                    {
                        /*ConsoleKeyInfo command2 = Input.ReadKey();
                        Screen.WriteMapString(14,14,((int)(command2.KeyChar)).ToString());
                        Input.ReadKey();
                        List<Tile> line = GetTarget(-1,-1);
                        if(line != null){
                            Tile t = line.Last();
                            if(t != null){
                                t.AddOpaqueFeature(FeatureType.FOG);
                            }
                        }*/
                        Actor a = M.SpawnMob(ActorType.STALKING_WEBSTRIDER);
                        /*foreach(Actor a in M.AllActors()){
                            if(a.type == ActorType.WARG){
                                a.attrs[AttrType.WANDERING] = 1;
                            }
                        }*/
                        Q0();
                        //M.GenerateFinalLevel();
                        break;
                    }
                    case 4:
                    {
                        Screen.CursorVisible = false;
                        colorchar cch;
                        cch.c = ' ';
                        cch.color = Color.Black;
                        cch.bgcolor = Color.Black;
                        foreach(Tile t in M.AllTiles()){
                            t.seen = false;
                            Screen.WriteMapChar(t.row,t.col,cch);
                        }
                        Screen.CursorVisible = true;
                        Q0();
                        break;
                    }
                    case 5:
                        curhp = maxhp;
                        Q0();
                        break;
                    case 6:
                        if(!HasAttr(AttrType.INVULNERABLE)){
                            attrs[AttrType.INVULNERABLE]++;
                            B.Add("On. ");
                        }
                        else{
                            attrs[AttrType.INVULNERABLE] = 0;
                            B.Add("Off. ");
                        }
                        Q0();
                        break;
                    case 7:
                    {
                        if(InventoryCount() >= Global.MAX_INVENTORY_SIZE){
                            inv = new List<Item>();
                        }
                        while(InventoryCount() < Global.MAX_INVENTORY_SIZE){
                            Item.Create(Item.RandomItem(),this);
                        }
                        foreach(Item i in inv){
                            i.revealed_by_light = true;
                        }
                        Q0();
                        break;
                    }
                    case 8:
                    {
                        //int[,] a = GetBinaryNoise(ROWS,COLS);
                        /*int[,] a = GetDividedNoise(ROWS,COLS,40);
                        int[,] chances = new int[ROWS,COLS];
                        int[,] values = new int[ROWS,COLS];
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                bool passable = (a[i,j] == 1);
                                if(passable){
                                    values[i,j] = -1;
                                }
                                else{
                                    values[i,j] = 0;
                                }
                            }
                        }
                        int minrow = 1;
                        int maxrow = ROWS-2;
                        int mincol = 1;
                        int maxcol = COLS-2;
                        int val = 0;
                        bool done = false;
                        while(!done){
                            done = true;
                            for(int i=minrow;i<=maxrow;++i){
                                for(int j=mincol;j<=maxcol;++j){
                                    if(values[i,j] == val){
                                        for(int s=i-1;s<=i+1;++s){
                                            for(int t=j-1;t<=j+1;++t){
                                                if(values[s,t] == -1){
                                                    values[s,t] = val + 1;
                                                    done = false;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            ++val;
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(a[i,j] == 1){
                                    //distances[i,j] = values[i,j];
                                    int k = 5 + values[i,j];
                                    if(k >= 10){
                                        chances[i,j] = 10;
                                    }
                                    else{
                                        chances[i,j] = k;
                                    }
                                }
                            }
                        }
                        values = new int[ROWS,COLS];
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                bool passable = (a[i,j] == -1);
                                if(passable){
                                    values[i,j] = -1;
                                }
                                else{
                                    values[i,j] = 0;
                                }
                            }
                        }
                        val = 0;
                        done = false;
                        while(!done){
                            done = true;
                            for(int i=minrow;i<=maxrow;++i){
                                for(int j=mincol;j<=maxcol;++j){
                                    if(values[i,j] == val){
                                        for(int s=i-1;s<=i+1;++s){
                                            for(int t=j-1;t<=j+1;++t){
                                                if(values[s,t] == -1){
                                                    values[s,t] = val + 1;
                                                    done = false;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            ++val;
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(a[i,j] == -1){
                                    //distances[i,j] = -(values[i,j]);
                                    int k = 5 + values[i,j];
                                    if(k >= 10){
                                        chances[i,j] = 0;
                                    }
                                    else{
                                        chances[i,j] = 10 - k;
                                    }
                                }
                            }
                        }
                        DungeonGen.StandardDungeon dungeon1 = new DungeonGen.StandardDungeon();
                        char[,] map1 = dungeon1.GenerateStandard();
                        DungeonGen.StandardDungeon dungeon2 = new DungeonGen.StandardDungeon();
                        char[,] map2 = dungeon2.GenerateCave();
                        char[,] map3 = new char[ROWS,COLS];
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(a[i,j] == -1){
                                    map3[i,j] = map1[i,j];
                                }
                                else{
                                    if(a[i,j] == 1){
                                        map3[i,j] = map2[i,j];
                                    }
                                    else{
                                        if(map1[i,j] == '#'){
                                            map3[i,j] = map2[i,j];
                                        }
                                        else{
                                            if(map2[i,j] == '#'){
                                                map3[i,j] = map1[i,j];
                                            }
                                            else{
                                                if(R.CoinFlip()){
                                                    map3[i,j] = map1[i,j];
                                                }
                                                else{
                                                    map3[i,j] = map2[i,j];
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                Screen.WriteMapChar(i,j,map3[i,j]);
                                if(distances[i,j] > -10){
                                    if(distances[i,j] < 10){
                                        if(distances[i,j] < 0){
                                            Screen.WriteMapChar(i,j,(-distances[i,j]).ToString()[0],Color.DarkMagenta);
                                        }
                                        else{
                                            if(distances[i,j] > 0){
                                                Screen.WriteMapChar(i,j,distances[i,j].ToString()[0],Color.DarkCyan);
                                            }
                                            else{
                                                Screen.WriteMapChar(i,j,distances[i,j].ToString()[0],Color.DarkGray);
                                            }
                                        }
                                    }
                                    else{
                                        Screen.WriteMapChar(i,j,'+',Color.DarkCyan);
                                    }
                                }
                                else{
                                    Screen.WriteMapChar(i,j,'-',Color.DarkMagenta);
                                }
                            }
                        }

                        tile().Toggle(null,TileType.BLAST_FUNGUS);

                        List<Tile> area = new List<Tile>();
                        foreach(Tile t in TilesWithinDistance(3).Where(x=>x.passable && HasLOE(x))){
                            t.Toggle(null,TileType.POPPY_FIELD);
                            area.Add(t);
                        }
                        Q.Add(new Event(area,100,EventType.POPPIES));

                        tile().Toggle(null,TileType.TOMBSTONE);
                        Input.ReadKey();

                        List<string> movement = new List<string>{"is immobile","moves quickly","moves slowly"};
                        List<string> ability = new List<string>{"can step back after attacking","moves erratically","flies","can use an aggressive stance","uses a ranged attack","uses a burst attack","lunges","has a poisonous attack","drains life","has a powerful but slow attack","grabs its targets","has a knockback attack","has a slowing attack","has a silencing attack","can steal items","explodes when defeated","stays at range",
                        "sidesteps when it attacks","has a paralyzing attack","has a stunning attack","is stealthy","appears with others of its type","carries a light source","is invisible in darkness","disrupts nearby spells","regenerates","comes back after death","wears armor","has heightened senses","has hard skin that can blunt edged weapons","casts spells","can reduce its target's attack power","can burrow"};
                        List<string> rare_ability = new List<string>{"is attracted to light","is blind in the light","can create illusions of itself","sets itself on fire","throws a bola to slow its targets","dims nearby light sources","screams to terrify its prey","howls to embolden others attacking its prey","breathes poison","is surrounded by a poisonous cloud",
                        "is surrounded by a cloud of fog","can summon a minion","can fill the area with sunlight","is resistant to weapons","can turn into a statue","can throw explosives","can create stalagmites","collapses into rubble when defeated","has a fiery attack","can teleport its foes away","can pull its targets closer from a distance","releases spores when attacked","can absorb light to heal","leaves a trail as it travels","breathes fire","can spit blinding poison","lays volatile eggs","can breach nearby walls","is knocked back by blunt weapons","causes attackers to become exhausted","can create a temporary wall","can throw its foes overhead"};
                        char randomsymbol = (char)((R.Roll(26)-1) + (int)'a');
                        if(R.CoinFlip()){
                            randomsymbol = randomsymbol.ToString().ToUpper()[0];
                        }
                        string s1 = "This monster is a " + Screen.GetColor(Color.RandomAny).ToString().ToLower().Replace("dark","dark ") + " '" + randomsymbol + "'. ";
                        string s2 = "It ";
                        bool add_move = R.OneIn(5);
                        int num_abilities = R.Roll(2) + 1;
                        if(R.OneIn(10)){
                            ++num_abilities;
                        }
                        int total = num_abilities;
                        if(add_move){ ++total; }
                        if(add_move){
                            --total;
                            if(total == 0){
                                s2 = s2 + "and " + movement.Random() + ". ";
                            }
                            else{
                                s2 = s2 + movement.Random() + ", ";
                            }
                        }
                        for(int i=num_abilities;i>0;--i){
                            --total;
                            string a = "";
                            if(R.PercentChance(50)){
                                a = ability.Random();
                            }
                            else{
                                a = rare_ability.Random();
                            }
                            if(!s2.Contains(a)){
                                if(total == 0){
                                    s2 = s2 + "and " + a + ". ";
                                }
                                else{
                                    s2 = s2 + a + ", ";
                                }
                            }
                            else{
                                ++i;
                                ++total;
                            }
                        }

                        if(add_rare){
                            --total;
                            if(total == 0){
                                s2 = s2 + "and " + rare_ability.Random() + ". ";
                            }
                            else{
                                s2 = s2 + rare_ability.Random() + ", ";
                            }
                        }

                        B.Add(s1);
                        B.Add(s2);
                        if(s2.Contains("casts spells")){
                            List<SpellType> all_spells = new List<SpellType>();
                            foreach(SpellType spl in Enum.GetValues(typeof(SpellType))){
                                all_spells.Add(spl);
                            }
                            all_spells.Remove(SpellType.NO_SPELL);
                            all_spells.Remove(SpellType.NUM_SPELLS);
                            string sp = "It can cast ";
                            for(int num_spells = R.Roll(4);num_spells > 0;--num_spells){
                                if(num_spells == 1){
                                    sp = sp + "and " + all_spells.RemoveRandom().ToString().ToLower().Replace('_',' ') + ". ";
                                }
                                else{
                                    sp = sp + all_spells.RemoveRandom().ToString().ToLower().Replace('_',' ') + ", ";
                                }
                            }
                            B.Add(sp);
                        }*/
                        Q0();
                        foreach(Tile t in M.AllTiles()){
                            if(t.passable && DistanceFrom(t) > 4 && R.OneIn(10)){
                                ActorType at = (ActorType)R.Between(3,72);
                                Actor.Create(at,t.row,t.col);
                            }
                        }
                        break;
                    }
                    case 9:
                        new Item(ConsumableType.PASSAGE,"rune of passage",'&',Color.White).Use(this);
                        Q1();
                        break;
                    case 10:
                        foreach(Tile t in M.AllTiles()){
                            t.seen = true;
                            colorchar ch2 = Screen.BlankChar();
                            if(t.IsKnownTrap() || t.IsShrine() || t.Is(TileType.RUINED_SHRINE)){
                                t.revealed_by_light = true;
                            }
                            if(t.inv != null){
                                t.inv.revealed_by_light = true;
                                ch2.c = t.inv.symbol;
                                ch2.color = t.inv.color;
                                M.last_seen[t.row,t.col] = ch2;
                            }
                            else{
                                if(t.features.Count > 0){
                                    ch2 = t.FeatureVisual();
                                    M.last_seen[t.row,t.col] = ch2;
                                }
                                else{
                                    ch2.c = t.symbol;
                                    ch2.color = t.color;
                                    if(ch2.c == '#' && ch2.color == Color.RandomGlowingFungus){
                                        ch2.color = Color.Gray;
                                    }
                                    M.last_seen[t.row,t.col] = ch2;
                                }
                            }
                            Screen.WriteMapChar(t.row,t.col,ch2);
                        }
                        //M.Draw();
                        foreach(Actor a in M.AllActors()){
                            Screen.WriteMapChar(a.row,a.col,new colorchar(a.color,Color.Black,a.symbol));
                        }
                        Input.ReadKey();
                        Q0();
                        break;
                    case 11:
                        for(int i=0;i<1;++i){
                            if(M.current_level < 20){
                                //M.level_types[M.current_level] = LevelType.Standard;
                            }
                            M.GenerateLevel();
                            /*foreach(Tile t in M.AllTiles()){
                                if(t.TilesWithinDistance(1).Any(x=>x.type != TileType.WALL)){
                                    t.seen = true;
                                }
                            }
                            B.Print(false);
                            M.Draw();*/
                        }
                        Q0();
                        break;
                    case 12:
                    {
                        /*PosArray<int> map = new PosArray<int>(ROWS,COLS);
                        pos center = new pos(ROWS/2,COLS/2);
                        int n = 2;
                        foreach(pos p in center.PositionsWithinDistance(n-1)){
                            map[p] = 1;
                        }
                        bool changed = true;
                        while(changed){
                            changed = false;
                            List<pos> list = center.PositionsAtDistance(n);
                            while(list.Count > 0){
                                pos p = list.RemoveRandom();
                                int count = p.PositionsAtDistance(1).Where(x=>map[x] == 1).Count;
                                if(R.PercentChance(count*25)){ //this number can be anywhere from ~19 to 25
                                    map[p] = 1;
                                    changed = true;
                                }
                            }
                            ++n;
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                //pos p = new pos(i,j);
                                //if(p.PositionsWithinDistance(1).Where(x=>map[x] == 1).Count >= 5){
                                if(map[i,j] == 1){
                                    Screen.WriteMapChar(i,j,'.',Color.Green);
                                }
                                else{
                                    Screen.WriteMapChar(i,j,'~',Color.Blue);
                                }
                            }
                        }
                        Input.ReadKey();
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                pos p = new pos(i,j);
                                if(p.PositionsWithinDistance(1).Where(x=>map[x] == 1).Count >= 5){
                                //if(map[i,j] == 1){
                                    Screen.WriteMapChar(i,j,'.',Color.Green);
                                }
                                else{
                                    Screen.WriteMapChar(i,j,'~',Color.Blue);
                                }
                            }
                        }
                        Input.ReadKey();

                        level = 10;
                        skills[SkillType.COMBAT] = 10;
                        skills[SkillType.DEFENSE] = 10;
                        skills[SkillType.MAGIC] = 10;
                        skills[SkillType.SPIRIT] = 10;
                        skills[SkillType.STEALTH] = 10;
                        foreach(FeatType f in Enum.GetValues(typeof(FeatType))){
                            if(f != FeatType.NO_FEAT && f != FeatType.NUM_FEATS){
                                feats[f] = true;
                            }
                        }

                        foreach(Tile t in M.AllTiles()){
                            if(t.type == TileType.FLOOR){
                                if(R.CoinFlip()){
                                    t.Toggle(null,TileType.STONE_RAIN_TRAP);
                                }
                                else{
                                    t.Toggle(null,TileType.FLING_TRAP);
                                }
                            }
                        }
                        for(int i=0;i<10;++i){
                            M.SpawnMob(ActorType.FROSTLING);
                        }*/
                        Q0();
                        RefreshDuration(AttrType.ENRAGED,1500);
                        break;
                    }
                    case 13:
                    {
                        //LevelUp();
                            foreach(Tile t in TilesWithinDistance(2)){
                                t.TransformTo((TileType)(R.Between(0,4)+(int)TileType.COMBAT_SHRINE));
                            }
                        Q0();
                        break;
                    }
                    case 14:
                    {
                        foreach(Tile t in TilesAtDistance(1)){
                            t.TransformTo(Tile.RandomTrap());
                        }
                        Q0();
                        break;
                    }
                    case 15:
                    {
                            List<Tile> line = GetTargetTile(-1,0,false,false);
                            if(line != null){
                                Tile t = line.LastOrDefault();
                                if(t != null){
                                    //t.TransformTo(TileType.DOOR_O);
                                if(t.Is(FeatureType.FIRE)){
                                    t.RemoveFeature(FeatureType.FIRE);
                                    t.Toggle(null,TileType.DEMONIC_IDOL);
                                }
                                else{
                                t.AddFeature(FeatureType.FIRE);
                                }
                                }
                            }
                        Q0();
                        break;
                    }
                    case 16:
                    {
                        for(int i=0;i<100;++i){
                            M.SpawnMob(ActorType.GOBLIN);
                        }
                        if(HasFeat(FeatType.NECK_SNAP)){
                            feats[FeatType.NECK_SNAP] = false;
                        }
                        Q0();
                        break;
                    }
                    case 17:
                    {
                        /*List<Tile> list = new List<Tile>();
                        while(list.Count < 15){
                            int rr = R.Roll(ROWS-2);
                            int rc = R.Roll(COLS-2);
                            if(M.tile[rr,rc].passable){
                                list.AddUnique(M.tile[rr,rc]);
                            }
                        }
                        for(int i=0;i<ROWS;++i){
                            for(int j=0;j<COLS;++j){
                                if(M.tile[i,j].passable){
                                    List<Tile> closest_tiles = list.WhereLeast(x => x.ApproximateEuclideanDistanceFromX10(i,j));
                                    //List<Tile> closest_tiles = list.WhereLeast(x => new Actor(this,i,j).GetPath(x.row,x.col).Count);
                                    if(closest_tiles.Count == 2){
                                        Screen.WriteMapChar(i,j,'=',Color.White);
                                    }
                                    else{
                                        int idx = list.IndexOf(closest_tiles[0]);
                                        Screen.WriteMapChar(i,j,M.tile[i,j].symbol,(Color)(idx+3));
                                    }
                                }
                                else{
                                    if(!M.tile[i,j].solid_rock){
                                        Screen.WriteMapChar(i,j,M.tile[i,j].symbol,M.tile[i,j].color);
                                    }
                                    else{
                                        Screen.WriteMapChar(i,j,Screen.BlankChar());
                                    }
                                }
                            }
                        }

                        Screen.Blank();
                        Tile[] prev = new Tile[20];
                        int idx = 0;
                        foreach(Tile t in M.ReachableTilesByDistance(row,col,false,TileType.DOOR_C)){
                            Screen.WriteMapChar(t.row,t.col,t.symbol,t.color);
                            prev[idx] = t;
                            idx = (idx + 1) % 20;
                            if(prev[idx] != null){
                                Screen.WriteMapChar(prev[idx].row,prev[idx].col,Screen.BlankChar());
                            }
                            Thread.Sleep(10);
                        }*/
                        foreach(Actor a in M.AllActors()){
                            if(a != this){
                                a.Kill();
                            }
                        }
                        UpdateRadius(LightRadius(),0);
                        for(int i=1;i<ROWS-1;++i){
                            for(int j=1;j<COLS-1;++j){
                                M.tile[i,j] = null;
                                Tile.Create(TileType.BRUSH,i,j);
                            }
                        }
                        UpdateRadius(0,LightRadius());
                        foreach(Tile t in M.AllTiles()){
                            if(t.TilesWithinDistance(1).Any(x=>x.type != TileType.WALL)){
                                t.seen = true;
                            }
                        }
                        Q.KillEvents(null,EventType.CHECK_FOR_HIDDEN);
                        M.wiz_lite = true;
                        M.wiz_dark = false;
                        B.Print(false);
                        M.Draw();
                        Q0();
                        break;
                    }
                    case 18:
                    {
                        if(attrs[AttrType.DETECTING_MONSTERS] == 0){
                            attrs[AttrType.DETECTING_MONSTERS] = 1;
                        }
                        else{
                            attrs[AttrType.DETECTING_MONSTERS] = 0;
                        }
                        Q0();
                        break;
                    }
                    case 19:
                    {
                        /*List<Tile> line = GetTargetTile(-1,0,false);
                        if(line != null){
                            Tile t = line.Last();
                            if(t != null){
                                t.Toggle(null,TileType.CHASM);
                                Q.Add(new Event(t,100,EventType.FLOOR_COLLAPSE));
                                B.Add("The floor begins to collapse! ");
                            }
                        }*/
                        if(tile().inv == null){
                            tile().inv = Item.Create(ConsumableType.ENCHANTMENT,row,col);
                            //TileInDirection(8).inv = Item.Create(ConsumableType.FLAMES,-1,-1);
                            B.Add("You feel something roll beneath your feet. ");
                            //magic_trinkets.Add(MagicTrinketType.PENDANT_OF_LIFE);
                        }
                        Q0();
                        break;
                    }
                    default:
                        Q0();
                        break;
                    }
                }
                else{
                    Q0();
                }
                break;
            }
            case ' ':
                Q0();
                break;
            default:
                B.Add("Press '?' for help. ");
                Q0();
                break;
            }
            if(ch != 'x'){
                attrs[AttrType.AUTOEXPLORE] = 0;
            }
        }
		public FilesPageModel()
		{
            filesSource = new FileSystemCollectionSource();
            Files = new VirtualCollection<FileSystemModel>(filesSource, DefaultPageSize, DefaultCacheSize);
            SelectedFile = new Observable<VirtualItem<FileSystemModel>>();
            CurrentFolder = new Observable<string>() { Value = "/"};
            CurrentFolder.PropertyChanged += delegate
                                                 {
                                                     filesSource.CurrentFolder = CurrentFolder.Value;
                                                     UpdateBreadCrumbs();
                                                     ApplicationModel.Current.Client.Notifications.FolderChanges(
                                                         CurrentFolder.Value)
                                                         .TakeUntil(Unloaded.Amb(CurrentFolder.ObserveChanged().Select(_ => Unit.Default)))
                                                         .SampleResponsive(TimeSpan.FromSeconds(1))
                                                         .ObserveOn(DispatcherScheduler.Instance)
                                                         .Subscribe(_ => Files.Refresh(RefreshMode.PermitStaleDataWhilstRefreshing));
                                                 };

            SearchPattern = new Observable<string>() { Value=""};
		    SearchPattern.ObserveChanged().Throttle(TimeSpan.FromSeconds(1)).Where(SearchPatternIsValid).Subscribe(value => filesSource.SearchPattern = value);
            SelectedItems = new ItemSelection<VirtualItem<FileSystemModel>>();

            IsSearchVisible = new Observable<bool>();

            BreadcrumbTrail = new ObservableCollection<DirectoryModel>();
		}
 public ItemSelection SelectItem(string message,bool never_redraw_map)
 {
     MouseUI.PushButtonMap();
     MouseUI.AutomaticButtonsFromStrings = true;
     colorstring top_border = "".PadRight(COLS,'-').GetColorString();
     colorstring bottom_border = ("------Space left: " + (Global.MAX_INVENTORY_SIZE - InventoryCount()).ToString().PadRight(7,'-') + "[?] for help").PadRight(COLS,'-').GetColorString();
     List<colorstring> strings = InventoryList().GetColorStrings();
     bool no_ask = false;
     bool no_cancel = false;
     bool easy_cancel = true;
     bool help_key = true;
     HelpTopic help_topic = HelpTopic.Items;
     ItemSelection result = new ItemSelection();
     result.value = -2;
     while(result.value == -2){ //this part is hacked together from Select()
         Screen.WriteMapString(0,0,top_border);
         char letter = 'a';
         int i=1;
         foreach(colorstring s in strings){
             Screen.WriteMapString(i,0,new colorstring("[",Color.Gray,letter.ToString(),Color.Cyan,"] ",Color.Gray));
             Screen.WriteMapString(i,4,s);
             if(s.Length() < COLS-4){
                 Screen.WriteMapString(i,s.Length()+4,"".PadRight(COLS - (s.Length()+4)));
             }
             letter++;
             i++;
         }
         Screen.WriteMapString(i,0,bottom_border);
         if(i < ROWS-1){
             Screen.WriteMapString(i+1,0,"".PadRight(COLS));
         }
         if(no_ask){
             B.DisplayNow(message);
             result.value = -1;
             MouseUI.PopButtonMap();
             MouseUI.AutomaticButtonsFromStrings = false;
             return result;
         }
         else{
             result = GetItemSelection(message,strings.Count,no_cancel,easy_cancel,help_key);
             if(result.value == -2){
                 MouseUI.AutomaticButtonsFromStrings = false;
                 Help.DisplayHelp(help_topic);
                 MouseUI.AutomaticButtonsFromStrings = true;
             }
             else{
                 if(!never_redraw_map && result.value != -1 && !result.description_requested){
                     M.Redraw();
                 }
                 MouseUI.PopButtonMap();
                 MouseUI.AutomaticButtonsFromStrings = false;
                 return result;
             }
         }
     }
     result.value = -1;
     MouseUI.PopButtonMap();
     MouseUI.AutomaticButtonsFromStrings = false;
     return result;
 }
 public ItemSelection GetItemSelection(string s,int count,bool no_cancel,bool easy_cancel,bool help_key)
 {
     ItemSelection result = new ItemSelection();
     B.DisplayNow(s);
     Screen.CursorVisible = true;
     ConsoleKeyInfo command;
     char ch;
     while(true){
         command = Input.ReadKey();
         ch = command.GetCommandChar();
         int i = ch - 'a';
         if(i >= 0 && i < count){
             result.value = i;
             return result;
         }
         if(help_key && ch == '?'){
             result.value = -2;
             return result;
         }
         int j = Char.ToLower(ch) - 'a';
         if(j >= 0 && j < count){
             result.value = j;
             result.description_requested = true;
             return result;
         }
         if(no_cancel == false){
             if(easy_cancel){
                 result.value = -1;
                 return result;
             }
             if(ch == (char)27 || ch == ' '){
                 result.value = -1;
                 return result;
             }
         }
         if(count == 0){
             result.value = -1;
             return result;
         }
     }
 }