public static void readData(GurpsDatabase database, IEnumerable<string> paths)
        {
            var nameToThing = database.nameToThing;
            // parse and check for duplicate names
            foreach (string path in paths)
            {
                foreach (ParsedThing parsedThing in parseFile(path))
                {
                    GurpsProperty property = interpretParsedThing(parsedThing);
                    try { nameToThing.Add(property.name, property); }
                    catch (ArgumentException)
                    {
                        GurpsProperty previousThing = nameToThing[property.name];
                        throw new GurpenatorException("duplicate definitions of \"" + parsedThing.name + "\". " + previousThing.parsedThing.getLocationString() + ", " + parsedThing.getLocationString());
                    }
                }
            }

            // make sure some core attributes are defined
            foreach (string name in GurpsCharacter.coreAttributeNames.Concat(new string[] { GurpsCharacter.HUMAN }))
                if (!nameToThing.ContainsKey(name))
                    throw new GurpenatorException("missing definition of core attribute \"" + name + "\"");

            checkFormulas(nameToThing);

            // tweek some attributes specially
            nameToThing["Thrust"].formattingFunction = GurpsProperty.formatAsDice;
            nameToThing["Swing"].formattingFunction = GurpsProperty.formatAsDice;
            // display Basic Speed in m/s rather than Basic Speed x4 in m/s*4.
            nameToThing["Basic Speed x4"].DisplayName = "Basic Speed";
            nameToThing["Basic Speed x4"].formattingFunction = (value) => (value * 0.25).ToString();
            nameToThing["Fright Check"].formattingFunction = (value) => value <= 13 ? value.ToString() : "13+" + (value - 13);
        }
 public CharacterSheet(GurpsDatabase database, string characterPath)
 {
     InitializeComponent();
     this.database = database;
     if (characterPath == null)
         newCharacter();
     else
         load(characterPath);
 }
 public static GurpsCharacter fromJson(object jsonObject, GurpsDatabase database)
 {
     GurpsCharacter character = new GurpsCharacter(database);
     var dict = (Dictionary<string, object>)jsonObject;
     character.name = (string)dict["name"];
     character.layout = AbstractTraitGroup.fromJson(dict["layout"]);
     foreach (object purchaseObject in (List<object>)dict["purchases"])
     {
         var purchase = (Dictionary<string, object>)purchaseObject;
         character.getPurchasedProperty((string)purchase["trait"]).PurchasedLevels = (int)purchase["purchased"];
     }
     return character;
 }
 private void databasesToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (new DatabaseListEditor().ShowDialog(this) == DialogResult.Cancel)
         return;
     // reload database and character
     database = new GurpsDatabase();
     DataLoader.readData(database, Preferences.Instance.Databases);
     try { setCharacter(GurpsCharacter.fromJson(character.toJson(), database)); }
     catch (GurpenatorException ex)
     {
         // TODO unify everything
         MessageBox.Show(this, ex.Message, "Data Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
         newCharacter();
     }
 }
 public GurpsCharacter(GurpsDatabase database)
 {
     foreach (GurpsProperty property in database.nameToThing.Values)
         nameToPurchasedAttribute[property.name] = new PurchasedProperty(property, this);
     foreach (PurchasedProperty purchasedProperty in nameToPurchasedAttribute.Values)
     {
         purchasedProperty.changed += raiseChanged;
         foreach (string name in purchasedProperty.property.usedNames())
         {
             if (DataLoader.reservedWords.Contains(name))
                 continue;
             nameToPurchasedAttribute[name].changed += purchasedProperty.handleChange;
         }
         foreach (Effect effect in purchasedProperty.property.effectedBy)
         {
             nameToPurchasedAttribute[effect.owner.name].changed += purchasedProperty.handleChange;
         }
     }
 }