public static void InitializeDefinition(string subBuildingsDefPath, HashSet <string> subBuildingsDefParseErrors, string packageName, BuildingInfo prefab = null)
        {
            SubBuildingsDefinition subBuildingsDef;

            try
            {
                subBuildingsDef = ReadDefinition(subBuildingsDefPath);
                if (subBuildingsDef == null)
                {
                    return;
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                subBuildingsDefParseErrors.Add(packageName + " - " + e.Message);
                return;
            }

            if (subBuildingsDef == null || subBuildingsDef.Buildings == null || subBuildingsDef.Buildings.Count == 0)
            {
                subBuildingsDefParseErrors.Add(packageName + " - subBuildingsDef is null or empty.");
                return;
            }

            foreach (var parentBuildingDef in subBuildingsDef.Buildings)
            {
                if (parentBuildingDef == null || parentBuildingDef.Name == null)
                {
                    subBuildingsDefParseErrors.Add(packageName + " - Building name missing.");
                    continue;
                }
                var parentBuildingPrefab = FindPrefab(parentBuildingDef.Name, packageName);

                if (parentBuildingPrefab == null)
                {
                    subBuildingsDefParseErrors.Add(packageName + " - Building with name " + parentBuildingDef.Name +
                                                   " not loaded.");
                    continue;
                }
                if (prefab != null && parentBuildingPrefab.name != $"{packageName}.{prefab.name}")
                {
                    UnityEngine.Debug.Log($"{parentBuildingPrefab.name}!={prefab.name} (package {packageName})");
                    continue;
                }

                if (parentBuildingDef.SubBuildings == null || parentBuildingDef.SubBuildings.Count == 0)
                {
                    subBuildingsDefParseErrors.Add(packageName + " - No sub buildings specified for " + parentBuildingDef.Name +
                                                   ".");
                    continue;
                }

                var subBuildings = new List <BuildingInfo.SubInfo>();

                foreach (var subBuildingDef in parentBuildingDef.SubBuildings)
                {
                    if (subBuildingDef == null || subBuildingDef.Name == null)
                    {
                        subBuildingsDefParseErrors.Add(parentBuildingDef.Name + " - Sub-building name missing.");
                        continue;
                    }

                    var subBuildingPrefab = FindPrefab(subBuildingDef.Name, packageName);

                    if (subBuildingPrefab == null)
                    {
                        subBuildingsDefParseErrors.Add(parentBuildingDef.Name + " - Sub-building with name " +
                                                       subBuildingDef.Name + " not loaded.");
                        continue;
                    }

                    var subBuilding = new BuildingInfo.SubInfo
                    {
                        m_buildingInfo = subBuildingPrefab,
                        m_position     = new Vector3(subBuildingDef.PosX, subBuildingDef.PosY, subBuildingDef.PosZ),
                        m_angle        = subBuildingDef.Angle,
                        m_fixedHeight  = subBuildingDef.FixedHeight
                    };

                    subBuildings.Add(subBuilding);

                    // this is usually done in the InitializePrefab method
                    if (subBuildingDef.FixedHeight && !parentBuildingPrefab.m_fixedHeight)
                    {
                        parentBuildingPrefab.m_fixedHeight = true;
                    }
                }

                if (subBuildings.Count == 0)
                {
                    subBuildingsDefParseErrors.Add("No sub buildings specified for " + parentBuildingDef.Name + ".");
                    continue;
                }
                if (prefab == null)
                {
                    parentBuildingPrefab.m_subBuildings = subBuildings.ToArray();
                }
                else
                {
                    prefab.m_subBuildings = subBuildings.ToArray();
                }
            }
        }
        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));
        }
Пример #3
0
        static object CustomDeserialize(Package p, Type t, PackageReader r)
        {
            // First, make the common case fast.
            if (t == typeof(float))
            {
                return(r.ReadSingle());
            }
            if (t == typeof(Vector2))
            {
                return(r.ReadVector2());
            }

            // 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 (pi != null)
                {
                    string n = pi.gameObject.name;

                    if (!string.IsNullOrEmpty(n) && n.Contains("."))
                    {
                        UsedAssets.StoreIndirectPropName(n);
                    }
                }

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

                    if (!string.IsNullOrEmpty(n) && n.Contains("."))
                    {
                        UsedAssets.StoreIndirectTreeName(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()
                });
            }

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

                if (fullName == AssetLoader.Current)
                {
                    Profiler.Warning("{0} wants to be a prop variation for itself.", fullName);
                }
                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.Current)
                {
                    Profiler.Warning("{0} wants to be a tree variation for itself.", fullName);
                }
                else
                {
                    ti = Get <TreeInfo>(p, fullName, name, false);
                }

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

            // 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);
            }

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

                if (fullName == AssetLoader.Current || name == AssetLoader.Current)
                {
                    Profiler.Trace("{0} wants to be a sub-building for itself.", fullName);
                }
                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);
            }

            var ret = OriginalDeserializer(p, t, r);

            return(ret);
        }