Exemplo n.º 1
0
        public static void ParseEffectDefinition(VehicleEffectsDefinition.Vehicle vehicleDef, VehicleEffectsDefinition.Effect effectDef, List <VehicleInfo.Effect> effectsList, ref HashSet <string> parseErrors)
        {
            if (effectDef?.Name == null)
            {
                parseErrors.Add(vehicleDef.Name + " - Effect name missing.");
                return;
            }

            string effectName = (effectDef.Replacment == null) ? effectDef.Name : effectDef.Replacment;

            effectName += (effectDef.Base != null) ? " - " + effectDef.Base : "";

            var effectPrefab = FindEffect(effectName);

            if (effectPrefab == null)
            {
                //This effect is either a 'special' effect or simply non existent

                if (effectName.StartsWith("Vehicle Effect Wrapper"))
                {
                    // Wrapper for effects
                    if (effectDef.Base != null)
                    {
                        var baseEffect = FindEffect(effectDef.Base);
                        if (baseEffect != null)
                        {
                            effectPrefab = CustomVehicleEffect.CreateEffect(effectDef, baseEffect);
                            if (effectPrefab == null)
                            {
                                parseErrors.Add(vehicleDef.Name + ": An error occured trying to create a custom effect. Check debug log for details.");
                                return;
                            }
                        }
                        else
                        {
                            // Try fallback
                            if (effectDef.Fallback != null)
                            {
                                Logging.Log(vehicleDef.Name + ": trying to use fallback " + effectDef.Fallback + " for " + effectName);
                                if (effectDef.Fallback.StartsWith("None"))
                                {
                                    // None specified as fallback, just exit
                                    return;
                                }
                                else if (effectDef.Fallback.StartsWith("Remove") && effectDef.Replacment != null)
                                {
                                    // Remove the existing effect
                                    effectName   = "Remove";
                                    effectPrefab = null;
                                }
                                else
                                {
                                    baseEffect = FindEffect(effectDef.Fallback);
                                    if (baseEffect != null)
                                    {
                                        effectPrefab = CustomVehicleEffect.CreateEffect(effectDef, baseEffect);
                                        if (effectPrefab == null)
                                        {
                                            parseErrors.Add(vehicleDef.Name + ": An error occured trying to create a custom effect. Check debug log for details.");
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        parseErrors.Add(vehicleDef.Name + ": Vehicle Effect Wrapper fallback " + effectDef.Fallback + " was needed for " + effectDef.Base + " but not loaded either!");
                                    }
                                }
                            }
                            else
                            {
                                parseErrors.Add(vehicleDef.Name + ": Vehicle Effect Wrapper base effect " + effectDef.Base + " was not loaded and no fallback was specified!");
                                return;
                            }
                        }
                    }
                    else
                    {
                        parseErrors.Add(vehicleDef.Name + ": Vehicle Effect Wrapper requires a base effect but it wasn't given");
                        return;
                    }
                }
                else if (effectName.StartsWith("Vehicle Effect Multi"))
                {
                    // Custom MultiEffect defined in the xml
                    if (effectDef.SubEffects != null)
                    {
                        List <MultiEffect.SubEffect> loadedSubEffects = new List <MultiEffect.SubEffect>();
                        foreach (var subEffect in effectDef.SubEffects)
                        {
                            var dummyList = new List <VehicleInfo.Effect>();
                            ParseEffectDefinition(vehicleDef, subEffect.Effect, dummyList, ref parseErrors);
                            if (dummyList.Count > 0)
                            {
                                loadedSubEffects.Add(new MultiEffect.SubEffect()
                                {
                                    m_effect      = dummyList[0].m_effect,
                                    m_endTime     = subEffect.EndTime,
                                    m_startTime   = subEffect.StartTime,
                                    m_probability = subEffect.Probability
                                });
                            }
                        }
                        effectPrefab = CustomVehicleMultiEffect.CreateEffect(effectDef, loadedSubEffects.ToArray(), effectDef.Duration, effectDef.UseSimulationTime);
                    }
                    else
                    {
                        parseErrors.Add(vehicleDef.Name + " Vehicle Effect Multi with no sub effects!");
                        return;
                    }
                }
                else if (effectName.StartsWith("None") || effectName.StartsWith("Remove"))
                {
                    // Not a real effect, but keywords used for removal of an existing effect.
                    // 'None' included for < 1.2c compatibility
                    effectName   = "Remove";
                    effectPrefab = null;
                }
                else
                {
                    // Try fallback
                    if (effectDef.Fallback != null)
                    {
                        Logging.Log(vehicleDef.Name + ": trying to use fallback " + effectDef.Fallback + " for " + effectName);
                        if (effectDef.Fallback.StartsWith("None"))
                        {
                            // None specified as fallback, just exit
                            return;
                        }
                        else if (effectDef.Fallback.StartsWith("Remove") && effectDef.Replacment != null)
                        {
                            // Remove the existing effect
                            effectName   = "Remove";
                            effectPrefab = null;
                        }
                        else
                        {
                            effectPrefab = FindEffect(effectDef.Fallback);
                            if (effectPrefab == null)
                            {
                                parseErrors.Add(vehicleDef.Name + " requested non-existing effect " + effectName + " and fallback " + effectDef.Fallback + " could not be found either!");
                                return;
                            }
                        }
                    }
                    else
                    {
                        parseErrors.Add(vehicleDef.Name + " requested non-existing effect " + effectName + " and no fallback was specified");
                        return;
                    }
                }
            }

            if (effectPrefab == null && !effectName.Equals("Remove"))
            {
                parseErrors.Add(vehicleDef.Name + " - Effect with name " + effectDef.Name + " not loaded.");
                return;
            }

            var vehicleInfoEffect = new VehicleInfo.Effect
            {
                m_effect = effectPrefab,
                m_parkedFlagsForbidden  = VehicleParked.Flags.Created,
                m_parkedFlagsRequired   = VehicleParked.Flags.None,
                m_vehicleFlagsForbidden = (Vehicle.Flags)effectDef.ForbiddenFlags,
                m_vehicleFlagsRequired  = ((Vehicle.Flags)effectDef.RequiredFlags) | Vehicle.Flags.Created
            };

            if (effectDef.Replacment == null)
            {
                effectsList.Add(vehicleInfoEffect);
            }
            else
            {
                int indexToRemove = -1;

                for (int i = 0; i < effectsList.Count; i++)
                {
                    if (effectsList[i].m_effect.name.Equals(effectDef.Name))
                    {
                        if (effectDef.Replacment.Equals("Remove"))
                        {
                            indexToRemove = i;
                            break;
                        }

                        effectsList[i] = vehicleInfoEffect;
                        break;
                    }
                }

                if (indexToRemove >= 0)
                {
                    effectsList.RemoveAt(indexToRemove);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Applies a vehicle definition vehicle entry.
        /// </summary>
        /// <param name="vehicleDef">Vehicle definition to parse.</param>
        /// <param name="packageName">Package name used in error messages.</param>
        /// <param name="backup">Used to store original effect array.</param>
        /// <param name="parseErrors">HashSet to add parse errors to.</param>
        /// <param name="noParseErrors">Optional: If true no vehicle related parse errors are given.</param>
        /// <param name="vehicleDefPrefab">Optional: VehicleInfo to apply definition to.</param>
        public static void ParseVehicleDefinition(VehicleEffectsDefinition.Vehicle vehicleDef, string packageName, ref Dictionary <VehicleInfo, VehicleInfo.Effect[]> backup, ref HashSet <string> parseErrors, bool noParseErrors = false, VehicleInfo vehicleDefPrefab = null)
        {
            if (vehicleDef?.Name == null)
            {
                if (!noParseErrors)
                {
                    parseErrors.Add(packageName + " - Vehicle name missing.");
                }
                return;
            }

            if (vehicleDefPrefab == null)
            {
                vehicleDefPrefab = FindVehicle(vehicleDef.Name, packageName);
            }


            if (vehicleDefPrefab == null)
            {
                if (!noParseErrors)
                {
                    parseErrors.Add(packageName + " - Vehicle with name " + vehicleDef.Name + " not loaded.");
                }
                return;
            }

            if (vehicleDef.Effects == null || vehicleDef.Effects.Count == 0)
            {
                if (!noParseErrors)
                {
                    parseErrors.Add(packageName + " - No effects specified for " + vehicleDef.Name + ".");
                }
                return;
            }


            if (vehicleDef.ApplyToTrailersOnly)
            {
                HashSet <VehicleInfo> trailers = new HashSet <VehicleInfo>();
                foreach (var trailer in vehicleDefPrefab.m_trailers)
                {
                    if (!trailers.Contains(trailer.m_info))
                    {
                        trailers.Add(trailer.m_info);
                    }
                }

                foreach (var trailer in trailers)
                {
                    var trailerDef = new VehicleEffectsDefinition.Vehicle();
                    trailerDef.Name    = trailer.name;
                    trailerDef.Effects = vehicleDef.Effects;
                    ParseVehicleDefinition(trailerDef, packageName, ref backup, ref parseErrors, noParseErrors, trailer);
                }

                return;
            }


            // Backup default effects array
            if (!backup.ContainsKey(vehicleDefPrefab))
            {
                var effects = new VehicleInfo.Effect[vehicleDefPrefab.m_effects.Length];
                vehicleDefPrefab.m_effects.CopyTo(effects, 0);
                backup.Add(vehicleDefPrefab, effects);
            }


            var vehicleEffectsList = new List <VehicleInfo.Effect>();

            vehicleEffectsList.AddRange(vehicleDefPrefab.m_effects);

            foreach (var effectDef in vehicleDef.Effects)
            {
                ParseEffectDefinition(vehicleDef, effectDef, vehicleEffectsList, ref parseErrors);
            }

            // Remove and log null effects
            for (int i = vehicleEffectsList.Count - 1; i >= 0; i--)
            {
                if (vehicleEffectsList[i].m_effect == null)
                {
                    Logging.LogWarning("Found effect that is NULL for vehicle " + vehicleDef.Name + " at index " + i + ", removing.");
                    vehicleEffectsList.RemoveAt(i);
                }
            }

            // Update the VehicleInfo with the new effects
            vehicleDefPrefab.m_effects = vehicleEffectsList.ToArray();


            // taken from VehicleInfo.InitializePrefab
            if (vehicleDefPrefab.m_effects != null)
            {
                for (int j = 0; j < vehicleDefPrefab.m_effects.Length; j++)
                {
                    if (vehicleDefPrefab.m_effects[j].m_effect != null)
                    {
                        vehicleDefPrefab.m_effects[j].m_effect.InitializeEffect();
                    }
                }
            }
        }