public static RelatedItem Load(XElement element)
        {
            string nameString = element.GetAttributeString("name", "");

            if (nameString == "")
            {
                return(null);
            }

            string[] names = nameString.Split(',');

            RelatedItem ri = new RelatedItem(names);

            try
            {
                ri.type = (RelationType)Enum.Parse(typeof(RelationType), element.GetAttributeString("type", "None"));
            }

            catch
            {
                ri.type = RelationType.None;
            }

            ri.Msg = element.GetAttributeString("msg", "");

            foreach (XElement subElement in element.Elements())
            {
                if (subElement.Name.ToString().ToLowerInvariant() != "statuseffect")
                {
                    continue;
                }

                ri.statusEffects.Add(StatusEffect.Load(subElement));
            }

            return(ri);
        }
예제 #2
0
        protected override void Act(float deltaTime)
        {
            // Only continue when the get item sub objectives have been completed.
            if (subObjectives.Any())
            {
                return;
            }
            foreach (Repairable repairable in Item.Repairables)
            {
                if (!repairable.HasRequiredItems(character, false))
                {
                    //make sure we have all the items required to fix the target item
                    foreach (var kvp in repairable.requiredItems)
                    {
                        foreach (RelatedItem requiredItem in kvp.Value)
                        {
                            subObjectives.Add(new AIObjectiveGetItem(character, requiredItem.Identifiers, objectiveManager, true));
                        }
                    }
                    return;
                }
            }
            if (repairTool == null)
            {
                FindRepairTool();
            }
            if (repairTool != null)
            {
                var containedItems = repairTool.Item.ContainedItems;
                if (containedItems == null)
                {
#if DEBUG
                    DebugConsole.ThrowError($"{character.Name}: AIObjectiveRepairItem failed - the item \"" + repairTool + "\" has no proper inventory");
#endif
                    Abandon = true;
                    return;
                }
                // Drop empty tanks
                foreach (Item containedItem in containedItems)
                {
                    if (containedItem == null)
                    {
                        continue;
                    }
                    if (containedItem.Condition <= 0.0f)
                    {
                        containedItem.Drop(character);
                    }
                }
                RelatedItem item = null;
                Item        fuel = null;
                foreach (RelatedItem requiredItem in repairTool.requiredItems[RelatedItem.RelationType.Contained])
                {
                    item = requiredItem;
                    fuel = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it));
                    if (fuel != null)
                    {
                        break;
                    }
                }
                if (fuel == null)
                {
                    RemoveSubObjective(ref goToObjective);
                    TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, item.Identifiers, repairTool.Item.GetComponent <ItemContainer>(), objectiveManager),
                                       onCompleted: () => RemoveSubObjective(ref refuelObjective),
                                       onAbandon: () => Abandon = true);
                    return;
                }
            }
            if (character.CanInteractWith(Item, out _, checkLinked: false))
            {
                HumanAIController.FaceTarget(Item);
                if (repairTool != null)
                {
                    OperateRepairTool(deltaTime);
                }
                foreach (Repairable repairable in Item.Repairables)
                {
                    if (repairable.CurrentFixer != null && repairable.CurrentFixer != character)
                    {
                        // Someone else is repairing the target. Abandon the objective if the other is better at this than us.
                        Abandon = repairable.DegreeOfSuccess(character) < repairable.DegreeOfSuccess(repairable.CurrentFixer);
                    }
                    if (!Abandon)
                    {
                        if (character.SelectedConstruction != Item)
                        {
                            if (!Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true) &&
                                !Item.TryInteract(character, ignoreRequiredItems: true, forceActionKey: true))
                            {
                                Abandon = true;
                            }
                        }
                        if (previousCondition == -1)
                        {
                            previousCondition = Item.Condition;
                        }
                        else if (Item.Condition < previousCondition)
                        {
                            // If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it.
                            Abandon = true;
                        }
                    }
                    if (Abandon)
                    {
                        if (IsRepairing)
                        {
                            character.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
                        }
                        repairable.StopRepairing(character);
                    }
                    else if (repairable.CurrentFixer != character)
                    {
                        repairable.StartRepairing(character, Repairable.FixActions.Repair);
                    }
                    break;
                }
            }
            else
            {
                RemoveSubObjective(ref refuelObjective);
                // If cannot reach the item, approach it.
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    previousCondition = -1;
                    var objective     = new AIObjectiveGoTo(Item, character, objectiveManager)
                    {
                        // Don't stop in ladders, because we can't interact with other items while holding the ladders.
                        endNodeFilter = node => node.Waypoint.Ladders == null
                    };
                    if (repairTool != null)
                    {
                        objective.CloseEnough = repairTool.Range * 0.75f;
                    }
                    return(objective);
                },
                                   onAbandon: () =>
                {
                    Abandon = true;
                    if (IsRepairing)
                    {
                        character.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
                    }
                });
            }
        }
예제 #3
0
        public static RelatedItem Load(XElement element, string parentDebugName)
        {
            string[] identifiers;
            if (element.Attribute("name") != null)
            {
                //backwards compatibility + a console warning
                DebugConsole.ThrowError("Error in RelatedItem config (" + (string.IsNullOrEmpty(parentDebugName) ? element.ToString() : parentDebugName) + ") - use item identifiers or tags instead of names.");
                string[] itemNames = element.GetAttributeStringArray("name", new string[0]);
                //attempt to convert to identifiers and tags
                List <string> convertedIdentifiers = new List <string>();
                foreach (string itemName in itemNames)
                {
                    if (MapEntityPrefab.List.Find(me => me.Name == itemName) is ItemPrefab matchingItem)
                    {
                        convertedIdentifiers.Add(matchingItem.Identifier);
                    }
                    else
                    {
                        //no matching item found, this must be a tag
                        convertedIdentifiers.Add(itemName);
                    }
                }
                identifiers = convertedIdentifiers.ToArray();
            }
            else
            {
                identifiers = element.GetAttributeStringArray("identifiers", new string[0]);
                if (identifiers.Length == 0)
                {
                    identifiers = element.GetAttributeStringArray("identifier", new string[0]);
                }
            }

            string[] excludedIdentifiers = element.GetAttributeStringArray("excludedidentifiers", new string[0]);
            if (excludedIdentifiers.Length == 0)
            {
                excludedIdentifiers = element.GetAttributeStringArray("excludedidentifier", new string[0]);
            }

            if (identifiers.Length == 0 && excludedIdentifiers.Length == 0)
            {
                return(null);
            }

            RelatedItem ri = new RelatedItem(identifiers, excludedIdentifiers);

            string typeStr = element.GetAttributeString("type", "");

            if (string.IsNullOrEmpty(typeStr))
            {
                if (element.Name.ToString().ToLowerInvariant() == "containable")
                {
                    typeStr = "Contained";
                }
            }
            if (!Enum.TryParse(typeStr, true, out ri.type))
            {
                DebugConsole.ThrowError("Error in RelatedItem config (" + parentDebugName + ") - \"" + typeStr + "\" is not a valid relation type.");
                return(null);
            }

            string msgTag = element.GetAttributeString("msg", "");
            string msg    = TextManager.Get(msgTag, true);

            if (msg == null)
            {
                ri.Msg = msgTag;
            }
            else
            {
#if CLIENT
                foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
                {
                    msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
                }
                ri.Msg = msg;
#endif
            }

            foreach (XElement subElement in element.Elements())
            {
                if (subElement.Name.ToString().ToLowerInvariant() != "statuseffect")
                {
                    continue;
                }
                ri.statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
            }

            ri.IsOptional = element.GetAttributeBool("optional", false);
            return(ri);
        }
예제 #4
0
        protected StatusEffect(XElement element, string parentDebugName)
        {
            requiredItems    = new List <RelatedItem>();
            spawnItems       = new List <ItemSpawnInfo>();
            Afflictions      = new List <Affliction>();
            ReduceAffliction = new List <Pair <string, float> >();
            tags             = new HashSet <string>(element.GetAttributeString("tags", "").Split(','));

            Range = element.GetAttributeFloat("range", 0.0f);

            IEnumerable <XAttribute> attributes         = element.Attributes();
            List <XAttribute>        propertyAttributes = new List <XAttribute>();

            propertyConditionals = new List <PropertyConditional>();

            foreach (XAttribute attribute in attributes)
            {
                switch (attribute.Name.ToString())
                {
                case "type":
                    if (!Enum.TryParse(attribute.Value, true, out type))
                    {
                        DebugConsole.ThrowError("Invalid action type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")");
                    }
                    break;

                case "target":
                    string[] Flags = attribute.Value.Split(',');
                    foreach (string s in Flags)
                    {
                        if (!Enum.TryParse(s, true, out TargetType targetType))
                        {
                            DebugConsole.ThrowError("Invalid target type \"" + s + "\" in StatusEffect (" + parentDebugName + ")");
                        }
                        else
                        {
                            targetTypes |= targetType;
                        }
                    }
                    break;

                case "disabledeltatime":
                    disableDeltaTime = attribute.GetAttributeBool(false);
                    break;

                case "setvalue":
                    setValue = attribute.GetAttributeBool(false);
                    break;

                case "targetnames":
                    DebugConsole.ThrowError("Error in StatusEffect config (" + parentDebugName + ") - use identifiers or tags to define the targets instead of names.");
                    break;

                case "targetidentifiers":
                    string[] identifiers = attribute.Value.Split(',');
                    targetIdentifiers = new HashSet <string>();
                    for (int i = 0; i < identifiers.Length; i++)
                    {
                        targetIdentifiers.Add(identifiers[i].Trim().ToLowerInvariant());
                    }
                    break;

                case "duration":
                    duration = attribute.GetAttributeFloat(0.0f);
                    break;

                case "stackable":
                    Stackable = attribute.GetAttributeBool(true);
                    break;

                case "checkconditionalalways":
                    CheckConditionalAlways = attribute.GetAttributeBool(false);
                    break;

                case "conditionalcomparison":
                case "comparison":
                    if (!Enum.TryParse(attribute.Value, out conditionalComparison))
                    {
                        DebugConsole.ThrowError("Invalid conditional comparison type \"" + attribute.Value + "\" in StatusEffect (" + parentDebugName + ")");
                    }
                    break;

                case "sound":
                    DebugConsole.ThrowError("Error in StatusEffect " + element.Parent.Name.ToString() +
                                            " - sounds should be defined as child elements of the StatusEffect, not as attributes.");
                    break;

                default:
                    propertyAttributes.Add(attribute);
                    break;
                }
            }

            int count = propertyAttributes.Count;

            propertyNames   = new string[count];
            propertyEffects = new object[count];

            int n = 0;

            foreach (XAttribute attribute in propertyAttributes)
            {
                propertyNames[n]   = attribute.Name.ToString().ToLowerInvariant();
                propertyEffects[n] = XMLExtensions.GetAttributeObject(attribute);
                n++;
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "explosion":
                    explosion = new Explosion(subElement, parentDebugName);
                    break;

                case "fire":
                    FireSize = subElement.GetAttributeFloat("size", 10.0f);
                    break;

                case "use":
                case "useitem":
                    useItemCount++;
                    break;

                case "remove":
                case "removeitem":
                    removeItem = true;
                    break;

                case "requireditem":
                case "requireditems":
                    RelatedItem newRequiredItem = RelatedItem.Load(subElement, parentDebugName);
                    if (newRequiredItem == null)
                    {
                        DebugConsole.ThrowError("Error in StatusEffect config - requires an item with no identifiers.");
                        continue;
                    }
                    requiredItems.Add(newRequiredItem);
                    break;

                case "conditional":
                    IEnumerable <XAttribute> conditionalAttributes = subElement.Attributes();
                    foreach (XAttribute attribute in conditionalAttributes)
                    {
                        if (attribute.Name.ToString().ToLowerInvariant() == "targetitemcomponent")
                        {
                            continue;
                        }
                        propertyConditionals.Add(new PropertyConditional(attribute));
                    }
                    break;

                case "affliction":
                    AfflictionPrefab afflictionPrefab;
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers instead of names.");
                        string afflictionName = subElement.GetAttributeString("name", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Name.ToLowerInvariant() == afflictionName);
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab \"" + afflictionName + "\" not found.");
                            continue;
                        }
                    }
                    else
                    {
                        string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Identifier.ToLowerInvariant() == afflictionIdentifier);
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab with the identifier \"" + afflictionIdentifier + "\" not found.");
                            continue;
                        }
                    }

                    float afflictionStrength = subElement.GetAttributeFloat(1.0f, "amount", "strength");
                    Afflictions.Add(afflictionPrefab.Instantiate(afflictionStrength));

                    break;

                case "reduceaffliction":
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers or types instead of names.");
                        ReduceAffliction.Add(new Pair <string, float>(
                                                 subElement.GetAttributeString("name", "").ToLowerInvariant(),
                                                 subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount")));
                    }
                    else
                    {
                        string name = subElement.GetAttributeString("identifier", null) ?? subElement.GetAttributeString("type", null);
                        name = name.ToLowerInvariant();

                        if (AfflictionPrefab.List.Any(ap => ap.Identifier == name || ap.AfflictionType == name))
                        {
                            ReduceAffliction.Add(new Pair <string, float>(
                                                     name,
                                                     subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount")));
                        }
                        else
                        {
                            DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - Affliction prefab with the identifier or type \"" + name + "\" not found.");
                        }
                    }
                    break;

                case "spawnitem":
                    var newSpawnItem = new ItemSpawnInfo(subElement, parentDebugName);
                    if (newSpawnItem.ItemPrefab != null)
                    {
                        spawnItems.Add(newSpawnItem);
                    }
                    break;
                }
            }
            InitProjSpecific(element, parentDebugName);
        }
예제 #5
0
        /// <summary>
        /// Reloads the ammunition found in the inventory.
        /// If seekAmmo is true, tries to get find the ammo elsewhere.
        /// </summary>
        private bool Reload(bool seekAmmo)
        {
            if (WeaponComponent == null)
            {
                return(false);
            }
            if (!WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained))
            {
                return(false);
            }
            var containedItems = Weapon.ContainedItems;

            // Drop empty ammo
            foreach (Item containedItem in containedItems)
            {
                if (containedItem == null)
                {
                    continue;
                }
                if (containedItem.Condition <= 0)
                {
                    containedItem.Drop(character);
                }
            }
            RelatedItem item       = null;
            Item        ammunition = null;

            string[] ammunitionIdentifiers = null;
            foreach (RelatedItem requiredItem in WeaponComponent.requiredItems[RelatedItem.RelationType.Contained])
            {
                ammunition = containedItems.FirstOrDefault(it => it.Condition > 0 && requiredItem.MatchesItem(it));
                if (ammunition != null)
                {
                    // Ammunition still remaining
                    return(true);
                }
                item = requiredItem;
                ammunitionIdentifiers = requiredItem.Identifiers;
            }
            // No ammo
            if (ammunition == null)
            {
                if (ammunitionIdentifiers != null)
                {
                    // Try reload ammunition from inventory
                    ammunition = character.Inventory.FindItem(i => ammunitionIdentifiers.Any(id => id == i.Prefab.Identifier || i.HasTag(id)) && i.Condition > 0, true);
                    if (ammunition != null)
                    {
                        var container = Weapon.GetComponent <ItemContainer>();
                        if (container.Item.ParentInventory == character.Inventory)
                        {
                            if (!container.Inventory.CanBePut(ammunition))
                            {
                                return(false);
                            }
                            character.Inventory.RemoveItem(ammunition);
                            if (!container.Inventory.TryPutItem(ammunition, null))
                            {
                                ammunition.Drop(character);
                            }
                        }
                        else
                        {
                            container.Combine(ammunition, character);
                        }
                    }
                }
            }
            if (WeaponComponent.HasRequiredContainedItems(character, addMessage: false))
            {
                return(true);
            }
            else if (ammunition == null && !HoldPosition && initialMode == CombatMode.Offensive && seekAmmo && ammunitionIdentifiers != null)
            {
                SeekAmmunition(ammunitionIdentifiers);
            }
            return(false);
        }
예제 #6
0
        public static RelatedItem Load(XElement element, bool returnEmpty, string parentDebugName)
        {
            string[] identifiers;
            if (element.Attribute("name") != null)
            {
                //backwards compatibility + a console warning
                DebugConsole.ThrowError("Error in RelatedItem config (" + (string.IsNullOrEmpty(parentDebugName) ? element.ToString() : parentDebugName) + ") - use item tags or identifiers instead of names.");
                string[] itemNames = element.GetAttributeStringArray("name", new string[0]);
                //attempt to convert to identifiers and tags
                List <string> convertedIdentifiers = new List <string>();
                foreach (string itemName in itemNames)
                {
                    var matchingItem = ItemPrefab.Prefabs.Find(me => me.Name == itemName);
                    if (matchingItem != null)
                    {
                        convertedIdentifiers.Add(matchingItem.Identifier);
                    }
                    else
                    {
                        //no matching item found, this must be a tag
                        convertedIdentifiers.Add(itemName);
                    }
                }
                identifiers = convertedIdentifiers.ToArray();
            }
            else
            {
                identifiers = element.GetAttributeStringArray("items", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("item", null, convertToLowerInvariant: true);
                if (identifiers == null)
                {
                    identifiers = element.GetAttributeStringArray("identifiers", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("tags", null, convertToLowerInvariant: true);
                    if (identifiers == null)
                    {
                        identifiers = element.GetAttributeStringArray("identifier", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("tag", new string[0], convertToLowerInvariant: true);
                    }
                }
            }

            string[] excludedIdentifiers = element.GetAttributeStringArray("excludeditems", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludeditem", null, convertToLowerInvariant: true);
            if (excludedIdentifiers == null)
            {
                excludedIdentifiers = element.GetAttributeStringArray("excludedidentifiers", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludedtags", null, convertToLowerInvariant: true);
                if (excludedIdentifiers == null)
                {
                    excludedIdentifiers = element.GetAttributeStringArray("excludedidentifier", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludedtag", new string[0], convertToLowerInvariant: true);
                }
            }

            if (identifiers.Length == 0 && excludedIdentifiers.Length == 0 && !returnEmpty)
            {
                return(null);
            }

            RelatedItem ri      = new RelatedItem(identifiers, excludedIdentifiers);
            string      typeStr = element.GetAttributeString("type", "");

            if (string.IsNullOrEmpty(typeStr))
            {
                switch (element.Name.ToString().ToLowerInvariant())
                {
                case "containable":
                    typeStr = "Contained";
                    break;

                case "suitablefertilizer":
                case "suitableseed":
                    typeStr = "None";
                    break;
                }
            }
            if (!Enum.TryParse(typeStr, true, out ri.type))
            {
                DebugConsole.ThrowError("Error in RelatedItem config (" + parentDebugName + ") - \"" + typeStr + "\" is not a valid relation type.");
                return(null);
            }

            ri.MsgTag = element.GetAttributeString("msg", "");
            string msg = TextManager.Get(ri.MsgTag, true);

            if (msg == null)
            {
                ri.Msg = ri.MsgTag;
            }
            else
            {
#if CLIENT
                foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
                {
                    msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBindText(inputType));
                }
                ri.Msg = msg;
#endif
            }

            foreach (XElement subElement in element.Elements())
            {
                if (!subElement.Name.ToString().Equals("statuseffect", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                ri.statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
            }

            ri.IsOptional     = element.GetAttributeBool("optional", false);
            ri.IgnoreInEditor = element.GetAttributeBool("ignoreineditor", false);
            ri.MatchOnEmpty   = element.GetAttributeBool("matchonempty", false);
            return(ri);
        }
예제 #7
0
        protected StatusEffect(XElement element)
        {
            requiredItems = new List <RelatedItem>();

#if CLIENT
            particleEmitters = new List <ParticleEmitterPrefab>();
#endif

            IEnumerable <XAttribute> attributes         = element.Attributes();
            List <XAttribute>        propertyAttributes = new List <XAttribute>();

            foreach (XAttribute attribute in attributes)
            {
                switch (attribute.Name.ToString())
                {
                case "type":
                    try
                    {
                        type = (ActionType)Enum.Parse(typeof(ActionType), attribute.Value, true);
                    }

                    catch
                    {
                        string[] split = attribute.Value.Split('=');
                        type = (ActionType)Enum.Parse(typeof(ActionType), split[0], true);

                        string[] containingNames = split[1].Split(',');
                        onContainingNames = new HashSet <string>();
                        for (int i = 0; i < containingNames.Length; i++)
                        {
                            onContainingNames.Add(containingNames[i].Trim());
                        }
                    }

                    break;

                case "target":
                    string[] Flags = attribute.Value.Split(',');
                    foreach (string s in Flags)
                    {
                        targetTypes |= (TargetType)Enum.Parse(typeof(TargetType), s, true);
                    }

                    break;

                case "disabledeltatime":
                    disableDeltaTime = ToolBox.GetAttributeBool(attribute, false);
                    break;

                case "setvalue":
                    setValue = ToolBox.GetAttributeBool(attribute, false);
                    break;

                case "targetnames":
                    string[] names = attribute.Value.Split(',');
                    targetNames = new HashSet <string>();
                    for (int i = 0; i < names.Length; i++)
                    {
                        targetNames.Add(names[i].Trim());
                    }
                    break;

                case "duration":
                    duration = ToolBox.GetAttributeFloat(attribute, 0.0f);
                    break;

#if CLIENT
                case "sound":
                    sound = Sound.Load(attribute.Value.ToString());
                    break;
#endif
                default:
                    propertyAttributes.Add(attribute);
                    break;
                }
            }

            int count = propertyAttributes.Count;
            propertyNames   = new string[count];
            propertyEffects = new object[count];

            int n = 0;
            foreach (XAttribute attribute in propertyAttributes)
            {
                propertyNames[n]   = attribute.Name.ToString().ToLowerInvariant();
                propertyEffects[n] = ToolBox.GetAttributeObject(attribute);
                n++;
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "explosion":
                    explosion = new Explosion(subElement);
                    break;

                case "fire":
                    FireSize = ToolBox.GetAttributeFloat(subElement, "size", 10.0f);
                    break;

                case "use":
                case "useitem":
                    useItem = true;
                    break;

                case "requireditem":
                case "requireditems":
                    RelatedItem newRequiredItem = RelatedItem.Load(subElement);

                    if (newRequiredItem == null)
                    {
                        continue;
                    }

                    requiredItems.Add(newRequiredItem);
                    break;

#if CLIENT
                case "particleemitter":
                    particleEmitters.Add(new ParticleEmitterPrefab(subElement));
                    break;
#endif
                }
            }
        }
예제 #8
0
        protected StatusEffect(XElement element)
        {
            requiredItems = new List <RelatedItem>();
            tags          = new HashSet <string>(element.GetAttributeString("tags", "").Split(','));

#if CLIENT
            particleEmitters = new List <ParticleEmitter>();
#endif

            IEnumerable <XAttribute> attributes         = element.Attributes();
            List <XAttribute>        propertyAttributes = new List <XAttribute>();
            propertyConditionals = new List <PropertyConditional>();

            foreach (XAttribute attribute in attributes)
            {
                switch (attribute.Name.ToString())
                {
                case "type":
                    try
                    {
                        type = (ActionType)Enum.Parse(typeof(ActionType), attribute.Value, true);
                    }

                    catch
                    {
                        string[] split = attribute.Value.Split('=');
                        type = (ActionType)Enum.Parse(typeof(ActionType), split[0], true);

                        string[] containingNames = split[1].Split(',');
                        onContainingNames = new HashSet <string>();
                        for (int i = 0; i < containingNames.Length; i++)
                        {
                            onContainingNames.Add(containingNames[i].Trim());
                        }
                    }

                    break;

                case "target":
                    string[] Flags = attribute.Value.Split(',');
                    foreach (string s in Flags)
                    {
                        targetTypes |= (TargetType)Enum.Parse(typeof(TargetType), s, true);
                    }

                    break;

                case "disabledeltatime":
                    disableDeltaTime = attribute.GetAttributeBool(false);
                    break;

                case "setvalue":
                    setValue = attribute.GetAttributeBool(false);
                    break;

                case "targetnames":
                    string[] names = attribute.Value.Split(',');
                    targetNames = new HashSet <string>();
                    for (int i = 0; i < names.Length; i++)
                    {
                        targetNames.Add(names[i].Trim());
                    }
                    break;

                case "duration":
                    duration = attribute.GetAttributeFloat(0.0f);
                    break;

                case "stackable":
                    Stackable = attribute.GetAttributeBool(true);
                    break;

                case "checkconditionalalways":
                    CheckConditionalAlways = attribute.GetAttributeBool(false);
                    break;

                case "sound":
                    DebugConsole.ThrowError("Error in StatusEffect " + element.Parent.Name.ToString() +
                                            " - sounds should be defined as child elements of the StatusEffect, not as attributes.");
                    break;

                default:
                    propertyAttributes.Add(attribute);
                    break;
                }
            }

            int count = propertyAttributes.Count;
            propertyNames   = new string[count];
            propertyEffects = new object[count];

            int n = 0;
            foreach (XAttribute attribute in propertyAttributes)
            {
                propertyNames[n]   = attribute.Name.ToString().ToLowerInvariant();
                propertyEffects[n] = XMLExtensions.GetAttributeObject(attribute);
                n++;
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "explosion":
                    explosion = new Explosion(subElement);
                    break;

                case "fire":
                    FireSize = subElement.GetAttributeFloat("size", 10.0f);
                    break;

                case "use":
                case "useitem":
                    useItemCount++;
                    break;

                case "remove":
                case "removeitem":
                    removeItem = true;
                    break;

                case "requireditem":
                case "requireditems":
                    RelatedItem newRequiredItem = RelatedItem.Load(subElement);

                    if (newRequiredItem == null)
                    {
                        continue;
                    }

                    requiredItems.Add(newRequiredItem);
                    break;

                case "conditional":
                    IEnumerable <XAttribute> conditionalAttributes = subElement.Attributes();
                    foreach (XAttribute attribute in conditionalAttributes)
                    {
                        propertyConditionals.Add(new PropertyConditional(attribute));
                    }
                    break;

#if CLIENT
                case "particleemitter":
                    particleEmitters.Add(new ParticleEmitter(subElement));
                    break;

                case "sound":
                    sound     = Sound.Load(subElement);
                    loopSound = subElement.GetAttributeBool("loop", false);
                    break;
#endif
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Reloads the ammunition found in the inventory.
        /// If seekAmmo is true and the condition is met or not provided, tries to get find the ammo elsewhere.
        /// </summary>
        private bool Reload(bool seekAmmo, Func <bool> condition = null)
        {
            if (WeaponComponent == null)
            {
                return(false);
            }
            if (!WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained))
            {
                return(false);
            }
            var         containedItems = Weapon.ContainedItems;
            RelatedItem item           = null;
            Item        ammunition     = null;

            string[] ammunitionIdentifiers = null;
            foreach (RelatedItem requiredItem in WeaponComponent.requiredItems[RelatedItem.RelationType.Contained])
            {
                ammunition = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it));
                if (ammunition != null)
                {
                    // Ammunition still remaining
                    return(true);
                }
                item = requiredItem;
                ammunitionIdentifiers = requiredItem.Identifiers;
            }
            // No ammo
            if (ammunition == null)
            {
                var container = Weapon.GetComponent <ItemContainer>();
                // Try reload ammunition in inventory
                foreach (string identifier in ammunitionIdentifiers)
                {
                    foreach (var i in character.Inventory.Items)
                    {
                        if (i == null)
                        {
                            continue;
                        }
                        if (i.Prefab.Identifier == identifier || i.HasTag(identifier))
                        {
                            if (i.Condition > 0)
                            {
                                container.Inventory.TryPutItem(ammunition, null);
                            }
                        }
                    }
                }
            }
            if (WeaponComponent.HasRequiredContainedItems(false))
            {
                return(true);
            }
            else if (ammunition == null)
            {
                if (seekAmmo && ammunitionIdentifiers != null && (condition == null || condition()))
                {
                    SeekAmmunition(ammunitionIdentifiers);
                }
            }
            return(false);
        }