/// <summary> /// Generate a RollableTable from an array of strings /// </summary> /// <param name="tableName"></param> /// <param name="dieRoll"></param> /// <param name="list"></param> /// <returns></returns> public static RollableTable FromList(string tableName, DieRoll dieRoll, string[] list) { if (tableName == null || dieRoll == null || list == null) { return(null); } //RollableTable table = new RollableTable(tableName); //table.Dice = dieRoll; //char[] comma = {','}; //char[] blank = {' '}; //foreach (string listMember in list) //{ // RollableTableRow row = table.GetNewRow(); //} RollableTable table; if (TryParse(list, out table)) { return(table); } return(null); }
/// <summary> /// Resolves the ItemRoll to a GameObject by performing a die roll /// </summary> /// <returns></returns> public IResolver Resolve() { string name = String.Empty; if (Item is GameObject) { name = ((GameObject)Item).Name; } else if (Item is GameObjectInstance) { name = ((GameObjectInstance)Item).Item.Name; } Logger.Write("Resolve ItemRoll: " + Item.ToString() + ", " + Dice.ToString() + " " + " x" + Multiplier + " (" + Percent + "%)"); DieRoll percentRoll = new DieRoll(1, 100, 0); int percent = percentRoll.Roll(); Logger.Write("... rolled " + percentRoll.ToString() + ": " + percent.ToString() + "%" + ((percent <= Percent) ? "" : " NO ROLL")); if (percent <= Percent) { return(Roll()); } else { return(null); } }
/// <summary> /// Perform a die roll from die roll stats /// </summary> /// <param name="dice"></param> /// <param name="sides"></param> /// <param name="modifier"></param> /// <param name="keep"></param> /// <returns></returns> public static int Roll(int dice, int sides, int modifier, int keep) { DieRoll dr = new DieRoll(dice, sides, modifier); dr.Keep = keep; return(dr.Roll()); }
/// <summary> /// Constructor /// </summary> /// <param name="item"></param> /// <param name="dice"></param> /// <param name="multiplier"></param> /// <param name="percent"></param> public ItemRoll(IResolver item, DieRoll dice, int multiplier, int percent) { Item = item; Dice = dice; Multiplier = multiplier; Percent = percent; IsGrouped = true; }
public RollableTable(string tableName) { TableName = tableName; Dice = RollableTable.DefaultDieRoll(); Columns.Add(new DataColumn("LowRoll", typeof(int))); Columns.Add(new DataColumn("HighRoll", typeof(int))); Columns.Add(new DataColumn("RangeText", typeof(string))); Columns.Add(new DataColumn("Item", typeof(IResolver))); }
private void DieRollWriteXml(DieRoll obj) { writer.WriteStartElement("DieRoll"); Utility.WriteAttribute(writer, "Dice", obj.Dice, 1); Utility.WriteAttribute(writer, "Sides", obj.Sides, 20); Utility.WriteAttribute(writer, "Modifier", obj.Modifier, 0); Utility.WriteAttribute(writer, "Keep", obj.Keep, obj.Dice); writer.WriteEndElement(); }
private DieRoll DieRollFromXml(XmlNode node) { DieRoll obj = new DieRoll(); obj.Dice = Utility.ParseAttribute(node, "Dice", 1); obj.Sides = Utility.ParseAttribute(node, "Sides", 20); obj.Modifier = Utility.ParseAttribute(node, "Modifier", 0); obj.Keep = Utility.ParseAttribute(node, "Keep", obj.Dice); return(obj); }
/// <summary> /// Performs a die roll to generate one or more IResolvers from Item /// </summary> /// <returns></returns> public IResolver Roll() { //GameObjectInstance result = new GameObjectInstance(Item, Dice.Roll() * Multiplier); if (Item is GameObject) { GameObjectInstance item = new GameObjectInstance((GameObject)Item, Dice.Roll() * Multiplier); Logger.Write("... rolled " + item.ToString()); return(item); } else if (Item is TableRoll && IsGrouped) { // Number of dice in Dice determines number of TableRolls performed. // Dice rolled with a single die determines number of occurrences of each TableRoll results. // e.g. if Dice = 4d10+2, 4 TableRolls are performed, and d10+2 is rolled to determine number of occurrences of each result. TableRoll t = (TableRoll)Item; Logger.Write("... performing " + Dice.Dice.ToString() + " rolls on " + t.Table.TableName); ItemList list = new ItemList(); DieRoll singleRoll = new DieRoll(1, Dice.Sides, Dice.Modifier); for (int i = 0; i < Dice.Dice; i++) { IResolver item = Item.Resolve(); if (item != null) { int count = singleRoll.Roll(); Logger.Write("... occurring " + count + " times"); for (int j = 0; j < count; j++) { list.Add(item); } } } return(list); } else { ItemList list = new ItemList(); int count = Dice.Roll() * Multiplier; Logger.Write("... rolled " + Dice.ToString() + ": " + count.ToString()); for (int i = 0; i < count; i++) { list.Add(Item.Resolve()); } return(list); } }
public IResolver Roll(int ignoreBelow, int ignoreAbove) { DieRoll dice = new DieRoll(1, this.Count, 0); int roll = -1; int attempts = 0; while (attempts <= Constants.MaxRollAttempts && (roll < ignoreBelow || roll > ignoreAbove)) { roll = dice.Roll(); attempts++; } IResolver result = this[roll]; return(result.Resolve()); }
/// <summary> /// Return a resolved, randomly selected item from the list /// </summary> /// <param name="ignoreBelow"></param> /// <param name="ignoreAbove"></param> /// <returns></returns> public IResolver Roll(int ignoreBelow, int ignoreAbove) { DieRoll dice = new DieRoll(1, _list.Count, 0); int roll = -1; int attempts = 0; while (attempts <= Constants.MaxRollAttempts && (roll < ignoreBelow || roll > ignoreAbove)) { roll = dice.Roll(); attempts++; } Dictionary <string, IResolver> .Enumerator en = _list.GetEnumerator(); for (int i = 0; i < roll; i++) { en.MoveNext(); } string key = en.Current.Key; return(this.Resolve(key)); }
/// <summary> /// Convert a text string to an IResolver /// </summary> /// <param name="itemText"></param> /// <returns></returns> public static IResolver ParseItem(string itemText) { char[] comma = { ',' }; char[] blank = { ' ' }; // if the item is a comma-separated list, parse it as an ItemList string[] items = itemText.Split(comma, StringSplitOptions.RemoveEmptyEntries); if (items.Length > 1) { ItemList itemList = new ItemList(); foreach (string item in items) { IResolver obj = ParseItem(item); if (obj != null) { itemList.Add(obj); } } return(itemList); } // parse an individual item else if (items.Length == 1) { DieRoll dieRoll; GameObject gameObject; string item = items[0]; // ItemRoll string[] tokens = item.Split(blank, StringSplitOptions.RemoveEmptyEntries); if (DieRoll.TryParse(tokens[0], out dieRoll)) { string theRest = item.Substring(tokens[0].Length).Trim(); if (GameObject.TryParse(theRest, out gameObject)) { return(new ItemRoll(gameObject, dieRoll)); } } // GameObjectInstance GameObjectInstance gameObjectInstance; if (GameObjectInstance.TryParse(item, out gameObjectInstance)) { return(gameObjectInstance); } // TableRoll if (item.ToLower().StartsWith("roll")) { TableRoll tableRoll; if (TableRoll.TryParse(item.Remove(0, 5), out tableRoll)) { return(tableRoll); } } // GameObject if (GameObject.TryParse(item, out gameObject)) { return(gameObject); } } return(null); }
public static bool TryParse(string st, out TableRoll outTableRoll) { outTableRoll = new TableRoll(); char[] blank = { ' ' }; string[] words = st.ToLower().Split(blank, StringSplitOptions.RemoveEmptyEntries); int i = 0; int rolls = 1; DieRoll dieRoll = null; if (words[i] == "once") { i++; } else if (words[i] == "twice") { i++; rolls = 2; } else if (int.TryParse(words[i], out rolls)) { i++; } else if (DieRoll.TryParse(words[i], out dieRoll)) { i++; } if (words[i] == "times") { i++; } if (words[i] == "on") { i++; } // get the RollableTable name enclosed in double quotes string remainder = String.Join(" ", words, words.Length - i); Regex regex = new Regex("\"([^\"]*)\""); Match match = regex.Match(remainder); if (match.Success) { int ignoreBelow = 0; int ignoreAbove = int.MaxValue; // scan for ignore options remainder.Remove(0, match.Length); words = remainder.Split(blank, StringSplitOptions.RemoveEmptyEntries); i = 0; if (words[i] == "ignoring" && words[i] == "ignore") { i++; if (words[i] == "results") { i++; } switch (words[i]) { case "above": case ">": case "greater": i++; if (words[i] == "than") { i++; } if (!int.TryParse(words[i], out ignoreAbove)) { return(false); } break; case "below": case "<": case "less": i++; if (words[i] == "than") { i++; } if (!int.TryParse(words[i], out ignoreBelow)) { return(false); } break; } } outTableRoll.Table = Repository.GetTable(match.Value); outTableRoll.Rolls = rolls; outTableRoll.IgnoreAbove = ignoreAbove; outTableRoll.IgnoreBelow = ignoreBelow; } return(true); }
public ItemRoll(IResolver item, DieRoll dice) : this(item, dice, 1) { }
public ItemRoll(IResolver item, DieRoll dice, int multiplier) : this(item, dice, multiplier, 100) { }
/// <summary> /// Perform a die roll from a string such as "3d8+1" /// </summary> /// <param name="dieRollString"></param> /// <returns></returns> public static int Roll(string dieRollString) { DieRoll dieRoll = DieRoll.FromString(dieRollString); return(dieRoll.Roll()); }
/// <summary> /// Attempt to parse a die roll string, returning true if successful. /// </summary> /// <param name="dieRollString"></param> /// <param name="dieRoll"></param> /// <returns></returns> public static bool TryParse(string dieRollString, out DieRoll dieRoll) { // 10/19/2011 - ideas for new ultimate syntax: // 3/4d6+1:8/10 = roll 4d6, keep best 3, add 1; do this 10 times and return best 8. // At least one of [dice, sides or modifier] must be a positive integer. // If dice=0 or sides=0 then the modifier must be a positive int; in that case Roll will always return the modifier as the result. // If keep is used it must be greater than 0. int dice = 0; int sides = 0; int modifier = 0; int keep = 0; dieRoll = null; // strip out blanks string st = dieRollString.Replace(" ", String.Empty).ToLower(); // a dieRoll can be a numeric constant - in this case make it the modifier and we're done if (int.TryParse(st, out modifier)) { dieRoll = new DieRoll(dice, sides, modifier, keep); return(modifier > 0); } // get the number of dice int dPos = st.IndexOf("d"); if (dPos < 0) { return(false); } else { if (!int.TryParse(st.Substring(0, dPos), out dice)) { dice = 1; } } // parse and strip off the keep value if present int iKeep = st.IndexOf(":"); if (iKeep >= 0) { if (!int.TryParse(st.Substring(iKeep + 1), out keep)) { return(false); } st = st.Remove(iKeep); } // default keep to # of dice if not explicitly and correctly set if (keep == 0) { keep = dice; } // get the modifier by parsing everything after +/- char[] signs = { '+', '-' }; int sign = st.IndexOfAny(signs); if (sign < 0) { modifier = 0; } else { // either there is a sign (so there is a modifier) or there is no "d" (so if there is only a fixed value it becomes the modifier) if (!int.TryParse(st.Substring(sign), out modifier)) { return(false); } } // get the number of sides if there are dice (dice=0 indicates a fixed value roll) if (dice > 0) { // get the sides by parsing everything between "d" and the sign, or everything after "d" if there is no sign; if (sign < 0) { // parse everything after "d" if (!int.TryParse(st.Substring(dPos + 1), out sides)) { return(false); } } else if (sign > dPos) { if (!int.TryParse(st.Substring(dPos + 1, sign - dPos - 1), out sides)) { return(false); } } } dieRoll = new DieRoll(dice, sides, modifier, keep); return(true); }