Beispiel #1
0
        /// <summary>
        /// Takes the symbol code and matches one of the stencils in the resource dictionary.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to look up the stencil.
        /// </param>
        /// <returns>
        /// The string that should be used to get the ResourceDictionary entry for this symbol.
        /// </returns>
        public static string CodeToStencil(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            int schemeKey = CodingScheme.GetCode(symbolCode);

            // Weather short circuits most considerations, at least for now
            if (schemeKey == CodingScheme.Weather)
            {
                return(symbolCode);
            }

            string stencil = symbolCode.Substring(0, 10).ToUpperInvariant();

            int dash = stencil.IndexOf('-', 4);

            if (dash > 0)
            {
                stencil = stencil.Substring(0, dash);
            }

            // Replace remaining '-'s with '_'s
            stencil = stencil.Replace('-', '_');

            // Return one of the four (approximately) that we know about
            int identityKey = StandardIdentity.GetNormalizedStandardIdentity(symbolCode);

            // Need the battle dimension
            int dimensionKey = CategoryBattleDimension.GetCode(symbolCode);

            // If we have a Z battle dimension cut right to the chase.
            // Get a blank stencil so we can add a question mark.
            if (dimensionKey == CategoryBattleDimension.BdUnknown)
            {
                return("I" + StandardIdentity.ToChar(identityKey) + "ZP");
            }

            string tail = stencil.Substring(2, 1) + "P" + stencil.Substring(4);

            // If we have EmergenctManagement and a NaturalEvent, get rid of the standard identity
            // or if we have a tactical graphic, get rid of the standard identity
            if ((schemeKey == CodingScheme.EmergencyManagement &&
                 dimensionKey == CategoryBattleDimension.EmNaturalEvents) ||
                schemeKey == CodingScheme.TacticalGraphics)
            {
                return(stencil.Substring(0, 1) + "_" + tail);
            }

            // If framed, we'll include the base affiliation
            if (dimensionKey != CategoryBattleDimension.BdOther)
            {
                return(stencil.Substring(0, 1) + StandardIdentity.ToChar(identityKey) + tail);
            }

            // Otherwise, we're looking for an unframed element
            return(stencil.Substring(0, 1) + "." + tail);
        }
Beispiel #2
0
        /// <summary>
        /// Generate the Joker, Faker, or "eXercise" character.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the large character string.
        /// </param>
        /// <param name="labels">
        /// A dictionary of the labels to be drawn.
        /// </param>
        /// <param name="style">
        /// The style to apply to the labels.
        /// </param>
        /// <returns>
        /// The TextBlock that incorporates the labels.
        /// </returns>
        internal static TextBlock GenerateJokerFakerExercise(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            // Check for matching code
            char theChar = StandardIdentity.GetExerciseAmplifyingDescriptor(symbolCode);

            if (theChar == (char)0)
            {
                return(null);
            }
#if WINDOWS_UWP
            string theString = theChar.ToString();
#else
            string theString = theChar.ToString(Culture);
#endif
            if (labels != null && labels.ContainsKey("F"))
            {
                theString += " " + labels["F"];
            }

            Rect r  = SymbolData.GetBounds(symbolCode);
            var  tb = new TextBlock
            {
                Style = style, // BigLabels,
                Text  = theString
            };
            tb.FindTextExtent();
            tb.SetValue(Canvas.TopProperty, r.Top - tb.Height);
            tb.SetValue(Canvas.LeftProperty, r.Right);
            return(tb);
        }
Beispiel #3
0
        /// <summary>
        /// Checks to see if the symbol requires a dashed outline.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code to check.
        /// </param>
        /// <returns>
        /// A boolean to indicate whether the outline should be dashed.
        /// </returns>
        internal static bool IsDashed(string symbolCode)
        {
            if (!Check(ref symbolCode))
            {
                return(false);
            }

            switch (StandardIdentity.GetCode(symbolCode))
            {
            case StandardIdentity.Pending:
            case StandardIdentity.AssumedFriend:
            case StandardIdentity.Suspect:
            case StandardIdentity.ExercisePending:
            case StandardIdentity.ExerciseAssumedFriend:
            {
                return(true);
            }

            default:
                if (StatusOperationalCapacity.GetCode(symbolCode) == StatusOperationalCapacity.AnticipatedPlanned)
                {
                    return(true);
                }

                return(false);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Generates a static tooltip for a given symbol code.
        /// </summary>
        /// <param name="symbolCode">The symbol code which needs the tooltip.</param>
        /// <returns>A string representing a tooltip.</returns>
        private static string GenerateTooltip(string symbolCode)
        {
            var desc = new StringBuilder(MilAppendix.Description(symbolCode));

            desc.AppendLine("Affiliation: " + StandardIdentity.GetName(symbolCode));
            desc.AppendLine("Condition: " + StatusOperationalCapacity.GetName(symbolCode));
            desc.AppendLine("Order of battle: " + OrderOfBattle.GetName(symbolCode));
            desc.AppendLine("Country: " + Countries.GetName(symbolCode));
            desc.Append("Modifier: " + CombinedModifierCode.GetName(symbolCode));
            return(desc.ToString(0, desc.Length));
        }
Beispiel #5
0
        /// <summary>
        /// This is the current background color for this particular symbol
        /// </summary>
        /// <param name="symbolCode">The symbol code</param>
        /// <returns>A brush representing the current background color for the symbol code</returns>
        public static Brush FindColorScheme(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (OrderOfBattle.GetCode(symbolCode) == OrderOfBattle.Civilian)
            {
                if (StandardIdentity.IsColorHostile(symbolCode))
                {
                    return(GetDefault(Reds, ColorScheme));
                }

                return(GetDefault(Purples, ColorScheme));
            }

            switch (StandardIdentity.GetCode(symbolCode))
            {
            case StandardIdentity.AssumedFriend:
            case StandardIdentity.ExerciseFriend:
            case StandardIdentity.Friend:
            case StandardIdentity.ExerciseAssumedFriend:
                return(GetDefault(Blues, ColorScheme));

            case StandardIdentity.Hostile:
            case StandardIdentity.Joker:
            case StandardIdentity.Faker:
            case StandardIdentity.Suspect:
                return(GetDefault(Reds, ColorScheme));

            case StandardIdentity.ExerciseNeutral:
            case StandardIdentity.Neutral:
                return(GetDefault(Greens, ColorScheme));

            case StandardIdentity.ExercisePending:
            case StandardIdentity.Pending:
            case StandardIdentity.Unknown:
            case StandardIdentity.ExerciseUnknown:
                return(GetDefault(Yellows, ColorScheme));

            default:
                return(null);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Generate the right labels for the symbol.
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code for which to generate the labels.
        /// </param>
        /// <param name="labels">
        /// The dictionary of labels to generate.
        /// </param>
        /// <param name="style">
        /// The style with which to render the labels.
        /// </param>
        /// <returns>
        /// A TextBlock that represents the rendered labels.
        /// </returns>
        internal static TextBlock GenerateRight(string symbolCode, IDictionary <string, string> labels, Style style)
        {
            // Pick off the left-oriented strings and write them out
            if (labels == null)
            {
                return(null);
            }

            var right = new TextBlock {
                Style = style                         /*RightLabels*/
            };
            bool gotLine = false;

            // If we have an X, J, or K modifier character, skip label F because it is already written out.
            if (StandardIdentity.GetExerciseAmplifyingDescriptor(symbolCode) != (char)0)
            {
                ProcessLabels(labels, false, new[] { string.Empty }, right, ref gotLine);
            }
            else
            {
                ProcessLabels(labels, false, new[] { "F" }, right, ref gotLine);
            }

            var height = gotLine ? (double)right.GetValue(TextBlock.LineHeightProperty) : 0.0;

            // At this point we need to process the remaining labels as if each row has a label.
            // Otherwise some label lines may appear in the wrong position
            // if other label lines are empty.
            // Setting "gotLine" to true forces a new line for each of the label lines.
            // More complicated logic might consider the height of the text block, prior to
            // the elimination of the empty lines.
            gotLine = true;

            ProcessLabels(labels, false, new[] { "G" }, right, ref gotLine);
            ProcessLabels(labels, false, new[] { "H" }, right, ref gotLine);
            ProcessLabels(labels, false, new[] { "M" }, right, ref gotLine);
            ProcessLabels(labels, true, new[] { "J", "K", "L", "N", "P" }, right, ref gotLine);
            TruncateNewLines(right);

            Rect b = SymbolData.GetBounds(symbolCode);

            SetTopLeft(right, b.Right + (height / 5.0), b.Top - height);
            return(right);
        }
Beispiel #7
0
        public void StandardIdentityTest()
        {
            int gc = StandardIdentity.GetCode(string.Empty);

            Assert.AreEqual(gc, (char)0);
            gc = StandardIdentity.GetCode(null);
            Assert.AreEqual(gc, (char)0);
            gc = StandardIdentity.GetCode("qqqqqqqqqqqqqqq");
            Assert.AreEqual(gc, (char)0);
            string str = StandardIdentity.GetName(string.Empty);

            Assert.AreEqual(str, string.Empty);
            str = StandardIdentity.GetName(null);
            Assert.AreEqual(str, string.Empty);
            str = StandardIdentity.GetName("qqqqqqqqqqqqqqq");
            Assert.AreEqual(str, string.Empty);
            str = StandardIdentity.GetName("qApqqqqqqqqqqqn");
            Assert.AreEqual(str, "Assumed Friend");
        }
Beispiel #8
0
        /// <summary>
        /// When is the top of the symbol flat?
        /// Answer:
        /// 1. normalize StandardIdentity to 'F', 'H', 'N' or 'U'
        /// 2. return true when it is Subsurface
        /// 3. return true when it is Neutral
        /// 4. return true when it is Friendly Units, Installations, or SOF
        /// 5. return true when it is Friendly Emergency Operations
        ///   a. technically, friendly emergency equipment is not flat
        /// </summary>
        /// <param name="symbolCode">
        /// The symbol code to check for a flat top to the symbol.
        /// </param>
        /// <returns>
        /// Returns a boolean to indicate whether the top of the symbol is flat.
        /// </returns>
        internal static bool IsTopFlat(string symbolCode)
        {
            if (!Check(ref symbolCode))
            {
                return(false);
            }

            int dimensionKey = CategoryBattleDimension.GetCode(symbolCode);

            if (dimensionKey == CategoryBattleDimension.BdSubsurface)
            {
                return(true);
            }

            int identityKey = StandardIdentity.GetNormalizedStandardIdentity(symbolCode);

            if (identityKey == StandardIdentity.Neutral)
            {
                return(true);
            }

            if (identityKey == StandardIdentity.Friend)
            {
                if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir ||
                    dimensionKey == CategoryBattleDimension.BdSeaSurface ||
                    dimensionKey == CategoryBattleDimension.BdUnknown)
                {
                    return(false);
                }

                if (IsEquipment(symbolCode))
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
Beispiel #9
0
        /// <summary>
        /// Writes out the CXML file.
        /// </summary>
        /// <param name="ms">
        /// The symbol for which to generate the CXML.
        /// </param>
        /// <param name="rootName">
        /// The name to use for the symbol.
        /// </param>
        private void WriteCxml(MilSymbol ms, string rootName)
        {
            var symbolCode = (CodingScheme.GetCode(ms.SymbolCode) != CodingScheme.Weather) ? rootName + "*****" : ms.SymbolCode;

            var description = MilAppendix.Description(symbolCode);
            var lines       = description.Split(new[] { '\n' });
            var lineCount   = lines.Length - 1; // the last line is empty

            var sb = new StringBuilder();

            sb.AppendFormat(@"<Item Id=""{0}"" Name=""{1}"" Img=""Symbols\{1}.png"" Href="""">", this.index++, rootName);
            sb.AppendLine();
            if (lineCount > 0)
            {
                sb.AppendFormat(@" <Description>""{0}""</Description>", lines[lineCount - 1].Trim(new[] { ' ', '\n', '\r' }));
                sb.AppendLine();
            }
            else
            {
                sb.AppendFormat(@" <Description>""""</Description>");
                sb.AppendLine();
            }

            sb.AppendLine(@" <Facets>");
            sb.AppendLine(@"  <Facet Name=""Affiliation"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", StandardIdentity.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            sb.AppendLine(@"  <Facet Name=""Battle Dimension"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", CategoryBattleDimension.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            if (lineCount > 2)
            {
                sb.AppendLine(@"  <Facet Name=""Type"">");
                sb.AppendFormat(@"   <String Value=""{0}"" />", lines[2].Trim(new[] { ' ', '\n', '\r' }));
                sb.AppendLine();
                sb.AppendLine(@"  </Facet>");
            }

            sb.AppendLine(@"  <Facet Name=""Coding Scheme"">");
            sb.AppendFormat(@"   <String Value=""{0}"" />", CodingScheme.GetName(symbolCode));
            sb.AppendLine();
            sb.AppendLine(@"  </Facet>");
            if (lineCount - 1 > 3)
            {
                sb.AppendLine(@"  <Facet Name=""Key Phrases"">");
                for (var i = 3; i < lineCount - 1; i++)
                {
                    sb.AppendFormat(@"   <String Value=""{0}"" />", lines[i].Trim(new[] { ' ', '\n', '\r' }));
                    sb.AppendLine();
                }

                sb.AppendLine(@"  </Facet>");
            }

            sb.AppendLine(@" </Facets>");
            sb.AppendLine(@"</Item>");

#if DO_WRITES
            this.cxmlStream.Write(sb.ToString());
#endif
        }
Beispiel #10
0
        /// <summary>
        /// Adds the black ribbon at the top of the symbol for the standard identity "Space".
        /// </summary>
        /// <param name="symbolCode">The symbol code for the space entity.</param>
        /// <returns>The shape representing the black ribbon overlay for a space entity.</returns>
        internal static Shape GenerateSpace(string symbolCode)
        {
            if (!SymbolData.Check(ref symbolCode))
            {
                return(null);
            }

            if (CategoryBattleDimension.GetCode(symbolCode) != CategoryBattleDimension.BdSpace)
            {
                return(null);
            }

            // Handy points for future reference
            // Inside for unknown ground
            // <Path Data="F0 M-61,-140 C-30,-175 30,-175 61,-140" />
            // Inside for hostile ground
            // <Polygon Points="-61,-105 0,-166 61,-105" />
            switch (StandardIdentity.GetNormalizedStandardIdentity(symbolCode))
            {
            case StandardIdentity.Friend:
            {
                return(GenerateBlackSpline(
                           new Point(-61, -107), new Point(-23, -148), new Point(23, -148), new Point(61, -107)));
            }

            case StandardIdentity.Unknown:
            {
                return(GenerateBlackSpline(
                           new Point(-61, -117), new Point(-30, -160), new Point(30, -160), new Point(61, -117)));
            }

            case StandardIdentity.Hostile:
            {
                return(new Path
                    {
                        Fill = new SolidColorBrush(Colors.Black),
                        Data = new PathGeometry
                        {
                            Figures = new PathFigureCollection
                            {
                                new PathFigure
                                {
                                    StartPoint = new Point(-61, -93),
                                    Segments = new PathSegmentCollection
                                    {
                                        new LineSegment {
                                            Point = new Point(0, -149)
                                        },
                                        new LineSegment {
                                            Point = new Point(61, -93)
                                        }
                                    }
                                }
                            }
                        }
                    });
            }

            case StandardIdentity.Neutral:
            {
                return(new Path
                    {
                        Fill = new SolidColorBrush(Colors.Black),
                        Data = new PathGeometry
                        {
                            Figures = new PathFigureCollection
                            {
                                new PathFigure
                                {
                                    StartPoint = new Point(-127, -104),
                                    Segments = new PathSegmentCollection
                                    {
                                        new LineSegment {
                                            Point = new Point(127, -104)
                                        },
                                        new LineSegment {
                                            Point = new Point(127, -139)
                                        },
                                        new LineSegment {
                                            Point = new Point(-127, -139)
                                        }
                                    }
                                }
                            }
                        }
                    });
            }
            }

            return(null);
        }
Beispiel #11
0
        /// <summary>
        /// Generate the installation rendering for the passed in symbol.
        /// </summary>
        /// <param name="ms">
        /// The military symbol for which to provide the installation rendering.
        /// </param>
        /// <param name="height">
        /// The height at which to provide the installation rendering.
        /// </param>
        /// <returns>
        /// The graphics Shape object that represents the installation rendering.
        /// </returns>
        private static Shape GenerateInstallation(MilSymbol ms, out double height)
        {
            ////    U&PGW   ZSGF      full unknown (flat)
            ////            AP        full air (not flat)
            ////            U         subsurface (flat)
            ////    N&L     ZSGF      full neutral (flat)
            ////            AP        full air (flat)
            ////            U         subsurface (flat)
            ////    H&S     ZSGF      full hostile (not flat)
            ////            AP        full air (not flat)
            ////            U         subsurface (flat)
            ////    F&ADMJK Z(IG)S    full friendly (not flat)
            ////            F(~IG)    full friendly (flat)
            ////            AP        full air (not flat)
            ////            U         subsurface  (flat)

            height = -185;
            Brush br = new SolidColorBrush(Colors.Black);
            int   si = StandardIdentity.GetNormalizedStandardIdentity(ms.SymbolCode);

            if (SymbolData.IsTopFlat(ms.SymbolCode))
            {
                double t = ms.BaseRect.Top;
                if (si == StandardIdentity.Unknown)
                {
                    t += SymbolData.HalfWidth;
                }

                height = t - 30;
                return(GenericInstallation(br, height, t));
            }

            int  bd = CategoryBattleDimension.GetCode(ms.SymbolCode);
            bool ap = bd == CategoryBattleDimension.BdSpace || bd == CategoryBattleDimension.BdAir;

            // The cases cover those surfaces which are flat on top versus those that are not
            switch (si)
            {
            case StandardIdentity.Unknown:
                // Outside for unknown space
                if (ap)
                {
                    return(UnknownSpaceInstallation(br, height));
                }

                return(UnknownGroundInstallation(br, height));

            case StandardIdentity.Hostile:
                // Outside for hostile space
                if (ap)
                {
                    height = -165;
                    return(HostileSpaceInstallation(br, height));
                }

                return(HostileGroundInstallation(br, height));

            case StandardIdentity.Friend:
                height = -175;

                // Outside for friendly space
                if (ap)
                {
                    return(FriendSpaceInstallation(br, height));
                }

                return(FriendCircleInstallation(br, height));
            }

            return(null);
        }
Beispiel #12
0
        /// <summary>
        /// Generate the task force rendering for the passed in symbol.
        /// </summary>
        /// <param name="ms">
        /// The military symbol for which to provide the task force rendering.
        /// </param>
        /// <param name="height">
        /// The height at which to provide the task force rendering.
        /// </param>
        /// <returns>
        /// The graphics Path object that represents the task force rendering.
        /// </returns>
        private static Path GenerateTaskForce(MilSymbol ms, out double height)
        {
            height = -185;
            double       bottom = 0;
            const double Wide   = 54;
            int          si     = StandardIdentity.GetNormalizedStandardIdentity(ms.SymbolCode);

            if (SymbolData.IsTopFlat(ms.SymbolCode))
            {
                bottom = ms.BaseRect.Top;
                if (si == StandardIdentity.Unknown)
                {
                    bottom += SymbolData.HalfWidth;
                }

                height = bottom - 75;
            }
            else
            {
                int  bd = CategoryBattleDimension.GetCode(ms.SymbolCode);
                bool ap = bd == CategoryBattleDimension.BdSpace || bd == CategoryBattleDimension.BdAir;

                // The cases cover those surfaces which are flat on top versus those that are not
                switch (si)
                {
                case StandardIdentity.Unknown:
                    if (ap)
                    {
                        height = -230;      // space
                        bottom = -133;
                    }
                    else
                    {
                        height = -250;      // ground
                        bottom = -154;
                    }

                    break;

                case StandardIdentity.Hostile:
                    if (ap)
                    {
                        height = -230;      // space
                        bottom = -107;
                    }
                    else
                    {
                        height = -253;      // ground
                        bottom = -119;
                    }

                    break;

                case StandardIdentity.Friend:
                    height = -222;
                    if (ap)
                    {
                        bottom = -121;      // space
                    }
                    else
                    {
                        bottom = -137;      // ground circles
                    }

                    break;
                }
            }

            return(new Path
            {
                Style = SymbolData.GetStyle("BS10"),
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        new PathFigure
                        {
                            StartPoint = new Point(Wide, bottom),
                            Segments = new PathSegmentCollection
                            {
                                new LineSegment {
                                    Point = new Point(Wide, height)
                                },
                                new LineSegment {
                                    Point = new Point(-Wide, height)
                                },
                                new LineSegment {
                                    Point = new Point(-Wide, bottom)
                                }
                            }
                        }
                    }
                }
            });
        }
Beispiel #13
0
        /// <summary>
        /// Return the headquarters factor to help position the headquarters staff
        /// </summary>
        /// <param name="sc">
        /// The symbol code for the headquarters.
        /// </param>
        /// <returns>
        /// A fractional offset as a double ranging from 0.0 to 1.0.
        /// </returns>
        internal static double GetHqFactor(string sc)
        {
            if (!Check(ref sc))
            {
                return(0);
            }

            int identityKey  = StandardIdentity.GetNormalizedStandardIdentity(sc);
            int dimensionKey = NormalizeBattleDimension(sc);

            switch (identityKey)
            {
            case StandardIdentity.Friend:
                if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(1.0);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(0.0);
                }

                if (dimensionKey == CategoryBattleDimension.BdSeaSurface ||
                    dimensionKey == CategoryBattleDimension.BdOther || IsEquipment(sc))
                {
                    return(0.5);    // of course there is no headquarters that is also equipment
                }

                return(1.0);

            case StandardIdentity.Hostile:
                if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(1.0);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(0.0);
                }

                return(0.5);

            case StandardIdentity.Neutral:
                return(1.0);

            case StandardIdentity.Unknown:
                if (dimensionKey == CategoryBattleDimension.BdSpace || dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(0.7);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(0.3);
                }

                return(0.5);
            }

            return(0.0);
        }
Beispiel #14
0
        /// <summary>
        /// This function returns the symbol bounds and some scaling factors
        /// (area and height) for the various standard symbol backgrounds.
        /// The exceptions to these sizes are the symbols that have headquarters
        /// or installations built-in.
        /// If that built-in is in the normal symbol code place (SymbolCode[10-11])
        /// we're OK.
        /// But the designers threw in a few curveballs that we're going to special
        /// case for now.
        /// </summary>
        /// <param name="sc">
        /// The symbol code.
        /// </param>
        /// <returns>
        /// A Scaling object representing the bounding rectangle and various scaling factors.
        /// </returns>
        public static Scaling GetScaling(string sc)
        {
            if (!Check(ref sc))
            {
                return(new Scaling(Rect.Empty, 300.0 * 300.0, 300.0));
            }

            int identityKey  = StandardIdentity.GetNormalizedStandardIdentity(sc);
            int dimensionKey = NormalizeBattleDimension(sc);

            switch (identityKey)
            {
            case StandardIdentity.Friend:
                if (dimensionKey == CategoryBattleDimension.BdSpace ||
                    dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(Rects["F137149A"]);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(Rects["F137149U"]);
                }

                if (dimensionKey == CategoryBattleDimension.BdSeaSurface ||
                    dimensionKey == CategoryBattleDimension.BdOther ||
                    IsEquipment(sc))
                {
                    return(Rects["F149149G"]);
                }

                return(Rects["F185125G"]);

            case StandardIdentity.Hostile:
                if (dimensionKey == CategoryBattleDimension.BdSpace ||
                    dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(Rects["H137161A"]);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(Rects["H137161U"]);
                }

                return(Rects["H180180G"]);

            case StandardIdentity.Neutral:
                if (dimensionKey == CategoryBattleDimension.BdSpace ||
                    dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(Rects["N137149A"]);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(Rects["N137149U"]);
                }

                return(Rects["N137137G"]);

            case StandardIdentity.Unknown:
                if (dimensionKey == CategoryBattleDimension.BdSpace ||
                    dimensionKey == CategoryBattleDimension.BdAir)
                {
                    return(Rects["U183161A"]);
                }

                if (dimensionKey == CategoryBattleDimension.BdSubsurface)
                {
                    return(Rects["U183161U"]);
                }

                return(Rects["U178178G"]);
            }

            return(new Scaling(Rect.Empty, 300.0 * 300.0, 300.0));
        }