/// <summary> /// Adds /// /// ASSUMPTIONS /// 1. Last row contains the Highest number (the die roll) /// </summary> /// <param name="nModifier">Some tables influence the value of the next table. Generally this should be 0</param> /// public static resultReturn GenerateResult(int nModifier, DataTable currentTable, ref string nextTable, string Title, NoteDataInterface[] notes, bool useHeadingStyle) { resultReturn returner = new resultReturn(); returner.nModifier = 0; returner.sResult = Constants.BLANK; // error checking // if result column does not exist if (currentTable.Columns.IndexOf(TableWrapper.Result) == -1 || currentTable.Columns.IndexOf(TableWrapper.Roll) == -1) { NewMessage.Show(String.Format(TableWrapper.ColumnDoesNotExist, "result or roll")); return(returner); } myRange[] ranges = new myRange[currentTable.Rows.Count]; // this is complicated. // I need to break each range apart into its components numbers // and do validity checking on it. // make the validity tests micro enough to use elsewhere // in case I need an authenticator int nFoundRowNumber = 0; int nValue = 0; int nMin = 0; int nMax = 0; if (currentTable.Rows.Count > 0) { if (currentTable.Rows [0] [0].ToString() == "-1") { // This is a linear table // Linear tables go through a checklist, one table after another. // RULES: // // - A result is taken (generally flat values or lookup results) and then we go to the next row // - If a result results in a next_table that is TAKEN, breaking the linear table // - to navigate we set Nexttable to the next row number but with a MINUS preceding it if (nextTable.Length > 0 && nextTable [0] == '-') { nFoundRowNumber = Math.Abs(Int32.Parse(nextTable)); } else { nFoundRowNumber = 0; } } else { // fill in ranges values ranges = TableWrapper.BuildRangeArray(ranges, currentTable); if (ranges == null) { return(returner); } // find maximum value in last row nMin = ranges [0].nMin; nMax = ranges [ranges.Length - 1].nMax; // roll the die Random r = LayoutDetails.Instance.RandomNumbers; nValue = nModifier + r.Next(nMin, nMax + 1); // if the value, with modifier, is now greater than the max, then set it to max if (nValue > nMax) { nValue = nMax; } // Go through each row and test to see if the number fits within the range for (int j = 0; j < ranges.Length; j++) { // am I greater than or equal to min value? if (nValue >= ranges [j].nMin) { // am I less than or equal to max value for this row if (nValue <= ranges [j].nMax) { nFoundRowNumber = j; } } } } // random lookup // we override the NExtTable result if there is a valid valu try { if (currentTable.Columns.IndexOf(TableWrapper.NextTable) > -1) { if (!Convert.IsDBNull(currentTable.Rows [nFoundRowNumber] [TableWrapper.NextTable])) { string sNext = currentTable.Rows [nFoundRowNumber] [TableWrapper.NextTable].ToString(); if (sNext != null && sNext != Constants.BLANK) { nextTable = sNext; } } else if (nextTable.Length > 1 && nextTable [0] == '-') { // a linear table // to keep from falling into an infinite loop we need to drop out nextTable = ""; } } } catch (Exception ex) { NewMessage.Show(ex.ToString()); } if (currentTable.Columns.IndexOf(TableWrapper.Modifier) > -1) { if (currentTable.Rows [nFoundRowNumber] [TableWrapper.Modifier] == null) { returner.nModifier = 0; } else { try { returner.nModifier = (int)Int32.Parse(currentTable.Rows [nFoundRowNumber] [TableWrapper.Modifier].ToString()); } catch (Exception) { returner.nModifier = 0; } } } else { returner.nModifier = 0; } string sDebugOnly = Constants.BLANK; // if (DebugMode == true) // { // sDebugOnly = "Modifier = " + nModifier.ToString() + " Roll =" + nValue.ToString() + "/" + nMin.ToString() + "-" + nMax.ToString() + " ::: "; // } string sResult = currentTable.Rows [nFoundRowNumber] [TableWrapper.Result].ToString(); if (sResult.ToLower().IndexOf("lookup") > -1) { // NewMessage.Show("lookup found"); sResult = lookup(sResult, currentTable, notes, useHeadingStyle); } string sTitle = sDebugOnly + Title + " "; if (sTitle == " ") { sTitle = ""; // get rid of space if there was no title } returner.sResult = sTitle + sResult + Environment.NewLine; } return(returner); }
/// <summary> /// will go through each "next" table from the source one /// the calling object /// and generateresults /// /// /// /// /// </summary> /// <returns></returns> public static string GenerateAllResults(ref string nextTable, DataTable currentTable, string Title, string Core_Table, LayoutPanelBase Layout, bool useHeadingStyle) { // probably should save first too but not sure // how to integrate that string sOriginalNextTable = nextTable; if (null == Layout) { throw new Exception("You must have a valid Layout loaded when doing a random table traversal."); } // do first table System.Collections.ArrayList notelist = Layout.GetAllNotes(); NoteDataInterface[] notes = new NoteDataInterface[notelist.Count]; notelist.CopyTo(notes); resultReturn sResult = GenerateResult(0, currentTable, ref nextTable, Title, notes, useHeadingStyle); // now, if there are more tables //classPageTable tables = this; if (sResult.sResult == " \n") { sResult.sResult = Constants.BLANK; } while (nextTable != null && nextTable != Constants.BLANK) { // looks for the note called start NoteDataXML_Table table = null; bool LINEAR_MODE = false; if (nextTable[0] == '-') { // Linear table system. // a -X (any number, with a minus preceding it) represents a row // basically we want to stay on the current table but go to the next row table = (NoteDataXML_Table)Layout.FindNoteByName(Core_Table); LINEAR_MODE = true; } else { // Grab the next table NoteDataInterface potentialTable = Layout.FindNoteByName(nextTable); if (potentialTable is NoteDataXML_Table) { table = (NoteDataXML_Table)potentialTable; // sep 28 2011 // linear table system // if we encounter a 'real table' reference that means // to set the Core Table to that Core_Table = nextTable; } } //NotePanelTable table = (NotePanelTable)desktop.GetPanelByName(nextTable); resultReturn newResult; if (table != null) { string old_next_table = nextTable; string _caption = ""; // table.Caption; if (table.TableCaption != "") { _caption = table.TableCaption; } // see note A below for why we have this check if (LINEAR_MODE == true && table.NextTable == "") { // leave nextable alone in Lienar mode // needed for when we call a linear table from another table (instead of calling the linear table directly) } else { nextTable = table.NextTable; // this is clearing the row field! } newResult = GenerateResult(sResult.nModifier, (DataTable)table.dataSource, ref nextTable, _caption, notes, useHeadingStyle); /* NOTE A September 28 2011 * There is a WEIRD pointer thing happening and working in my favor * Basically because AppearanceClass.NextTable is passed as a ref into GenerateAllResults it is modified directly * when we set Generate the next result * basically we continue to setting this value (not sure why the breakpoint never succeeded though) * * So... I don't want to mess everything, so if we are in LINEAR mode then we * manualy set the table. */ // if (nextTable == old_next_table) //{ // nextTable = Header.Blank; // } // nextTable = table.NextTable; if (newResult.sResult == " \n") { newResult.sResult = Constants.BLANK; } sResult.sResult = sResult.sResult + newResult.sResult; sResult.nModifier = newResult.nModifier; } else { // if we hit a null then we hit user error // abort nextTable = Constants.BLANK; } } nextTable = sOriginalNextTable; return(sResult.sResult); }