// TODO: refactor and add tests
        private bool Matches(ISerializableEntity target, SerializableProperty property)
        {
            object propertyValue = property.GetValue(target);

            if (propertyValue == null)
            {
                DebugConsole.ThrowError("Couldn't compare " + AttributeValue.ToString() + " (" + AttributeValue.GetType() + ") to property \"" + property.Name + "\" - property.GetValue() returns null!");
                return(false);
            }

            Type  type          = propertyValue.GetType();
            float?floatProperty = null;

            if (type == typeof(float) || type == typeof(int))
            {
                floatProperty = (float)propertyValue;
            }

            switch (Operator)
            {
            case OperatorType.Equals:
                if (type == typeof(bool))
                {
                    return(((bool)propertyValue) == (AttributeValue == "true"));
                }
                else if (FloatValue == null)
                {
                    return(propertyValue.ToString().Equals(AttributeValue));
                }
                else
                {
                    return(propertyValue.Equals(FloatValue));
                }

            case OperatorType.NotEquals:
                if (type == typeof(bool))
                {
                    return(((bool)propertyValue) != (AttributeValue == "true"));
                }
                else if (FloatValue == null)
                {
                    return(!propertyValue.ToString().Equals(AttributeValue));
                }
                else
                {
                    return(!propertyValue.Equals(FloatValue));
                }

            case OperatorType.GreaterThan:
                if (FloatValue == null)
                {
                    DebugConsole.ThrowError("Couldn't compare " + AttributeValue.ToString() + " (" + AttributeValue.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
                                            + "Make sure the type of the value set in the config files matches the type of the property.");
                }
                else if (floatProperty > FloatValue)
                {
                    return(true);
                }
                break;

            case OperatorType.LessThan:
                if (FloatValue == null)
                {
                    DebugConsole.ThrowError("Couldn't compare " + AttributeValue.ToString() + " (" + AttributeValue.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
                                            + "Make sure the type of the value set in the config files matches the type of the property.");
                }
                else if (floatProperty < FloatValue)
                {
                    return(true);
                }
                break;

            case OperatorType.GreaterThanEquals:
                if (FloatValue == null)
                {
                    DebugConsole.ThrowError("Couldn't compare " + AttributeValue.ToString() + " (" + AttributeValue.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
                                            + "Make sure the type of the value set in the config files matches the type of the property.");
                }
                else if (floatProperty >= FloatValue)
                {
                    return(true);
                }
                break;

            case OperatorType.LessThanEquals:
                if (FloatValue == null)
                {
                    DebugConsole.ThrowError("Couldn't compare " + AttributeValue.ToString() + " (" + AttributeValue.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
                                            + "Make sure the type of the value set in the config files matches the type of the property.");
                }
                else if (floatProperty <= FloatValue)
                {
                    return(true);
                }
                break;
            }
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Upgrade the properties of an entity saved with an older version of the game. Properties that should be upgraded are defined using "Upgrade" elements in the config file.
        /// for example, <Upgrade gameversion="0.9.2.0" scale="0.5"/> would force the scale of the entity to 0.5 if it was saved with a version prior to 0.9.2.0.
        /// </summary>
        /// <param name="entity">The entity to upgrade</param>
        /// <param name="configElement">The XML element to get the upgrade instructions from (e.g. the config of an item prefab)</param>
        /// <param name="savedVersion">The game version the entity was saved with</param>
        public static void UpgradeGameVersion(ISerializableEntity entity, XElement configElement, Version savedVersion)
        {
            foreach (XElement subElement in configElement.Elements())
            {
                if (!subElement.Name.ToString().Equals("upgrade", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                var upgradeVersion = new Version(subElement.GetAttributeString("gameversion", "0.0.0.0"));
                if (savedVersion >= upgradeVersion)
                {
                    continue;
                }

                foreach (XAttribute attribute in subElement.Attributes())
                {
                    string attributeName = attribute.Name.ToString().ToLowerInvariant();
                    if (attributeName == "gameversion")
                    {
                        continue;
                    }
                    if (entity.SerializableProperties.TryGetValue(attributeName, out SerializableProperty property))
                    {
                        property.TrySetValue(entity, attribute.Value);
                    }
                    else if (entity is Item item1)
                    {
                        foreach (ISerializableEntity component in item1.AllPropertyObjects)
                        {
                            if (component.SerializableProperties.TryGetValue(attributeName, out SerializableProperty componentProperty))
                            {
                                componentProperty.TrySetValue(component, attribute.Value);
                            }
                        }
                    }
                }

                if (entity is Item item2)
                {
                    XElement componentElement = subElement.FirstElement();
                    if (componentElement == null)
                    {
                        continue;
                    }
                    ItemComponent itemComponent = item2.Components.First(c => c.Name == componentElement.Name.ToString());
                    if (itemComponent == null)
                    {
                        continue;
                    }
                    foreach (XElement element in componentElement.Elements())
                    {
                        switch (element.Name.ToString().ToLowerInvariant())
                        {
                        case "requireditem":
                        case "requireditems":
                            itemComponent.requiredItems.Clear();
                            itemComponent.DisabledRequiredItems.Clear();

                            itemComponent.SetRequiredItems(element);
                            break;
                        }
                    }
                }
            }
        }
        public bool Matches(ISerializableEntity target)
        {
            string valStr = AttributeValue.ToString();

            switch (Type)
            {
            case ConditionType.PropertyValue:
                SerializableProperty property;
                if (target.SerializableProperties.TryGetValue(AttributeName, out property))
                {
                    return(Matches(target, property));
                }
                return(false);

            case ConditionType.Name:
                return((Operator == OperatorType.Equals) == (target.Name == valStr));

            case ConditionType.HasTag:
            {
                string[] readTags = valStr.Split(',');
                int      matches  = 0;
                foreach (string tag in readTags)
                {
                    if (((Item)target).HasTag(tag))
                    {
                        matches++;
                    }
                }

                //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
                return(Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0);
            }

            case ConditionType.HasStatusTag:
                List <DurationListElement> durations = StatusEffect.DurationList.FindAll(d => d.Targets.Contains(target));
                List <DelayedListElement>  delays    = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));

                bool success = false;
                if (durations.Count > 0 || delays.Count > 0)
                {
                    string[] readTags = valStr.Split(',');
                    foreach (DurationListElement duration in durations)
                    {
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (duration.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }

                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            StatusEffect.DurationList.Remove(duration);
                        }
                        if (cancelStatusEffect != 2)     //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
                        {
                            return(success);
                        }
                    }
                    foreach (DelayedListElement delay in delays)
                    {
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (delay.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }

                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            DelayedEffect.DelayList.Remove(delay);
                        }
                        if (cancelStatusEffect != 2)     //ditto
                        {
                            return(success);
                        }
                    }
                }
                else if (Operator == OperatorType.NotEquals)
                {
                    //no status effects, so the tags cannot be equal -> condition met
                    return(true);
                }
                return(success);

            case ConditionType.SpeciesName:
                Character targetCharacter = target as Character;
                if (targetCharacter == null)
                {
                    return(false);
                }
                return((Operator == OperatorType.Equals) == (targetCharacter.SpeciesName == valStr));

            case ConditionType.Affliction:
                if (target is Character targetChar)
                {
                    var health = targetChar.CharacterHealth;
                    if (health == null)
                    {
                        return(false);
                    }
                    var affliction = health.GetAffliction(AttributeName);
                    if (affliction == null)
                    {
                        return(false);
                    }
                    if (FloatValue.HasValue)
                    {
                        float value = FloatValue.Value;
                        switch (Operator)
                        {
                        case OperatorType.Equals:
                            return(affliction.Strength == value);

                        case OperatorType.GreaterThan:
                            return(affliction.Strength > value);

                        case OperatorType.GreaterThanEquals:
                            return(affliction.Strength >= value);

                        case OperatorType.LessThan:
                            return(affliction.Strength < value);

                        case OperatorType.LessThanEquals:
                            return(affliction.Strength <= value);

                        case OperatorType.NotEquals:
                            return(affliction.Strength != value);
                        }
                    }
                }
                return(false);

            default:
                return(false);
            }
        }
예제 #4
0
        public bool Matches(ISerializableEntity target)
        {
            string valStr = AttributeValue.ToString();

            switch (Type)
            {
            case ConditionType.PropertyValue:
                SerializableProperty property;
                if (target?.SerializableProperties == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                if (target.SerializableProperties.TryGetValue(AttributeName, out property))
                {
                    return(Matches(target, property));
                }
                return(false);

            case ConditionType.Name:
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                return((Operator == OperatorType.Equals) == (target.Name == valStr));

            case ConditionType.HasTag:
            {
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                string[] readTags = valStr.Split(',');
                int      matches  = 0;
                foreach (string tag in readTags)
                {
                    if (target is Item item && item.HasTag(tag))
                    {
                        matches++;
                    }
                }
                //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
                return(Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0);
            }

            case ConditionType.HasStatusTag:
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                bool success = false;
                if (StatusEffect.DurationList.Any(d => d.Targets.Contains(target)) || DelayedEffect.DelayList.Any(d => d.Targets.Contains(target)))
                {
                    string[] readTags = valStr.Split(',');
                    foreach (DurationListElement duration in StatusEffect.DurationList)
                    {
                        if (!duration.Targets.Contains(target))
                        {
                            continue;
                        }
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (duration.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }
                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            StatusEffect.DurationList.Remove(duration);
                        }
                        if (cancelStatusEffect != 2)
                        {
                            //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
                            return(success);
                        }
                    }
                    foreach (DelayedListElement delay in DelayedEffect.DelayList)
                    {
                        if (!delay.Targets.Contains(target))
                        {
                            continue;
                        }
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (delay.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }
                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            DelayedEffect.DelayList.Remove(delay);
                        }
                        if (cancelStatusEffect != 2)
                        {
                            //ditto
                            return(success);
                        }
                    }
                }
                else if (Operator == OperatorType.NotEquals)
                {
                    //no status effects, so the tags cannot be equal -> condition met
                    return(true);
                }
                return(success);

            case ConditionType.SpeciesName:
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                if (!(target is Character targetCharacter))
                {
                    return(false);
                }
                return((Operator == OperatorType.Equals) == targetCharacter.SpeciesName.Equals(valStr, StringComparison.OrdinalIgnoreCase));

            case ConditionType.EntityType:
                switch (valStr)
                {
                case "character":
                case "Character":
                    return((Operator == OperatorType.Equals) == target is Character);

                case "limb":
                case "Limb":
                    return((Operator == OperatorType.Equals) == target is Limb);

                case "item":
                case "Item":
                    return((Operator == OperatorType.Equals) == target is Item);

                case "structure":
                case "Structure":
                    return((Operator == OperatorType.Equals) == target is Structure);

                case "null":
                    return((Operator == OperatorType.Equals) == (target == null));

                default:
                    return(false);
                }

            case ConditionType.LimbType:
            {
                if (!(target is Limb limb))
                {
                    return(false);
                }
예제 #5
0
        public static void SerializeProperties(ISerializableEntity obj, XElement element, bool saveIfDefault = false)
        {
            var saveProperties = GetProperties <Serialize>(obj);

            foreach (var property in saveProperties)
            {
                object value = property.GetValue(obj);
                if (value == null)
                {
                    continue;
                }

                if (!saveIfDefault)
                {
                    //only save
                    //  - if the attribute is saveable and it's different from the default value
                    //  - or can be changed in-game or in the editor
                    bool save = false;
                    foreach (var attribute in property.Attributes.OfType <Serialize>())
                    {
                        if ((attribute.isSaveable && !attribute.defaultValue.Equals(value)) ||
                            property.Attributes.OfType <Editable>().Any())
                        {
                            save = true;
                            break;
                        }
                    }

                    if (!save)
                    {
                        continue;
                    }
                }

                string stringValue;
                if (!supportedTypes.TryGetValue(value.GetType(), out string typeName))
                {
                    if (property.PropertyType.IsEnum)
                    {
                        stringValue = value.ToString();
                    }
                    else
                    {
                        DebugConsole.ThrowError("Failed to serialize the property \"" + property.Name + "\" of \"" + obj + "\" (type " + property.PropertyType + " not supported)");
                        continue;
                    }
                }
                else
                {
                    switch (typeName)
                    {
                    case "float":
                        //make sure the decimal point isn't converted to a comma or anything else
                        stringValue = ((float)value).ToString("G", CultureInfo.InvariantCulture);
                        break;

                    case "point":
                        stringValue = XMLExtensions.PointToString((Point)value);
                        break;

                    case "vector2":
                        stringValue = XMLExtensions.Vector2ToString((Vector2)value);
                        break;

                    case "vector3":
                        stringValue = XMLExtensions.Vector3ToString((Vector3)value);
                        break;

                    case "vector4":
                        stringValue = XMLExtensions.Vector4ToString((Vector4)value);
                        break;

                    case "color":
                        stringValue = XMLExtensions.ColorToString((Color)value);
                        break;

                    case "rectangle":
                        stringValue = XMLExtensions.RectToString((Rectangle)value);
                        break;

                    default:
                        stringValue = value.ToString();
                        break;
                    }
                }

                element.Attribute(property.Name)?.Remove();
                element.SetAttributeValue(property.NameToLowerInvariant, stringValue);
            }
        }
예제 #6
0
        public bool Matches(ISerializableEntity target)
        {
            if (TargetContainedItem)
            {
                if (target is Item item)
                {
                    return(item.ContainedItems.Any(it => Matches(it)));
                }
                else if (target is Items.Components.ItemComponent ic)
                {
                    return(ic.Item.ContainedItems.Any(it => Matches(it)));
                }
                else if (target is Character character)
                {
                    return(character.Inventory != null && character.Inventory.AllItems.Any(it => Matches(it)));
                }
            }

            switch (Type)
            {
            case ConditionType.PropertyValue:
                SerializableProperty property;
                if (target?.SerializableProperties == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                if (target.SerializableProperties.TryGetValue(AttributeName, out property))
                {
                    return(Matches(target, property));
                }
                return(false);

            case ConditionType.Name:
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                return((Operator == OperatorType.Equals) == (target.Name == AttributeValue));

            case ConditionType.HasTag:
            {
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                int matches = 0;
                foreach (string tag in SplitAttributeValue)
                {
                    if (target is Item item && item.HasTag(tag))
                    {
                        matches++;
                    }
                }
                //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
                return(Operator == OperatorType.Equals ? matches >= SplitAttributeValue.Length : matches <= 0);
            }

            case ConditionType.HasStatusTag:
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                bool success = false;
                if (StatusEffect.DurationList.Any(d => d.Targets.Contains(target)) || DelayedEffect.DelayList.Any(d => d.Targets.Contains(target)))
                {
                    int matches = 0;
                    foreach (DurationListElement durationEffect in StatusEffect.DurationList)
                    {
                        if (!durationEffect.Targets.Contains(target))
                        {
                            continue;
                        }
                        foreach (string tag in SplitAttributeValue)
                        {
                            if (durationEffect.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }
                        success = Operator == OperatorType.Equals ? matches >= SplitAttributeValue.Length : matches <= 0;
                    }
                    foreach (DelayedListElement delayedEffect in DelayedEffect.DelayList)
                    {
                        if (!delayedEffect.Targets.Contains(target))
                        {
                            continue;
                        }
                        foreach (string tag in SplitAttributeValue)
                        {
                            if (delayedEffect.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }
                    }
                    return(Operator == OperatorType.Equals ? matches >= SplitAttributeValue.Length : matches <= 0);
                }
                else if (Operator == OperatorType.NotEquals)
                {
                    //no status effects, so the tags cannot be equal -> condition met
                    return(true);
                }
                return(success);

            case ConditionType.SpeciesName:
            {
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                if (!(target is Character targetCharacter))
                {
                    return(false);
                }
                return(Operator == OperatorType.Equals == targetCharacter.SpeciesName.Equals(AttributeValue, StringComparison.OrdinalIgnoreCase));
            }

            case ConditionType.SpeciesGroup:
            {
                if (target == null)
                {
                    return(Operator == OperatorType.NotEquals);
                }
                if (!(target is Character targetCharacter))
                {
                    return(false);
                }
                return(Operator == OperatorType.Equals == targetCharacter.Params.CompareGroup(AttributeValue));
            }

            case ConditionType.EntityType:
                switch (AttributeValue)
                {
                case "character":
                case "Character":
                    return((Operator == OperatorType.Equals) == target is Character);

                case "limb":
                case "Limb":
                    return((Operator == OperatorType.Equals) == target is Limb);

                case "item":
                case "Item":
                    return((Operator == OperatorType.Equals) == target is Item);

                case "structure":
                case "Structure":
                    return((Operator == OperatorType.Equals) == target is Structure);

                case "null":
                    return((Operator == OperatorType.Equals) == (target == null));

                default:
                    return(false);
                }

            case ConditionType.LimbType:
            {
                if (!(target is Limb limb))
                {
                    return(false);
                }
예제 #7
0
        protected bool IsValidTarget(ISerializableEntity entity)
        {
            if (targetIdentifiers == null)
            {
                return(true);
            }

            if (entity is Item item)
            {
                if (targetIdentifiers.Contains("item"))
                {
                    return(true);
                }
                if (item.HasTag(targetIdentifiers))
                {
                    return(true);
                }
                if (targetIdentifiers.Any(id => id == item.Prefab.Identifier))
                {
                    return(true);
                }
            }
            else if (entity is ItemComponent itemComponent)
            {
                if (targetIdentifiers.Contains("itemcomponent"))
                {
                    return(true);
                }
                if (itemComponent.Item.HasTag(targetIdentifiers))
                {
                    return(true);
                }
                if (targetIdentifiers.Any(id => id == itemComponent.Item.Prefab.Identifier))
                {
                    return(true);
                }
            }
            else if (entity is Structure structure)
            {
                if (targetIdentifiers.Contains("structure"))
                {
                    return(true);
                }
                if (targetIdentifiers.Any(id => id == structure.Prefab.Identifier))
                {
                    return(true);
                }
            }
            else if (entity is Character character)
            {
                if (targetIdentifiers.Contains("character"))
                {
                    return(true);
                }
                if (targetIdentifiers.Any(id => id == character.SpeciesName))
                {
                    return(true);
                }
            }

            return(targetIdentifiers.Any(id => id == entity.Name));
        }
예제 #8
0
        private GUIComponent CreateColorField(ISerializableEntity entity, SerializableProperty property, Color value, int yPos, GUIComponent parent)
        {
            var label = new GUITextBlock(new Rectangle(0, yPos, 0, 18), property.Name, "", Alignment.TopLeft, Alignment.Left, parent, false, GUI.SmallFont);

            label.ToolTip = property.GetAttribute <Editable>().ToolTip;

            var colorBoxBack = new GUIFrame(new Rectangle(110 - 1, yPos - 1, 25 + 2, 18 + 2), Color.Black, Alignment.TopLeft, null, parent);
            var colorBox     = new GUIFrame(new Rectangle(110, yPos, 25, 18), value, Alignment.TopLeft, null, parent);

            for (int i = 0; i < 4; i++)
            {
                new GUITextBlock(new Rectangle(140 + i * 70, yPos, 100, 18), colorComponentLabels[i], "", Alignment.TopLeft, Alignment.CenterLeft, parent, false, GUI.SmallFont);
                GUINumberInput numberInput = new GUINumberInput(new Rectangle(160 + i * 70, yPos, 45, 18), "", GUINumberInput.NumberType.Int, Alignment.Left, parent);
                numberInput.MinValueInt = 0;
                numberInput.MaxValueInt = 255;

                if (i == 0)
                {
                    numberInput.IntValue = value.R;
                }
                else if (i == 1)
                {
                    numberInput.IntValue = value.G;
                }
                else if (i == 2)
                {
                    numberInput.IntValue = value.B;
                }
                else
                {
                    numberInput.IntValue = value.A;
                }

                numberInput.Font = GUI.SmallFont;

                int comp = i;
                numberInput.OnValueChanged += (numInput) =>
                {
                    Color newVal = (Color)property.GetValue();
                    if (comp == 0)
                    {
                        newVal.R = (byte)(numInput.IntValue);
                    }
                    else if (comp == 1)
                    {
                        newVal.G = (byte)(numInput.IntValue);
                    }
                    else if (comp == 2)
                    {
                        newVal.B = (byte)(numInput.IntValue);
                    }
                    else
                    {
                        newVal.A = (byte)(numInput.IntValue);
                    }

                    if (property.TrySetValue(newVal))
                    {
                        TrySendNetworkUpdate(entity, property);
                        colorBox.Color = newVal;
                    }
                };
            }

            return(label);
        }
예제 #9
0
        //private GUIComponent editingHUD;

        public SerializableEntityEditor(ISerializableEntity entity, bool inGame, GUIComponent parent, bool showName) : base("")
        {
            List <SerializableProperty> editableProperties = inGame ?
                                                             SerializableProperty.GetProperties <InGameEditable>(entity) :
                                                             SerializableProperty.GetProperties <Editable>(entity);

            if (parent != null)
            {
                parent.AddChild(this);
            }

            if (showName)
            {
                new GUITextBlock(new Rectangle(0, 0, 100, 20), entity.Name, "",
                                 Alignment.TopLeft, Alignment.TopLeft, this, false, GUI.Font);
            }

            int y = showName ? 30 : 10, padding = 10;

            foreach (var property in editableProperties)
            {
                //int boxHeight = 18;
                //var editable = property.Attributes.OfType<Editable>().FirstOrDefault();
                //if (editable != null) boxHeight = (int)(Math.Ceiling(editable.MaxLength / 40.0f) * 18.0f);

                object value = property.GetValue();

                GUIComponent propertyField = null;
                if (value is bool)
                {
                    propertyField = CreateBoolField(entity, property, (bool)value, y, this);
                }
                else if (value.GetType().IsEnum)
                {
                    propertyField = CreateEnumField(entity, property, value, y, this);
                }
                else if (value is string)
                {
                    propertyField = CreateStringField(entity, property, (string)value, y, this);
                }
                else if (value is int)
                {
                    propertyField = CreateIntField(entity, property, (int)value, y, this);
                }
                else if (value is float)
                {
                    propertyField = CreateFloatField(entity, property, (float)value, y, this);
                }
                else if (value is Vector2)
                {
                    propertyField = CreateVector2Field(entity, property, (Vector2)value, y, this);
                }
                else if (value is Vector3)
                {
                    propertyField = CreateVector3Field(entity, property, (Vector3)value, y, this);
                }
                else if (value is Vector4)
                {
                    propertyField = CreateVector4Field(entity, property, (Vector4)value, y, this);
                }
                else if (value is Color)
                {
                    propertyField = CreateColorField(entity, property, (Color)value, y, this);
                }
                else if (value is Rectangle)
                {
                    propertyField = CreateRectangleField(entity, property, (Rectangle)value, y, this);
                }

                if (propertyField != null)
                {
                    y += propertyField.Rect.Height + padding;
                }
            }

            if (children.Count > 0)
            {
                SetDimensions(new Point(Rect.Width, children.Last().Rect.Bottom - Rect.Y + 10), false);
            }
            else
            {
                SetDimensions(new Point(Rect.Width, 0), false);
            }

            if (parent is GUIListBox)
            {
                ((GUIListBox)parent).UpdateScrollBarSize();
            }
        }
        public bool Matches(ISerializableEntity target)
        {
            string valStr = Value.ToString();

            switch (Type)
            {
            case ConditionType.PropertyValue:
                SerializableProperty property;
                if (target.SerializableProperties.TryGetValue(PropertyName.ToLowerInvariant(), out property))
                {
                    return(Matches(property));
                }
                return(false);

            case ConditionType.Name:
                return((Operator == OperatorType.Equals) == (target.Name == valStr));

            case ConditionType.HasTag:
            {
                string[] readTags = valStr.Split(',');
                int      matches  = 0;
                foreach (string tag in readTags)
                {
                    if (((Item)target).HasTag(tag))
                    {
                        matches++;
                    }
                }

                //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
                return(Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0);
            }

            case ConditionType.HasStatusTag:
                List <DurationListElement> durations = StatusEffect.DurationList.FindAll(d => d.Targets.Contains(target));
                List <DelayedListElement>  delays    = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));

                bool success = false;
                if (durations.Count > 0 || delays.Count > 0)
                {
                    string[] readTags = valStr.Split(',');
                    foreach (DurationListElement duration in durations)
                    {
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (duration.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }

                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            StatusEffect.DurationList.Remove(duration);
                        }
                        if (cancelStatusEffect != 2)     //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
                        {
                            return(success);
                        }
                    }
                    foreach (DelayedListElement delay in delays)
                    {
                        int matches = 0;
                        foreach (string tag in readTags)
                        {
                            if (delay.Parent.HasTag(tag))
                            {
                                matches++;
                            }
                        }

                        success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
                        if (cancelStatusEffect > 0 && success)
                        {
                            DelayedEffect.DelayList.Remove(delay);
                        }
                        if (cancelStatusEffect != 2)     //ditto
                        {
                            return(success);
                        }
                    }
                }
                return(success);

            case ConditionType.SpeciesName:
                Character targetCharacter = target as Character;
                if (targetCharacter == null)
                {
                    return(false);
                }
                return((Operator == OperatorType.Equals) == (targetCharacter.SpeciesName == valStr));

            default:
                return(false);
            }
        }