/// <summary> /// Copy constructor. /// </summary> /// <param name="existing"></param> public Component(Component copy) : base(copy) { Mass = copy.Mass; Cost = new Resources(copy.Cost); Properties = new Dictionary <string, ComponentProperty>(); RequiredTech = new TechLevel(copy.RequiredTech); ComponentImage = copy.ComponentImage; ImageFile = copy.ImageFile; Description = copy.Description; foreach (string key in copy.Properties.Keys) { Properties.Add(key, (ComponentProperty)copy.Properties[key].Clone()); } if (copy.Restrictions != null) { Restrictions = new RaceRestriction(copy.Restrictions); } else { Restrictions = null; } }
private readonly RadioButton[,] radioMap = new RadioButton[24, 3]; // an array representation (map) of the radio button controls for ease of programatic manipulation /// <Summary> /// initializing constructor for the dialog /// </Summary> /// <param name="existingName">The component's name.</param> /// <param name="existingImage">The component's Image</param> /// <param name="existingRestrictions">The component's current <see cref="RaceRestriction"'s/></param> public RaceRestrictionDialog(string existingName, Bitmap existingImage, RaceRestriction existingRestrictions) { InitializeComponent(); try { this.componentName.Text = existingName; this.componentImage.Image = existingImage; } catch { // incase the name or image are null. } // Map the RadioButton controls to an array for easier manipulation. // PRTs this.radioMap[0, 0] = this.notAvailableHE; this.radioMap[0, 1] = this.notRequiredHE; this.radioMap[0, 2] = this.requiredHE; this.radioMap[1, 0] = this.notAvailableSS; this.radioMap[1, 1] = this.notRequiredSS; this.radioMap[1, 2] = this.requiredSS; this.radioMap[2, 0] = this.notAvailableWM; this.radioMap[2, 1] = this.notRequiredWM; this.radioMap[2, 2] = this.requiredWM; this.radioMap[3, 0] = this.notAvailableCA; this.radioMap[3, 1] = this.notRequiredCA; this.radioMap[3, 2] = this.requiredCA; this.radioMap[4, 0] = this.notAvailableIS; this.radioMap[4, 1] = this.notRequiredIS; this.radioMap[4, 2] = this.requiredIS; this.radioMap[5, 0] = this.notAvailableSD; this.radioMap[5, 1] = this.notRequiredSD; this.radioMap[5, 2] = this.requiredSD; this.radioMap[6, 0] = this.notAvailablePP; this.radioMap[6, 1] = this.notRequiredPP; this.radioMap[6, 2] = this.requiredPP; this.radioMap[7, 0] = this.notAvailableIT; this.radioMap[7, 1] = this.notRequiredIT; this.radioMap[7, 2] = this.requiredIT; this.radioMap[8, 0] = this.notAvailableAR; this.radioMap[8, 1] = this.notRequiredAR; this.radioMap[8, 2] = this.requiredAR; this.radioMap[9, 0] = this.notAvailableJOAT; this.radioMap[9, 1] = this.notRequiredJOAT; this.radioMap[9, 2] = this.requiredJOAT; // LRTs this.radioMap[10, 0] = this.notAvailableIFE; this.radioMap[10, 1] = this.notRequiredIFE; this.radioMap[10, 2] = this.requiredIFE; this.radioMap[11, 0] = this.notAvailableTT; this.radioMap[11, 1] = this.notRequiredTT; this.radioMap[11, 2] = this.requiredTT; this.radioMap[12, 0] = this.notAvailableARM; this.radioMap[12, 1] = this.notRequiredARM; this.radioMap[12, 2] = this.requiredARM; this.radioMap[13, 0] = this.notAvailableISB; this.radioMap[13, 1] = this.notRequiredISB; this.radioMap[13, 2] = this.requiredISB; this.radioMap[14, 0] = this.notAvailableGR; this.radioMap[14, 1] = this.notRequiredGR; this.radioMap[14, 2] = this.requiredGR; this.radioMap[15, 0] = this.notAvailableUR; this.radioMap[15, 1] = this.notRequiredUR; this.radioMap[15, 2] = this.requiredUR; this.radioMap[16, 0] = this.notAvailableMA; this.radioMap[16, 1] = this.notRequiredMA; this.radioMap[16, 2] = this.requiredMA; this.radioMap[17, 0] = this.notAvailableCE; this.radioMap[17, 1] = this.notRequiredCE; this.radioMap[17, 2] = this.requiredCE; this.radioMap[18, 0] = this.notAvailableCE; this.radioMap[18, 1] = this.notRequiredCE; this.radioMap[18, 2] = this.requiredCE; this.radioMap[19, 0] = this.notAvailableOBRM; this.radioMap[19, 1] = this.notRequiredOBRM; this.radioMap[19, 2] = this.requiredOBRM; this.radioMap[20, 0] = this.notAvailableNAS; this.radioMap[20, 1] = this.notRequiredNAS; this.radioMap[20, 2] = this.requiredNAS; this.radioMap[21, 0] = this.notAvailableLSP; this.radioMap[21, 1] = this.notRequiredLSP; this.radioMap[21, 2] = this.requiredLSP; this.radioMap[22, 0] = this.notAvailableBET; this.radioMap[22, 1] = this.notRequiredBET; this.radioMap[22, 2] = this.requiredBET; this.radioMap[23, 0] = this.notAvailableRS; this.radioMap[23, 1] = this.notRequiredRS; this.radioMap[23, 2] = this.requiredRS; // initialize race restriction radio button selections. if (existingRestrictions != null) { Restrictions = new RaceRestriction(existingRestrictions); int n = 0; foreach (string trait in AllTraits.TraitKeys) { // For each trait there are three radio buttons. We need to set one of them, // which will clear the other two (as only one radio button in a set can be selected). The // enumerated Availability maps onto which of the three buttons to select. this.radioMap[n, (int)existingRestrictions.Availability(trait)].Checked = true; n++; } } else { Restrictions = new RaceRestriction(); } }
/// <summary> /// Load from XML: Initializing constructor from an XML node. /// </summary> /// <param name="node">An <see cref="XmlNode"/> within /// a Nova component definition file (xml document). /// </param> public Component(XmlNode node) : base(node) { Properties = new Dictionary <string, ComponentProperty>(); XmlNode mainNode = node.FirstChild; while (mainNode != null) { try { switch (mainNode.Name.ToLower()) { case "mass": Mass = int.Parse(mainNode.FirstChild.Value, System.Globalization.CultureInfo.InvariantCulture); break; case "cost": Cost = new Resources(mainNode); break; case "tech": RequiredTech = new TechLevel(mainNode); break; case "description": XmlText xmltxtDescription = (XmlText)mainNode.FirstChild; if (xmltxtDescription != null) { this.Description = xmltxtDescription.Value; } break; case "race_restrictions": Restrictions = new RaceRestriction(mainNode); break; case "image": { // Paths are always stored in external files using forward slashes. ImageFile = mainNode.FirstChild.Value; ImageFile = ImageFile.Replace('/', Path.DirectorySeparatorChar); // relative or absolute path? we normally store the relative path but will handle loading either incase the file has been manually modified. try { FileInfo info = new FileInfo(ImageFile); if (info.Exists) { // was absolute, so keep as is and load up the image ComponentImage = new Bitmap(ImageFile); } else { { string graphicsPath = FileSearcher.GetGraphicsPath(); if (graphicsPath != null) { ImageFile = Path.Combine(graphicsPath, ImageFile); info = new FileInfo(ImageFile); } } if (info.Exists) { // now we have an absolute path, load the image ComponentImage = new Bitmap(ImageFile); } else { // No further action. FileSearcher will report an error (once only) if the graphics are not available. } } } catch (System.NotSupportedException) { // The path doesn't make sense, maybe it wasn't relative. // Don't change anything and don't load the image ImageFile = mainNode.FirstChild.Value.Replace('/', Path.DirectorySeparatorChar); ComponentImage = null; Report.Error("Unable to locate the image file " + ImageFile); } break; } case "property": { // Load the property. It may be of any type (Bomb, IntegerProperty, Hull, etc), so // check the save file first to determine what to load, and use the appropriate constructor. string propertyType = mainNode.SelectSingleNode("Type").FirstChild.Value; ComponentProperty newProperty; switch (propertyType.ToLower()) { case "armor": { newProperty = new IntegerProperty(mainNode); break; } case "battle movement": { newProperty = new DoubleProperty(mainNode); break; } case "beam deflector": { newProperty = new ProbabilityProperty(mainNode); break; } case "bomb": { newProperty = new Bomb(mainNode); break; } case "capacitor": { newProperty = new CapacitorProperty(mainNode); break; } case "cloak": { newProperty = new ProbabilityProperty(mainNode); break; } case "defense": { newProperty = new Defense(mainNode); break; } case "energy dampener": { newProperty = new DoubleProperty(mainNode); break; } case "cargo": { newProperty = new IntegerProperty(mainNode); break; } case "colonizer": { newProperty = new Colonizer(mainNode); break; } case "computer": { newProperty = new Computer(mainNode); break; } case "engine": { newProperty = new Engine(mainNode); break; } case "fuel": { newProperty = new Fuel(mainNode); break; } case "gate": { newProperty = new Gate(mainNode); break; } case "hull": { newProperty = new Hull(mainNode); break; } case "hull affinity": { newProperty = new HullAffinity(mainNode); break; } case "jammer": { newProperty = new ProbabilityProperty(mainNode); break; } case "mass driver": { newProperty = new MassDriver(mainNode); break; } case "mine layer": { newProperty = new MineLayer(mainNode); break; } case "mine layer efficiency": { newProperty = new DoubleProperty(mainNode); break; } case "mining robot": { newProperty = new IntegerProperty(mainNode); break; } case "orbital adjuster": { newProperty = new IntegerProperty(mainNode); break; } case "radiation": { newProperty = new Radiation(mainNode); break; } case "shield": { newProperty = new IntegerProperty(mainNode); break; } case "scanner": { newProperty = new Scanner(mainNode); break; } case "tachyon detector": { newProperty = new ProbabilityProperty(mainNode); break; } case "terraform": { newProperty = new Terraform(mainNode); break; } case "transport ships only": { newProperty = new SimpleProperty(mainNode); break; } case "weapon": { newProperty = new Weapon(mainNode); break; } default: { // it is an error to arrive here, but try to recover using an integer property Report.Error("Component property type " + propertyType + " not recognised, using default constructor"); newProperty = new IntegerProperty(mainNode); break; } } if (newProperty != null) { this.Properties.Add(propertyType, newProperty); } break; } } } catch (Exception e) { Report.FatalError(e.Message + "\n Details: \n" + e.ToString()); } mainNode = mainNode.NextSibling; } }