/// <summary> /// Loads an animation definition from the given XML node. /// </summary> /// <param name="animElem">The XML node to load from.</param> /// <param name="layerIndex">The index of the render layer of this animation.</param> /// <param name="spritePalette">The sprite palette that the animation is based on.</param> /// <param name="animName">The name of the animation to be loaded.</param> /// <returns>The constructed animation definition.</returns> private static Animation LoadAnimation(XElement animElem, int layerIndex, ISpritePalette <MapDirection> spritePalette) { XAttribute animNameAttr = animElem.Attribute(XmlMetadataConstants.ANIMATION_NAME_ATTR); if (animNameAttr == null) { throw new SimulatorException("Animation name not defined in animation palette!"); } /// Collect the labels. Dictionary <string, int> labels = new Dictionary <string, int>(); int i = 0; foreach (XElement instructionElem in animElem.Elements()) { if (instructionElem.Name == XmlMetadataConstants.LABEL_ELEM) { XAttribute labelNameAttr = instructionElem.Attribute(XmlMetadataConstants.LABEL_NAME_ATTR); if (labelNameAttr == null) { throw new SimulatorException("Label name not defined in animation!"); } labels.Add(labelNameAttr.Value, i); } else { i++; } } /// Collect the instructions i = 0; List <Animation.IInstruction> instructions = new List <Animation.IInstruction>(); foreach (XElement instructionElem in animElem.Elements()) { if (instructionElem.Name == XmlMetadataConstants.FRAME_ELEM) { instructions.Add(LoadNewFrameInstruction(instructionElem, spritePalette)); } else if (instructionElem.Name == XmlMetadataConstants.GOTO_ELEM) { instructions.Add(LoadGotoInstruction(instructionElem, labels)); } else if (instructionElem.Name == XmlMetadataConstants.WAIT_ELEM) { instructions.Add(LoadWaitInstruction(instructionElem)); } else if (instructionElem.Name == XmlMetadataConstants.REPEAT_ELEM) { instructions.Add(new RepeatInstruction()); } } XAttribute isPreviewAttr = animElem.Attribute(XmlMetadataConstants.ANIMATION_ISPREVIEW_ATTR); /// Create the animation object. return(new Animation(animNameAttr.Value, layerIndex, isPreviewAttr != null && XmlHelper.LoadBool(isPreviewAttr.Value), instructions)); }
/// <summary> /// Sets the shadow palette for this metadata. /// </summary> /// <param name="shadowPalette">The shadow palette for this metadata.</param> public void SetShadowPalette(ISpritePalette shadowPalette) { if (this.isFinalized) { throw new InvalidOperationException("ScenarioMetadata object already finalized!"); } if (shadowPalette == null) { throw new ArgumentNullException("shadowPalette"); } this.shadowPalette = shadowPalette; }
/// <summary> /// Sets the HP indicator icon palette of this element type. /// </summary> /// <param name="hpIconPalette">The HP indicator icon palette of this element type.</param> public void SetHPIconPalette(ISpritePalette hpIconPalette) { if (this.metadata.IsFinalized) { throw new InvalidOperationException("Already finalized!"); } if (hpIconPalette == null) { throw new ArgumentNullException("hpIconPalette"); } this.hpIconPalette = hpIconPalette; }
/// <summary> /// Sets the sprite palette of this element type. /// </summary> /// <param name="spritePalette">The sprite palette of this element type.</param> public void SetSpritePalette(ISpritePalette <MapDirection> spritePalette) { if (this.metadata.IsFinalized) { throw new InvalidOperationException("Already finalized!"); } if (spritePalette == null) { throw new ArgumentNullException("spritePalette"); } this.spritePalette = spritePalette; }
/// <summary> /// Tests whether the FOWSpriteGroup for drawing the given type of Fog Of War is generated properly. /// </summary> private void FOWSpriteGroupTest(FOWTypeEnum fowType) { /// Load the Fog Of War sprite palette and create a FOWSpriteGroup out of it. string fowSpritePalettePath = System.IO.Path.Combine(FOW_SPRITEPALETTE_DIR, FOW_SPRITEPALETTE_FILE); XDocument fowSpritePaletteXml = XDocument.Load(fowSpritePalettePath); ISpritePalette <FOWTypeEnum> spritePalette = XmlHelper.LoadSpritePalette(fowSpritePaletteXml.Root, fowType, FOW_SPRITEPALETTE_DIR); FOWSpriteGroup spriteGroup = new FOWSpriteGroup(spritePalette, fowType); spriteGroup.Load(); /// Check that 2 UISprite instances are the same if and only if they images have the same bytes. PrivateObject spriteGroupObj = new PrivateObject(spriteGroup, new PrivateType(typeof(SpriteGroup))); List <UISprite> fowSprites = (List <UISprite>)spriteGroupObj.GetField("spriteList"); RCSet <UISprite> savedFowSprites = new RCSet <UISprite>(); for (int indexA = 0; indexA < fowSprites.Count - 1; indexA++) { if (fowSprites[indexA] == null) { continue; } byte[] bytesOfSpriteA = fowSprites[indexA].Save(); for (int indexB = indexA + 1; indexB < fowSprites.Count; indexB++) { if (fowSprites[indexB] == null) { continue; } byte[] bytesOfSpriteB = fowSprites[indexB].Save(); if (StructuralComparisons.StructuralEqualityComparer.Equals(bytesOfSpriteA, bytesOfSpriteB)) { Assert.AreEqual(fowSprites[indexA], fowSprites[indexB]); } else { Assert.AreNotEqual(fowSprites[indexA], fowSprites[indexB]); } } if (savedFowSprites.Add(fowSprites[indexA])) { string outputPath = System.IO.Path.Combine(OUTPUT_DIR, string.Format("{0}_{1}.png", fowType, Convert.ToString(indexA, 2).PadLeft(9, '0'))); File.WriteAllBytes(outputPath, bytesOfSpriteA); } } /// Destroy the FOWSpriteGroup object. spriteGroup.Unload(); }
/// <summary> /// Loads a command input listener (and all of its children recursively) from the given XML-node. /// </summary> /// <param name="listenerElem">The XML-element to load from.</param> /// <param name="spritePalette">The sprite palette to be used by the listener.</param> /// <param name="commandBuilder">Reference to the command builder interface.</param> /// <returns>The loaded command input listener or null if command input listener could not be loaded from the given XML-node.</returns> public static CommandInputListener LoadFromXml(XElement listenerElem, ISpritePalette spritePalette, ICommandBuilder commandBuilder) { if (listenerElem == null) { throw new ArgumentNullException("listenerElem"); } if (spritePalette == null) { throw new ArgumentNullException("spritePalette"); } if (commandBuilder == null) { throw new ArgumentNullException("commandBuilder"); } /// Check if the XML-node is supported. if (!commandInputListenerTypes.ContainsKey(listenerElem.Name.ToString())) { return(null); } /// Load the listener from the XML-node. CommandInputListener loadedListener = (CommandInputListener)Activator.CreateInstance(commandInputListenerTypes[listenerElem.Name.ToString()]); /// Load the children of the loaded listener recursively. List <CommandInputListener> children = new List <CommandInputListener>(); foreach (XElement childElem in listenerElem.Elements()) { CommandInputListener childNode = LoadFromXml(childElem, spritePalette, commandBuilder); if (childNode != null) { children.Add(childNode); } } loadedListener.children = children; loadedListener.spritePalette = spritePalette; loadedListener.commandBuilder = commandBuilder; loadedListener.Init(listenerElem); /// Return the loaded listener. return(loadedListener); }
/// <see cref="ScenarioDependentComponent.StartImpl"/> protected override void StartImpl() { this.selectionManager = ComponentManager.GetInterface <ISelectionManagerBC>(); this.commandBuilder = new CommandBuilder(); /// Load the command input listeners from the configured directory. DirectoryInfo rootDir = new DirectoryInfo(BizLogicConstants.COMMAND_DIR); if (rootDir.Exists) { FileInfo[] commandFiles = rootDir.GetFiles("*.xml", SearchOption.AllDirectories); foreach (FileInfo commandFile in commandFiles) { string xmlStr = File.ReadAllText(commandFile.FullName); string imageDir = commandFile.DirectoryName; /// Load the XML document. XDocument xmlDoc = XDocument.Parse(xmlStr); /// Load the sprite palette if exists. XElement spritePaletteElem = xmlDoc.Root.Element(SPRITEPALETTE_ELEM); ISpritePalette spritePalette = spritePaletteElem != null?XmlHelper.LoadSpritePalette(spritePaletteElem, imageDir) : null; if (spritePalette != null) { spritePalette.SetIndex(this.allSpritePalettes.Count); this.allSpritePalettes.Add(spritePalette); } /// Load the command input listeners. foreach (XElement listenerElem in xmlDoc.Root.Elements()) { CommandInputListener rootListener = CommandInputListener.LoadFromXml(listenerElem, spritePalette, this.commandBuilder); if (rootListener != null) { this.rootListeners.Add(rootListener); this.activeListeners.Add(rootListener); this.CollectProductButtonSprites(rootListener); } } } } }
/// <summary> /// Constructs a FOWSpriteGroup instance from the given sprite palette. /// </summary> /// <param name="spritePalette">The sprite palette that contains the sprites for drawing the Fog Of War.</param> /// <param name="fowType">The type of the Fog Of War stored in this sprite-group.</param> public FOWSpriteGroup(ISpritePalette <FOWTypeEnum> spritePalette, FOWTypeEnum fowType) { if (spritePalette == null) { throw new ArgumentNullException("spritePalette"); } if (fowType == FOWTypeEnum.None) { throw new ArgumentException("FOWSpriteGroup cannot store sprites for FOWTypeEnum.None!", "fowType"); } if (spritePalette.TransparentColor == RCColor.Undefined) { throw new ArgumentException("Transparent color is not defined for FOW sprite palette!", "spritePalette"); } this.spritePalette = spritePalette; this.fowType = fowType; this.spriteIndices = new Dictionary <FOWTileFlagsEnum, int>(); foreach (KeyValuePair <FOWTileFlagsEnum, string> item in SPRITE_NAMES) { this.spriteIndices[item.Key] = this.spritePalette.GetSpriteIndex(item.Value, this.fowType); } }
/// <summary> /// Loads a new frame instruction from the given XML node. /// </summary> /// <param name="instructionElem">The XML node to load from.</param> /// <param name="spritePalette">The sprite palette that the animation instruction is based on.</param> /// <returns>The constructed instruction.</returns> private static Animation.IInstruction LoadNewFrameInstruction(XElement instructionElem, ISpritePalette <MapDirection> spritePalette) { XAttribute spritesAttr = instructionElem.Attribute(XmlMetadataConstants.FRAME_SPRITES_ATTR); XAttribute durationAttr = instructionElem.Attribute(XmlMetadataConstants.FRAME_DURATION_ATTR); if (spritesAttr == null) { throw new SimulatorException("Sprites not defined for new frame instruction!"); } string[] spriteNames = spritesAttr.Value.Split(','); if (spriteNames.Length == 0) { throw new SimulatorException("Syntax error!"); } Dictionary <MapDirection, int[]> spriteIndices = new Dictionary <MapDirection, int[]> { { MapDirection.North, new int[spriteNames.Length] }, { MapDirection.NorthEast, new int[spriteNames.Length] }, { MapDirection.East, new int[spriteNames.Length] }, { MapDirection.SouthEast, new int[spriteNames.Length] }, { MapDirection.South, new int[spriteNames.Length] }, { MapDirection.SouthWest, new int[spriteNames.Length] }, { MapDirection.West, new int[spriteNames.Length] }, { MapDirection.NorthWest, new int[spriteNames.Length] }, }; /// Search the appropriate sprite indices for each directions from the sprite palette. foreach (KeyValuePair <MapDirection, int[]> item in spriteIndices) { MapDirection direction = item.Key; for (int i = 0; i < spriteNames.Length; i++) { /// Get the sprite index for the current direction or for MapDirection.Undefined if not found. int spriteIndex = spritePalette.GetSpriteIndex(spriteNames[i], direction); if (spriteIndex == -1) { spriteIndex = spritePalette.GetSpriteIndex(spriteNames[i], MapDirection.Undefined); } if (spriteIndex == -1) { throw new SimulatorException(string.Format("Sprite '{0}' not defined for neither {1} nor {2}!", spriteNames[i], direction, MapDirection.Undefined)); } spriteIndices[direction][i] = spriteIndex; } } return(new NewFrameInstruction(spriteIndices, durationAttr != null ? XmlHelper.LoadInt(durationAttr.Value) : 1)); }
/// <summary> /// Loads an animation palette definition from the given XML node. /// </summary> /// <param name="animPaletteElem">The XML node to load from.</param> /// <param name="metadata">The metadata object.</param> /// <param name="spritePalette">The sprite palette that the animation palette is based on.</param> /// <returns>The constructed animation palette definition.</returns> private static AnimationPalette LoadAnimationPalette(XElement animPaletteElem, ISpritePalette <MapDirection> spritePalette, ScenarioMetadata metadata) { /// Create the animation palette object. AnimationPalette animPalette = new AnimationPalette(metadata); /// Load the animations. foreach (XElement animElem in animPaletteElem.Elements(XmlMetadataConstants.ANIMATION_ELEM)) { Animation animation = LoadAnimation(animElem, animPalette.Count, spritePalette); animPalette.AddAnimation(animation); } return(animPalette); }
/// <summary> /// Loads the necessary data of a scenario element type. /// </summary> /// <param name="elementTypeElem">The XML node to load from.</param> /// <param name="elementType">The scenario element type being constructed.</param> /// <param name="metadata">The metadata object.</param> private static void LoadScenarioElementType(XElement elementTypeElem, ScenarioElementType elementType, ScenarioMetadata metadata) { /// Load the displayed name of the element type. XAttribute displayedNameAttr = elementTypeElem.Attribute(XmlMetadataConstants.TYPE_DISPLAYEDNAME_ATTR); if (displayedNameAttr != null) { elementType.SetDisplayedName(displayedNameAttr.Value); } /// Load the has owner flag of the element type. XAttribute hasOwnerAttr = elementTypeElem.Attribute(XmlMetadataConstants.TYPE_HASOWNER_ATTR); elementType.SetHasOwner(hasOwnerAttr != null && XmlHelper.LoadBool(hasOwnerAttr.Value)); /// Load the sprite palette of the element type. XElement spritePaletteElem = elementTypeElem.Element(XmlMetadataConstants.SPRITEPALETTE_ELEM); ISpritePalette <MapDirection> spritePalette = null; if (spritePaletteElem != null) { spritePalette = XmlHelper.LoadSpritePalette(spritePaletteElem, MapDirection.Undefined, tmpImageDir); elementType.SetSpritePalette(spritePalette); } /// Load the HP indicator icon palette of this element type. XElement hpIconPaletteElem = elementTypeElem.Element(XmlMetadataConstants.HPICONPALETTE_ELEM); if (hpIconPaletteElem != null) { ISpritePalette hpIconPalette = XmlHelper.LoadSpritePalette(hpIconPaletteElem, tmpImageDir); elementType.SetHPIconPalette(hpIconPalette); } /// Load the animation palette of the element type. XElement animPaletteElem = elementTypeElem.Element(XmlMetadataConstants.ANIMPALETTE_ELEM); if (animPaletteElem != null) { if (spritePalette == null) { throw new SimulatorException("Animation palette definition requires a sprite palette definition!"); } elementType.SetAnimationPalette(LoadAnimationPalette(animPaletteElem, spritePalette, metadata)); } /// Load the cost data of the element type. XElement costsDataElem = elementTypeElem.Element(XmlMetadataConstants.COSTS_ELEM); if (costsDataElem != null) { LoadCostsData(costsDataElem, elementType); } /// Load the general data of the element type. XElement genDataElem = elementTypeElem.Element(XmlMetadataConstants.GENERALDATA_ELEM); if (genDataElem != null) { LoadGeneralData(genDataElem, elementType); } /// Load the shadow data of the element type. XElement shadowDataElem = elementTypeElem.Element(XmlMetadataConstants.SHADOWDATA_ELEM); if (shadowDataElem != null) { LoadShadowData(shadowDataElem, elementType); } /// Load the ground weapon definitions of the element type. foreach (XElement gndWeaponElem in elementTypeElem.Elements(XmlMetadataConstants.GROUNDWEAPON_ELEM)) { elementType.AddWeapon(LoadWeaponData(gndWeaponElem, metadata)); } /// Load the air weapon definitions of the element type. foreach (XElement airWeaponElem in elementTypeElem.Elements(XmlMetadataConstants.AIRWEAPON_ELEM)) { elementType.AddWeapon(LoadWeaponData(airWeaponElem, metadata)); } /// Load the air-ground weapon definitions of the element type. foreach (XElement airGroundWeaponElem in elementTypeElem.Elements(XmlMetadataConstants.AIRGROUNDWEAPON_ELEM)) { elementType.AddWeapon(LoadWeaponData(airGroundWeaponElem, metadata)); } /// Load the custom weapon definitions of the element type. foreach (XElement customWeaponElem in elementTypeElem.Elements(XmlMetadataConstants.CUSTOMWEAPON_ELEM)) { elementType.AddWeapon(LoadWeaponData(customWeaponElem, metadata)); } /// Load the requirements of the element type. XElement requiresElem = elementTypeElem.Element(XmlMetadataConstants.REQUIRES_ELEM); if (requiresElem != null) { string reqListStr = requiresElem.Value.Trim(); string[] requirementStrings = reqListStr.Split(','); foreach (string reqStr in requirementStrings) { Tuple <string, string> buildingAddonPair = ParseBuildingAddonStr(reqStr); elementType.AddRequirement(new Requirement(buildingAddonPair.Item1, buildingAddonPair.Item2, metadata)); } } }