Example #1
0
        // Indexes attributes.
        internal void Index()
        {
            LevelIndex.Clear();
            QualityIndex.Clear();

            if (Attributes == null)
            {
                return;
            }

            foreach (GemAttribute attr in Attributes)
            {
                LookupTable  levelTable    = new LookupTable();
                LookupTable  qualityTable  = new LookupTable();
                LookupRanges levelRanges   = new LookupRanges();
                LookupRanges qualityRanges = new LookupRanges();
                LookupGain   levelGain     = null;
                LookupGain   qualityGain   = null;
                LookupFixed  fixedValue    = null;

                foreach (Value value in attr.Values)
                {
                    // Ignore values which doesn't have required cardinality of attribute.
                    if (value.Cardinality != attr.Cardinality)
                    {
                        continue;
                    }

                    if (value is ValueAt)
                    {
                        ValueAt valueAt = (ValueAt)value;
                        if (valueAt.LevelSpecified)
                        {
                            levelTable.Add(valueAt.Level, valueAt.ToValue());
                        }
                        else if (valueAt.QualitySpecified)
                        {
                            qualityTable.Add(valueAt.Quality, valueAt.ToValue());
                        }
                        else
                        {
                            fixedValue = new LookupFixed {
                                Value = valueAt.ToValue()
                            }
                        };
                    }
                    else if (value is ValueForLevelRange)
                    {
                        ValueForLevelRange range = (ValueForLevelRange)value;
                        levelRanges.Add(range.From, range.To, range.ToValue());
                    }
                    else if (value is ValueForQualityRange)
                    {
                        ValueForQualityRange range = (ValueForQualityRange)value;
                        qualityRanges.Add(range.From, range.To, range.ToValue());
                    }
                    else if (value is ValuePerLevel)
                    {
                        levelGain = new LookupGain {
                            From = 2, Value = ((ValuePerLevel)value).ToValue()
                        };
                    }
                    else // value is ValuePerQuality
                    {
                        qualityGain = new LookupGain {
                            Value = ((ValuePerQuality)value).ToValue()
                        };
                    }
                }

                // Add level dependant attribute to index.
                // LookupFixed is added to LevelIndex only (due to quality-based attributes not being defined for non-quality gems).
                LookupBase.Method method = LookupBase.Method.None;
                if (!levelTable.IsEmpty())
                {
                    method |= LookupBase.Method.Table;
                }
                if (!levelRanges.IsEmpty())
                {
                    method |= LookupBase.Method.Range;
                }
                if (levelGain != null)
                {
                    method |= LookupBase.Method.Gain;
                }
                if (fixedValue != null)
                {
                    method |= LookupBase.Method.Fixed;
                }
                if (method != LookupBase.Method.None && method != LookupBase.Method.Table && method != LookupBase.Method.Range && method != LookupBase.Method.Gain &&
                    method != LookupBase.Method.Fixed)
                {
                    LevelIndex.Add(attr.Name, new LookupMixed
                    {
                        Table  = method.HasFlag(LookupBase.Method.Table) ? levelTable : null,
                        Ranges = method.HasFlag(LookupBase.Method.Range) ? levelRanges : null,
                        Gain   = method.HasFlag(LookupBase.Method.Gain) ? levelGain : null,
                        Fixed  = method.HasFlag(LookupBase.Method.Fixed) ? fixedValue : null
                    });
                }
                else if (method.HasFlag(LookupBase.Method.Table))
                {
                    LevelIndex.Add(attr.Name, levelTable);
                }
                else if (method.HasFlag(LookupBase.Method.Range))
                {
                    LevelIndex.Add(attr.Name, levelRanges);
                }
                else if (method.HasFlag(LookupBase.Method.Gain))
                {
                    LevelIndex.Add(attr.Name, levelGain);
                }
                else if (method.HasFlag(LookupBase.Method.Fixed))
                {
                    LevelIndex.Add(attr.Name, fixedValue);
                }

                // Add quality dependant attribute to index.
                method = LookupBase.Method.None;
                if (!qualityTable.IsEmpty())
                {
                    method |= LookupBase.Method.Table;
                }
                if (!qualityRanges.IsEmpty())
                {
                    method |= LookupBase.Method.Range;
                }
                if (qualityGain != null)
                {
                    method |= LookupBase.Method.Gain;
                }
                if (method != LookupBase.Method.None && method != LookupBase.Method.Table && method != LookupBase.Method.Range && method != LookupBase.Method.Gain)
                {
                    QualityIndex.Add(attr.Name, new LookupMixed
                    {
                        Table  = method.HasFlag(LookupBase.Method.Table) ? qualityTable : null,
                        Ranges = method.HasFlag(LookupBase.Method.Range) ? qualityRanges : null,
                        Gain   = method.HasFlag(LookupBase.Method.Gain) ? qualityGain : null
                    });
                }
                else if (method.HasFlag(LookupBase.Method.Table))
                {
                    QualityIndex.Add(attr.Name, qualityTable);
                }
                else if (method.HasFlag(LookupBase.Method.Range))
                {
                    QualityIndex.Add(attr.Name, qualityRanges);
                }
                else if (method.HasFlag(LookupBase.Method.Gain))
                {
                    QualityIndex.Add(attr.Name, qualityGain);
                }
            }
        }
Example #2
0
        // Cleans up redundancies.
        public void CleanUp()
        {
            // Replace ValueForRange where From == To with ValueAt.
            List <Value> values = Values.FindAll(v => v is ValueForLevelRange && ((ValueForLevelRange)v).From == ((ValueForLevelRange)v).To);

            if (values.Count > 0)
            {
                foreach (Value value in values)
                {
                    Replace(value, new ValueAt {
                        Level = ((ValueForLevelRange)value).From, Text = value.Text
                    });
                }
            }
            values = Values.FindAll(v => v is ValueForQualityRange && ((ValueForQualityRange)v).From == ((ValueForQualityRange)v).To);
            if (values.Count > 0)
            {
                foreach (Value value in values)
                {
                    Replace(value, new ValueAt {
                        Quality = ((ValueForQualityRange)value).From, Text = value.Text
                    });
                }
            }

            // Get level-based table values and perform redundancy checks.
            LookupTable    table;
            List <ValueAt> tableValues      = Values.FindAll(v => v is ValueAt && ((ValueAt)v).LevelSpecified).Cast <ValueAt>().ToList();
            bool           hasLevelTable    = false;
            bool           levelTableIsFull = false;

            if (tableValues.Count > 0)
            {
                float[] dummy = new float[] { 1 };
                table = new LookupTable();
                foreach (ValueAt value in tableValues)
                {
                    table.Add(value.Level, dummy);
                }

                hasLevelTable    = true;
                levelTableIsFull = table.IsFull();

                // Remove obsolete level ranges and per level gains.
                Values.RemoveAll(v => (v is ValueForLevelRange || v is ValuePerLevel) && table.IsCovering(v));
            }

            // Get quality-based table values and perform redundancy checks.
            tableValues = Values.FindAll(v => v is ValueAt && ((ValueAt)v).QualitySpecified).Cast <ValueAt>().ToList();
            bool qualityTableIsFull = false;

            if (tableValues.Count > 0)
            {
                float[] dummy = new float[] { 1 };
                table = new LookupTable();
                foreach (ValueAt value in tableValues)
                {
                    table.Add(value.Quality, dummy);
                }

                qualityTableIsFull = table.IsFull();

                // Remove obsolete quality ranges and per quality gains.
                Values.RemoveAll(v => v is ValueForQualityRange && table.IsCovering(v) || v is ValuePerQuality && qualityTableIsFull);
            }

            // Remove obsolete ValueAt for any level if level table is full.
            if (hasLevelTable && levelTableIsFull)
            {
                Values.RemoveAll(v => v is ValueAt && !((ValueAt)v).LevelSpecified && !((ValueAt)v).QualitySpecified);
            }

            LookupRanges ranges;
            List <ValueForLevelRange> levelRangeValues = Values.FindAll(v => v is ValueForLevelRange).Cast <ValueForLevelRange>().ToList();
            bool hasLevelRanges   = false;
            bool levelRangeIsFull = false;

            if (levelRangeValues.Count > 0)
            {
                float[] dummy = new float[] { 1 };
                ranges = new LookupRanges();
                foreach (ValueForLevelRange value in levelRangeValues)
                {
                    ranges.Add(value.From, value.To, dummy);
                }

                hasLevelRanges   = true;
                levelRangeIsFull = ranges.IsFull();

                // Remove obsolete level gains.
                Values.RemoveAll(v => v is ValuePerLevel && ranges.IsCovering(v));
            }

            List <ValueForQualityRange> qualityRangeValues = Values.FindAll(v => v is ValueForQualityRange).Cast <ValueForQualityRange>().ToList();
            bool qualityRangesIsFull = false;

            if (qualityRangeValues.Count > 0)
            {
                float[] dummy = new float[] { 1 };
                ranges = new LookupRanges();
                foreach (ValueForQualityRange value in qualityRangeValues)
                {
                    ranges.Add(value.From, value.To, dummy);
                }

                qualityRangesIsFull = ranges.IsFull();

                // Remove obsolete level gains.
                if (qualityRangesIsFull)
                {
                    Values.RemoveAll(v => v is ValuePerQuality);
                }
            }

            // Remove obsolete ValueAt for any level if level range is full.
            if (hasLevelRanges && levelRangeIsFull)
            {
                Values.RemoveAll(v => v is ValueAt && !((ValueAt)v).LevelSpecified && !((ValueAt)v).QualitySpecified);
            }
        }