Пример #1
0
        void AddToQueue(List <Package.Asset>[] queues, CustomAssetMetaData meta, int offset, bool dontSpawn)
        {
            Package.Asset assetRef = meta.assetRef;

            if (assetRef == null)
            {
                Util.DebugPrint(meta.name, " Warning : NULL asset");
                return;
            }

            CustomAssetMetaData.Type type = meta.type;
            Package package  = assetRef.package;
            string  fullName = type < CustomAssetMetaData.Type.RoadElevation ? assetRef.fullName : PillarOrElevationName(package.packageName, assetRef.name);

            if (!IsDuplicate(fullName, allLoads[(int)type], package))
            {
                queues[loadQueueIndex[(int)type] + offset].Add(assetRef);
                metaTypes[assetRef.fullName] = type;

                if (dontSpawn)
                {
                    dontSpawnNormally.Add(fullName);
                }

                if (type == CustomAssetMetaData.Type.Citizen)
                {
                    citizenMetaDatas[fullName] = meta;
                }
            }
        }
Пример #2
0
        void AddToQueue(List <Package.Asset>[] queues, CustomAssetMetaData meta, CustomAssetMetaData.Type type, int offset, bool dontSpawn)
        {
            Package.Asset assetRef = meta.assetRef;

            if (assetRef == null)
            {
                Util.DebugPrint(meta.name, " Error : NULL asset");
                return;
            }

            if (assetRef.fullName == null)
            {
                Util.DebugPrint(meta.name, " Warning : NULL asset name");
            }

            Package package  = assetRef.package;
            string  fullName = type < CustomAssetMetaData.Type.RoadElevation ? assetRef.fullName : PillarOrElevationName(package.packageName, assetRef.name);

            if (!IsDuplicate(assetRef, type, queues))
            {
                int index = Math.Max(loadQueueIndex[(int)type] + offset, 0);
                queues[index].Add(assetRef);
                metaDatas[assetRef.fullName] = new SomeMetaData(meta.userDataRef, meta.name, type);

                if (dontSpawn)
                {
                    dontSpawnNormally.Add(fullName);
                }

                if (type == CustomAssetMetaData.Type.Citizen)
                {
                    citizenMetaDatas[fullName] = meta;
                }
            }
        }
Пример #3
0
        static void AddRef(PrefabInfo info, string fullName, CustomAssetMetaData.Type type)
        {
            if (info == null)
            {
                if (type == CustomAssetMetaData.Type.Prop && instance.skipProps && SkippedProps.Contains(fullName))
                {
                    return;
                }

                // The referenced asset is missing.
                Package.Asset container = FindContainer();

                if (container != null)
                {
                    AssetReport.instance.AddReference(container, fullName, type);
                }
            }
            else if (info.m_isCustomContent)
            {
                string        r         = info.name;
                Package.Asset container = FindContainer();

                if (!string.IsNullOrEmpty(r) && container != null)
                {
                    string packageName = container.package.packageName;
                    int    i           = r.IndexOf('.');
                    string r2;

                    if (i >= 0 && (i != packageName.Length || !r.StartsWith(packageName)) && (r2 = FindMain(r)) != null)
                    {
                        AssetReport.instance.AddReference(container, r2, type);
                    }
                }
            }
        }
Пример #4
0
 internal void AddMissing(string fullName, CustomAssetMetaData.Type type)
 {
     if (!assets.TryGetValue(fullName, out Item child))
     {
         assets.Add(fullName, new Missing(fullName, type, useddir: true));
     }
     else
     {
         child.UsedDir = true;
     }
 }
Пример #5
0
        internal void AddReference(Package.Asset knownRef, string fullName, CustomAssetMetaData.Type type)
        {
            if (!assets.TryGetValue(fullName, out Item child))
            {
                assets.Add(fullName, child = new Missing(fullName, type));
            }
            else
            {
                child.type = type;
            }

            assets[knownRef.fullName].Add(child);
        }
Пример #6
0
        bool IsDuplicate(Package.Asset assetRef, CustomAssetMetaData.Type type, List <Package.Asset>[] queues)
        {
            string fullName = assetRef.fullName;

            if (!queuedLoads[(int)type].Add(fullName))
            {
                if (suspects.TryGetValue(fullName, out List <Package.Asset> assets))
                {
                    assets.Add(assetRef);
                }
                else
                {
                    int   index   = loadQueueIndex[(int)type];
                    int[] indices = index > 0 ? new int[] { index, index - 1 } : new int[] { index };

                    foreach (int i in indices)
                    {
                        foreach (Package.Asset a in queues[i])
                        {
                            if (fullName == a.fullName)
                            {
                                suspects.Add(fullName, new List <Package.Asset>(2)
                                {
                                    a, assetRef
                                });
                                return(true);
                            }
                        }
                    }

                    suspects.Add(fullName, new List <Package.Asset>(2)
                    {
                        assetRef
                    });
                }

                return(true);
            }

            return(false);
        }
Пример #7
0
        void Load(Package.Asset asset)
        {
            string fullName = null;

            try
            {
                CustomAssetMetaData assetMetaData = asset.Instantiate <CustomAssetMetaData>();

                // Always remember: assetRef may point to another package because the deserialization method accepts any asset with a matching checksum.
                // There is a bug in the 1.6.0 game update in this.
                fullName = asset.package.packageName + "." + assetMetaData.assetRef.name;

                CustomAssetMetaData.Type type = assetMetaData.type;
                bool spawnNormally            = (type == CustomAssetMetaData.Type.Building || type == CustomAssetMetaData.Type.SubBuilding) ?
                                                loadEnabled && IsEnabled(asset) || loadUsed && UsedAssets.instance.GotBuilding(fullName) : true;
                stack.Clear();
                LoadImpl(fullName, assetMetaData.assetRef, spawnNormally);
            }
            catch (Exception e)
            {
                AssetFailed(fullName ?? asset.fullName, e);
            }
        }
Пример #8
0
        static void ReportMissingAssets <P>(HashSet <string> customAssets, CustomAssetMetaData.Type type) where P : PrefabInfo
        {
            try
            {
                bool reportAssets = Settings.settings.reportAssets;

                foreach (string fullName in customAssets)
                {
                    if (CustomDeserializer.FindLoaded <P>(fullName, tryName:false) == null)
                    {
                        AssetLoader.instance.NotFound(fullName);

                        if (reportAssets)
                        {
                            AssetReport.instance.AddMissing(fullName, type);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogException(e);
            }
        }
        internal static object CustomDeserialize(Package p, Type t, PackageReader r)
        {
            // Props and trees in buildings and parks.
            if (t == typeof(BuildingInfo.Prop))
            {
                PropInfo pi = Get <PropInfo>(r.ReadString()); // old name format (without package name) is possible
                TreeInfo ti = Get <TreeInfo>(r.ReadString()); // old name format (without package name) is possible

                if (instance.report && UsedAssets.instance.GotAnyContainer())
                {
                    if (pi != null)
                    {
                        string n = pi.gameObject.name;

                        if (!string.IsNullOrEmpty(n) && n.IndexOf('.') >= 0)
                        {
                            UsedAssets.instance.IndirectProps.Add(n);
                        }
                    }

                    if (ti != null)
                    {
                        string n = ti.gameObject.name;

                        if (!string.IsNullOrEmpty(n) && n.IndexOf('.') >= 0)
                        {
                            UsedAssets.instance.IndirectTrees.Add(n);
                        }
                    }
                }

                return(new BuildingInfo.Prop
                {
                    m_prop = pi,
                    m_tree = ti,
                    m_position = r.ReadVector3(),
                    m_angle = r.ReadSingle(),
                    m_probability = r.ReadInt32(),
                    m_fixedHeight = r.ReadBoolean()
                });
            }

            // Paths (nets) in buildings.
            if (t == typeof(BuildingInfo.PathInfo))
            {
                string  fullName           = r.ReadString();
                NetInfo ni                 = Get <NetInfo>(fullName);
                BuildingInfo.PathInfo path = new BuildingInfo.PathInfo();
                path.m_netInfo         = ni;
                path.m_nodes           = r.ReadVector3Array();
                path.m_curveTargets    = r.ReadVector3Array();
                path.m_invertSegments  = r.ReadBoolean();
                path.m_maxSnapDistance = r.ReadSingle();

                if (p.version >= 5)
                {
                    path.m_forbidLaneConnection = r.ReadBooleanArray();
                    path.m_trafficLights        = (BuildingInfo.TrafficLights[])(object) r.ReadInt32Array();
                    path.m_yieldSigns           = r.ReadBooleanArray();
                }

                return(path);
            }

            if (t == typeof(Package.Asset))
            {
                return(r.ReadAsset(p));
            }

            // It seems that trailers are listed in the save game so this is not necessary. Better to be safe however
            // because a missing trailer reference is fatal for the simulation thread.
            if (t == typeof(VehicleInfo.VehicleTrailer))
            {
                string      name     = r.ReadString();
                string      fullName = p.packageName + "." + name;
                VehicleInfo vi       = Get <VehicleInfo>(p, fullName, name, false);

                VehicleInfo.VehicleTrailer trailer;
                trailer.m_info              = vi;
                trailer.m_probability       = r.ReadInt32();
                trailer.m_invertProbability = r.ReadInt32();
                return(trailer);
            }

            if (t == typeof(NetInfo.Lane))
            {
                return(new NetInfo.Lane
                {
                    m_position = r.ReadSingle(),
                    m_width = r.ReadSingle(),
                    m_verticalOffset = r.ReadSingle(),
                    m_stopOffset = r.ReadSingle(),
                    m_speedLimit = r.ReadSingle(),
                    m_direction = (NetInfo.Direction)r.ReadInt32(),
                    m_laneType = (NetInfo.LaneType)r.ReadInt32(),
                    m_vehicleType = (VehicleInfo.VehicleType)r.ReadInt32(),
                    m_stopType = (VehicleInfo.VehicleType)r.ReadInt32(),
                    m_laneProps = GetNetLaneProps(p, r),
                    m_allowConnect = r.ReadBoolean(),
                    m_useTerrainHeight = r.ReadBoolean(),
                    m_centerPlatform = r.ReadBoolean(),
                    m_elevated = r.ReadBoolean()
                });
            }

            if (t == typeof(NetInfo.Segment))
            {
                NetInfo.Segment segment  = new NetInfo.Segment();
                string          checksum = r.ReadString();
                segment.m_mesh              = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, true);
                checksum                    = r.ReadString();
                segment.m_material          = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, true);
                checksum                    = r.ReadString();
                segment.m_lodMesh           = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, false);
                checksum                    = r.ReadString();
                segment.m_lodMaterial       = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, false);
                segment.m_forwardRequired   = (NetSegment.Flags)r.ReadInt32();
                segment.m_forwardForbidden  = (NetSegment.Flags)r.ReadInt32();
                segment.m_backwardRequired  = (NetSegment.Flags)r.ReadInt32();
                segment.m_backwardForbidden = (NetSegment.Flags)r.ReadInt32();
                segment.m_emptyTransparent  = r.ReadBoolean();
                segment.m_disableBendNodes  = r.ReadBoolean();
                return(segment);
            }

            if (t == typeof(NetInfo.Node))
            {
                NetInfo.Node node     = new NetInfo.Node();
                string       checksum = r.ReadString();
                node.m_mesh             = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, true);
                checksum                = r.ReadString();
                node.m_material         = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, true);
                checksum                = r.ReadString();
                node.m_lodMesh          = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMesh(checksum, p, false);
                checksum                = r.ReadString();
                node.m_lodMaterial      = string.IsNullOrEmpty(checksum) ? null : Sharing.instance.GetMaterial(checksum, p, false);
                node.m_flagsRequired    = (NetNode.Flags)r.ReadInt32();
                node.m_flagsForbidden   = (NetNode.Flags)r.ReadInt32();
                node.m_connectGroup     = (NetInfo.ConnectGroup)r.ReadInt32();
                node.m_directConnect    = r.ReadBoolean();
                node.m_emptyTransparent = r.ReadBoolean();
                return(node);
            }

            if (t == typeof(NetInfo))
            {
                string name = r.ReadString();
                CustomAssetMetaData.Type type = AssetLoader.instance.GetMetaType(AssetLoader.instance.Current);

                if (type == CustomAssetMetaData.Type.Road || type == CustomAssetMetaData.Type.RoadElevation)
                {
                    return(Get <NetInfo>(p, name));
                }
                else
                {
                    return(Get <NetInfo>(name));
                }
            }

            if (t == typeof(BuildingInfo))
            {
                string name = r.ReadString();
                CustomAssetMetaData.Type type = AssetLoader.instance.GetMetaType(AssetLoader.instance.Current);

                if (type == CustomAssetMetaData.Type.Road || type == CustomAssetMetaData.Type.RoadElevation)
                {
                    return(Get <BuildingInfo>(p, name));
                }
                else
                {
                    return(Get <BuildingInfo>(name));
                }
            }

            // Sub-buildings in buildings.
            if (t == typeof(BuildingInfo.SubInfo))
            {
                string       name     = r.ReadString();
                string       fullName = p.packageName + "." + name;
                BuildingInfo bi       = null;

                if (fullName == AssetLoader.instance.Current.fullName || name == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a sub-building for itself");
                }
                else
                {
                    bi = Get <BuildingInfo>(p, fullName, name, true);
                }

                BuildingInfo.SubInfo subInfo = new BuildingInfo.SubInfo();
                subInfo.m_buildingInfo = bi;
                subInfo.m_position     = r.ReadVector3();
                subInfo.m_angle        = r.ReadSingle();
                subInfo.m_fixedHeight  = r.ReadBoolean();
                return(subInfo);
            }

            // Prop variations in props.
            if (t == typeof(PropInfo.Variation))
            {
                string   name     = r.ReadString();
                string   fullName = p.packageName + "." + name;
                PropInfo pi       = null;

                if (fullName == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a prop variation for itself");
                }
                else
                {
                    pi = Get <PropInfo>(p, fullName, name, false);
                }

                return(new PropInfo.Variation
                {
                    m_prop = pi,
                    m_probability = r.ReadInt32()
                });
            }

            // Tree variations in trees.
            if (t == typeof(TreeInfo.Variation))
            {
                string   name     = r.ReadString();
                string   fullName = p.packageName + "." + name;
                TreeInfo ti       = null;

                if (fullName == AssetLoader.instance.Current.fullName)
                {
                    Util.DebugPrint("Warning:", fullName, "wants to be a tree variation for itself");
                }
                else
                {
                    ti = Get <TreeInfo>(p, fullName, name, false);
                }

                return(new TreeInfo.Variation
                {
                    m_tree = ti,
                    m_probability = r.ReadInt32()
                });
            }

            if (t == typeof(VehicleInfo.MeshInfo))
            {
                VehicleInfo.MeshInfo meshinfo = new VehicleInfo.MeshInfo();
                string checksum = r.ReadString();

                if (!string.IsNullOrEmpty(checksum))
                {
                    Package.Asset asset = p.FindByChecksum(checksum);
                    GameObject    go    = AssetDeserializer.Instantiate(asset) as GameObject;
                    meshinfo.m_subInfo = go.GetComponent <VehicleInfoBase>();
                    go.SetActive(false);

                    if (meshinfo.m_subInfo.m_lodObject != null)
                    {
                        meshinfo.m_subInfo.m_lodObject.SetActive(false);
                    }
                }
                else
                {
                    meshinfo.m_subInfo = null;
                }

                meshinfo.m_vehicleFlagsForbidden = (Vehicle.Flags)r.ReadInt32();
                meshinfo.m_vehicleFlagsRequired  = (Vehicle.Flags)r.ReadInt32();
                meshinfo.m_parkedFlagsForbidden  = (VehicleParked.Flags)r.ReadInt32();
                meshinfo.m_parkedFlagsRequired   = (VehicleParked.Flags)r.ReadInt32();
                return(meshinfo);
            }

            return(PackageHelper.CustomDeserialize(p, t, r));
        }
Пример #10
0
        Package.Asset[] GetLoadQueue(HashSet <string> styleBuildings)
        {
            Package[] packages = PackageManager.allPackages.ToArray();
            Array.Sort(packages, (a, b) => string.Compare(a.packageName, b.packageName));
            List <Package.Asset>       assets = new List <Package.Asset>(8);
            List <CustomAssetMetaData> metas  = new List <CustomAssetMetaData>(8);

            // Why this load order? By having related and identical assets close to each other, we get more loader cache hits (of meshes and textures)
            // in Sharing. We also get faster disk reads.
            // [0] propvar and prop, citizen  [1] prop, tree  [2] pillar and elevation and road  [3] road
            // [4] sub-building and building  [5] building    [6] trailer and vehicle            [7] vehicle
            List <Package.Asset>[] queues = { new List <Package.Asset>(4), new List <Package.Asset>(64), new List <Package.Asset>(4),  new List <Package.Asset>(4),
                                              new List <Package.Asset>(4), new List <Package.Asset>(64), new List <Package.Asset>(32), new List <Package.Asset>(32) };

            SteamHelper.DLC_BitMask notMask = ~SteamHelper.GetOwnedDLCMask();
            bool loadEnabled = Settings.settings.loadEnabled, loadUsed = Settings.settings.loadUsed, report = loadUsed && Settings.settings.reportAssets;

            //PrintPackages(packages);

            foreach (Package p in packages)
            {
                CustomAssetMetaData meta = null;

                try
                {
                    assets.Clear();
                    assets.AddRange(p.FilterAssets(UserAssetType.CustomAssetMetaData));

                    if (assets.Count == 0)
                    {
                        continue;
                    }

                    if (report)
                    {
                        AssetReport.instance.AddPackage(p);
                    }

                    bool enabled = loadEnabled && IsEnabled(p);

                    if (assets.Count == 1) // the common case
                    {
                        bool want = enabled || styleBuildings.Contains(assets[0].fullName);

                        // Fast exit.
                        if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                        {
                            continue;
                        }

                        meta = AssetDeserializer.Instantiate(assets[0]) as CustomAssetMetaData;
                        bool used = loadUsed && UsedAssets.instance.IsUsed(meta);

                        if (used || want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0)
                        {
                            CustomAssetMetaData.Type type = meta.type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            AddToQueue(queues, meta, offset, !(enabled | used));
                        }
                    }
                    else
                    {
                        bool want = enabled;

                        // Fast exit.
                        if (!want)
                        {
                            for (int i = 0; i < assets.Count; i++)
                            {
                                want = want || styleBuildings.Contains(assets[i].fullName);
                            }

                            if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                            {
                                continue;
                            }
                        }

                        metas.Clear();
                        bool used = false;

                        for (int i = 0; i < assets.Count; i++)
                        {
                            meta = AssetDeserializer.Instantiate(assets[i]) as CustomAssetMetaData;
                            metas.Add(meta);
                            want = want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0;
                            used = used || loadUsed && UsedAssets.instance.IsUsed(meta);
                        }

                        if (want | used)
                        {
                            metas.Sort((a, b) => b.type - a.type); // prop variation, sub-building, trailer, elevation, pillar before main asset
                            CustomAssetMetaData.Type type = metas[0].type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            bool dontSpawn = !(enabled | used);

                            for (int i = 0; i < metas.Count; i++)
                            {
                                AddToQueue(queues, metas[i], offset, dontSpawn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    AssetFailed(meta?.assetRef?.fullName ?? p.packageName + "." + p.packageMainAsset, e);
                }
            }

            Package.Asset[] queue = new Package.Asset[queues.Select(lst => lst.Count).Sum()];

            for (int i = 0, k = 0; i < queues.Length; k += queues[i].Count, i++)
            {
                queues[i].CopyTo(queue, k);
            }

            return(queue);
        }
Пример #11
0
        internal void LoadImpl(Package.Asset assetRef)
        {
            try
            {
                stack.Push(assetRef);
                LoadingManager.instance.m_loadingProfilerCustomAsset.BeginLoading(AssetName(assetRef.name));
                GameObject go = AssetDeserializer.Instantiate(assetRef) as GameObject;
                CustomAssetMetaData.Type type = GetMetaType(assetRef);
                string packageName            = assetRef.package.packageName;
                string fullName = type < CustomAssetMetaData.Type.RoadElevation ? packageName + "." + go.name : PillarOrElevationName(packageName, go.name);
                go.name = fullName;
                go.SetActive(false);
                PrefabInfo info = go.GetComponent <PrefabInfo>();
                info.m_isCustomContent = true;

                if (info.m_Atlas != null && !string.IsNullOrEmpty(info.m_InfoTooltipThumbnail) && info.m_Atlas[info.m_InfoTooltipThumbnail] != null)
                {
                    info.m_InfoTooltipAtlas = info.m_Atlas;
                }

                PropInfo pi = go.GetComponent <PropInfo>();

                if (pi != null)
                {
                    if (pi.m_lodObject != null)
                    {
                        pi.m_lodObject.SetActive(false);
                    }

                    Initialize(pi);
                    loadedProps.Add(fullName);
                }

                TreeInfo ti = go.GetComponent <TreeInfo>();

                if (ti != null)
                {
                    Initialize(ti);
                    loadedTrees.Add(fullName);
                }

                BuildingInfo bi = go.GetComponent <BuildingInfo>();

                if (bi != null)
                {
                    if (bi.m_lodObject != null)
                    {
                        bi.m_lodObject.SetActive(false);
                    }

                    bi.m_dontSpawnNormally = dontSpawnNormally.Remove(fullName);
                    Initialize(bi);
                    loadedBuildings.Add(fullName);

                    if (bi.GetAI() is IntersectionAI)
                    {
                        loadedIntersections.Add(fullName);
                    }
                }

                VehicleInfo vi = go.GetComponent <VehicleInfo>();

                if (vi != null)
                {
                    if (vi.m_lodObject != null)
                    {
                        vi.m_lodObject.SetActive(false);
                    }

                    Initialize(vi);
                    loadedVehicles.Add(fullName);
                }

                CitizenInfo ci = go.GetComponent <CitizenInfo>();

                if (ci != null)
                {
                    if (ci.m_lodObject != null)
                    {
                        ci.m_lodObject.SetActive(false);
                    }

                    if (ci.InitializeCustomPrefab(citizenMetaDatas[assetRef.fullName]))
                    {
                        citizenMetaDatas.Remove(assetRef.fullName);
                        ci.gameObject.SetActive(true);
                        Initialize(ci);
                        loadedCitizens.Add(fullName);
                    }
                    else
                    {
                        CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Custom citizen [" + assetRef.fullName + "] template not available in selected theme. Asset not added in game.");
                    }
                }

                NetInfo ni = go.GetComponent <NetInfo>();

                if (ni != null)
                {
                    loadedNets.Add(fullName);
                    Initialize(ni);
                }
            }
            finally
            {
                stack.Pop();
                assetCount++;
                LoadingManager.instance.m_loadingProfilerCustomAsset.EndLoading();
            }
        }
Пример #12
0
 internal SomeMetaData(Package.Asset u, string n, CustomAssetMetaData.Type t)
 {
     userDataRef = u;
     name        = n;
     type        = t;
 }
Пример #13
0
        Package.Asset[] GetLoadQueue(HashSet <string> styleBuildings)
        {
            Package.AssetType[] customAssets = { UserAssetType.CustomAssetMetaData };
            Package[]           packages     = { };

            try
            {
                packages = PackageManager.allPackages.Where(p => p.FilterAssets(customAssets).Any()).ToArray();
                Array.Sort(packages, PackageComparison);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogException(e);
            }

            List <Package.Asset>       assets = new List <Package.Asset>(8);
            List <CustomAssetMetaData> metas  = new List <CustomAssetMetaData>(8);

            // Why this load order? By having related and identical assets close to each other, we get more loader cache hits (of meshes and textures)
            // in Sharing. We also get faster disk reads.
            // [0] propvar and prop, tree, citizen  [1] prop      [2] pillar and elevation and road  [3] road
            // [4] sub-building and building        [5] building  [6] trailer and vehicle            [7] vehicle
            List <Package.Asset>[] queues = { new List <Package.Asset>(32), new List <Package.Asset>(64), new List <Package.Asset>(4),  new List <Package.Asset>(4),
                                              new List <Package.Asset>(16), new List <Package.Asset>(64), new List <Package.Asset>(32), new List <Package.Asset>(32) };

            SteamHelper.DLC_BitMask notMask = ~SteamHelper.GetOwnedDLCMask();
            bool loadEnabled = Settings.settings.loadEnabled, loadUsed = Settings.settings.loadUsed;

            //PrintPackages(packages);

            foreach (Package p in packages)
            {
                CustomAssetMetaData meta = null;

                try
                {
                    assets.Clear();
                    assets.AddRange(p.FilterAssets(customAssets));
                    int count = assets.Count;

                    CustomDeserializer.instance.AddPackage(p);
                    bool enabled = loadEnabled && IsEnabled(p);

                    if (count == 1) // the common case
                    {
                        bool want = enabled || styleBuildings.Contains(assets[0].fullName);

                        // Fast exit.
                        if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                        {
                            continue;
                        }

                        meta = AssetDeserializer.Instantiate(assets[0]) as CustomAssetMetaData;
                        bool used = loadUsed && UsedAssets.instance.IsUsed(meta);

                        if (used || want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0)
                        {
                            if (reportAssets)
                            {
                                AssetReport.instance.AddPackage(p, meta, want, used);
                            }

                            CustomAssetMetaData.Type type = meta.type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;

                            AddToQueue(queues, meta, type, offset, !(enabled | used));
                        }
                    }
                    else
                    {
                        bool want = enabled;

                        // Fast exit.
                        if (!want)
                        {
                            for (int i = 0; i < count; i++)
                            {
                                want = want || styleBuildings.Contains(assets[i].fullName);
                            }

                            if (!want && !(loadUsed && UsedAssets.instance.GotPackage(p.packageName)))
                            {
                                continue;
                            }
                        }

                        metas.Clear();
                        bool used = false;

                        for (int i = 0; i < count; i++)
                        {
                            meta = AssetDeserializer.Instantiate(assets[i]) as CustomAssetMetaData;
                            metas.Add(meta);
                            want = want && (AssetImporterAssetTemplate.GetAssetDLCMask(meta) & notMask) == 0;
                            used = used || loadUsed && UsedAssets.instance.IsUsed(meta);
                        }

                        if (want | used)
                        {
                            metas.Sort((a, b) => b.type - a.type); // prop variation, sub-building, trailer, elevation, pillar before main asset
                            CustomAssetMetaData lastmeta = metas[count - 1];

                            if (reportAssets)
                            {
                                AssetReport.instance.AddPackage(p, lastmeta, want, used);
                            }

                            CustomAssetMetaData.Type type = metas[0].type;
                            int offset = type == CustomAssetMetaData.Type.Trailer || type == CustomAssetMetaData.Type.SubBuilding ||
                                         type == CustomAssetMetaData.Type.PropVariation || type >= CustomAssetMetaData.Type.RoadElevation ? -1 : 0;
                            bool treeVariations = lastmeta.type == CustomAssetMetaData.Type.Tree, dontSpawn = !(enabled | used);

                            for (int i = 0; i < count; i++)
                            {
                                CustomAssetMetaData      m = metas[i];
                                CustomAssetMetaData.Type t = m.type;

                                if (treeVariations && t == CustomAssetMetaData.Type.PropVariation)
                                {
                                    t = CustomAssetMetaData.Type.Tree;
                                }

                                AddToQueue(queues, m, t, offset, dontSpawn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    AssetFailed(meta?.assetRef, p, e);
                }
            }

            CheckSuspects();

            for (int i = 0; i < queuedLoads.Length; i++)
            {
                queuedLoads[i].Clear();
                queuedLoads[i] = null;
            }

            queuedLoads = null;
            Package.Asset[] queue = new Package.Asset[queues.Sum(lst => lst.Count)];

            for (int i = 0, k = 0; i < queues.Length; i++)
            {
                queues[i].CopyTo(queue, k);
                k += queues[i].Count;
                queues[i].Clear(); queues[i] = null;
            }

            return(queue);
        }
Пример #14
0
        internal void LoadImpl(Package.Asset assetRef)
        {
            try
            {
                stack.Push(assetRef);
                LoadingManager.instance.m_loadingProfilerCustomAsset.BeginLoading(ShortName(assetRef.name));
                CustomAssetMetaData.Type type = GetMetaType(assetRef);

                GameObject go          = AssetDeserializer.Instantiate(assetRef) as GameObject;
                string     packageName = assetRef.package.packageName;
                string     fullName    = type < CustomAssetMetaData.Type.RoadElevation ? packageName + "." + go.name : PillarOrElevationName(packageName, go.name);
                go.name = fullName;
                go.SetActive(false);
                PrefabInfo info = go.GetComponent <PrefabInfo>();
                info.m_isCustomContent = true;

                if (info.m_Atlas != null && !string.IsNullOrEmpty(info.m_InfoTooltipThumbnail) && info.m_Atlas[info.m_InfoTooltipThumbnail] != null)
                {
                    info.m_InfoTooltipAtlas = info.m_Atlas;
                }

                PropInfo     pi;
                TreeInfo     ti;
                BuildingInfo bi;
                VehicleInfo  vi;
                CitizenInfo  ci;
                NetInfo      ni;

                if ((pi = go.GetComponent <PropInfo>()) != null)
                {
                    if (pi.m_lodObject != null)
                    {
                        pi.m_lodObject.SetActive(false);
                    }

                    Initialize(pi);
                }
                else if ((ti = go.GetComponent <TreeInfo>()) != null)
                {
                    Initialize(ti);
                }
                else if ((bi = go.GetComponent <BuildingInfo>()) != null)
                {
                    if (bi.m_lodObject != null)
                    {
                        bi.m_lodObject.SetActive(false);
                    }

                    bi.m_dontSpawnNormally = dontSpawnNormally.Remove(fullName);
                    Initialize(bi);

                    if (bi.GetAI() is IntersectionAI)
                    {
                        loadedIntersections.Add(fullName);
                    }
                }
                else if ((vi = go.GetComponent <VehicleInfo>()) != null)
                {
                    if (vi.m_lodObject != null)
                    {
                        vi.m_lodObject.SetActive(false);
                    }

                    Initialize(vi);
                }
                else if ((ci = go.GetComponent <CitizenInfo>()) != null)
                {
                    if (ci.m_lodObject != null)
                    {
                        ci.m_lodObject.SetActive(false);
                    }

                    if (ci.InitializeCustomPrefab(citizenMetaDatas[assetRef.fullName]))
                    {
                        citizenMetaDatas.Remove(assetRef.fullName);
                        ci.gameObject.SetActive(true);
                        Initialize(ci);
                    }
                    else
                    {
                        info = null;
                        CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Custom citizen [" + assetRef.fullName + "] template not available in selected theme. Asset not added in game.");
                    }
                }
                else if ((ni = go.GetComponent <NetInfo>()) != null)
                {
                    Initialize(ni);
                }
                else
                {
                    info = null;
                }

                if (info != null)
                {
                    string path = Path.GetDirectoryName(assetRef.package.packagePath);

                    if (!string.IsNullOrEmpty(path) && plugins.TryGetValue(path, out PluginInfo plugin))
                    {
                        IAssetDataExtension[] extensions = plugin.GetInstances <IAssetDataExtension>();

                        if (extensions.Length > 0)
                        {
                            UserAssetData uad = GetUserAssetData(assetRef, out string name);

                            if (uad != null)
                            {
                                for (int i = 0; i < extensions.Length; i++)
                                {
                                    try
                                    {
                                        extensions[i].OnAssetLoaded(name, info, uad.Data);
                                    }
                                    catch (Exception e)
                                    {
                                        ModException ex = new ModException("The Mod " + plugin.ToString() + " has caused an error when loading " + fullName, e);
                                        UIView.ForwardException(ex);
                                        Debug.LogException(ex);
                                    }
                                }
                            }
                            else
                            {
                                Util.DebugPrint("UserAssetData is null for", fullName);
                            }
                        }
                    }
                }
            }
            finally
            {
                stack.Pop();
                assetCount++;
                LoadingManager.instance.m_loadingProfilerCustomAsset.EndLoading();
            }
        }
Пример #15
0
 bool IsCommonBuilding(String fullName, Package.Asset asset, CustomAssetMetaData assetMetaData)
 {
     CustomAssetMetaData.Type type = assetMetaData.type;
     return(type == CustomAssetMetaData.Type.Building || type == CustomAssetMetaData.Type.SubBuilding);
 }