Esempio n. 1
0
        public static object Serialize_ChunkPortal(object _obj, System.Type type, OverloadLevelConvertSerializer serializer)
        {
            ChunkPortal obj = (ChunkPortal)_obj;

            serializer.SerializeX(obj, x => x.Num);
            serializer.SerializeX(obj, x => x.Chunknum);
            serializer.SerializeX(obj, x => x.Segnum);
            serializer.SerializeX(obj, x => x.Sidenum);
            serializer.SerializeX(obj, x => x.ConnectedChunk);
            serializer.SerializeX(obj, x => x.ConnectedPortal);
            serializer.SerializeX(obj, x => x.PortalGeomNum);
            return(obj);
        }
Esempio n. 2
0
    //This is called after a level is loaded.  Create the GameManager if this is the first level loaded.
    //This function should do nothing else.
    public void Awake()
    {
#if !OVERLOAD_LEVEL_EDITOR
        // Defer the Awake until after user level loading is complete
        if (UserLevelLoader.IsLoadingUserLevel)
        {
            UserLevelLoader.ExecuteAfterLoading(() => { Awake(); });
            return;
        }

        Debug.Log("LevelData Awake " + Time.realtimeSinceStartup);

        //If Game Manager doesn't exist (this is the first level to be loaded), create it
        if (Object.Equals(GameManager.m_gm, null))                      //When the game is shutting down in the editor it apparently re-loads the editor level after closing down the GameManager causing this to be called when m_gm is fake-null.   So check for real null.
        {
            GameManager.Required(m_game_manager_prefab != null, "Game manager prefab not specified");
            Instantiate(m_game_manager_prefab, Vector3.zero, Quaternion.identity);
        }

        //Check for geometry data
        GameManager.Required(m_geometry != null, "Geometry data not specified");

        //Save the global for the level initializer object
        GameManager.m_level_data = this;

        // Add local player immediately. Remote clients will only add players once scene is loaded both on server and locally.
        if (NetworkManager.IsServer())
        {
            Client.AddPlayer();
        }
        else
        {
            GameManager.m_player_ship  = PlayerShip.Instantiate();
            GameManager.m_local_player = GameManager.m_player_ship.c_player;
        }

        GameObject legacy_player_start = GameObject.FindGameObjectWithTag("LegacyPlayerStart");
        if (!GameplayManager.IsMultiplayer)
        {
            GameManager.m_player_ship.SetSpawnPosAndRotation(legacy_player_start);
        }
        if (legacy_player_start != null)
        {
            legacy_player_start.SetActive(false);              // start has a camera we want to disable
        }

        //Get the viewer component
        GameManager.m_viewer = Camera.main.GetComponent <Viewer>();
        GameManager.Required(GameManager.m_viewer != null, "Must have Viewer component on camera");

        //Get the mesh containers
        GameManager.m_mesh_container = GameObject.Find("_container_level_meshes");

        //
        // Do some processing on this object's data.  Don't do anything else here.
        //

        //Fix up the door references
        if (m_portal_to_door_references != null)
        {
            foreach (var portal_door_ref in m_portal_to_door_references)
            {
                int portal_index = portal_door_ref.PortalIndex;
                if (portal_index >= 0 && portal_index < m_geometry.Portals.Length)
                {
                    m_geometry.Portals[portal_index].DoorData = portal_door_ref.ReferenceDoor;
                }
                else
                {
                    Debug.LogError(string.Format("Portal Index {0} is out of range for door {1}", portal_index, portal_door_ref.ReferenceDoor.name));
                }
            }
        }

        //Create empty level light and reflection probe arrays if they're not present
        if (m_level_lights == null)
        {
            m_level_lights = new SegmentLightInfo[0];
        }

        if (m_level_reflection_probes == null || m_level_reflection_probes.Length == 0)
        {
            List <SegmentReflectionProbeInfo> srpi_list = new List <SegmentReflectionProbeInfo>();
            // Gather the reflection probes the hard way (slowly)
            GameObject userContainerObject = GameObject.Find("!rprobes");
            if (userContainerObject != null && userContainerObject.transform.parent == null)
            {
                // Gather all the reflection probes under "!probes"
                ReflectionProbe[] rps = userContainerObject.GetComponentsInChildren <ReflectionProbe>();
                int count             = rps.Length;
                for (int i = 0; i < count; i++)
                {
                    SegmentReflectionProbeInfo srpi = new SegmentReflectionProbeInfo();
                    srpi.ProbeObject  = rps[i].gameObject;
                    srpi.SegmentIndex = FindSegmentContainingWorldPosition(rps[i].transform.position);
                    if (srpi.SegmentIndex < 0)
                    {
                        srpi.SegmentIndex = ChunkManager.FindNearestSegment(rps[i].transform.position);
                    }
                    srpi.ProbeType = SegmentReflectionProbeType.UserPlaced;

                    srpi_list.Add(srpi);
                }
            }

            m_level_reflection_probes = srpi_list.ToArray();

            if (m_level_reflection_probes == null)
            {
                m_level_reflection_probes = new SegmentReflectionProbeInfo[0];
            }
        }


        NumSegments = m_geometry.Segments.Length;

        // Associate lights to segments
        {
            Dictionary <int, List <SegmentLightInfo> > mapLightsToSegment = new Dictionary <int, List <SegmentLightInfo> >();

            foreach (var llight in m_level_lights)
            {
                if (llight.SegmentIndex < 0 || llight.SegmentIndex >= NumSegments)
                {
                    Debug.LogErrorFormat("Level light at invalid segment index {0}", llight.SegmentIndex);
                    continue;
                }

                List <SegmentLightInfo> list;
                if (!mapLightsToSegment.TryGetValue(llight.SegmentIndex, out list))
                {
                    list = new List <SegmentLightInfo>();
                    mapLightsToSegment.Add(llight.SegmentIndex, list);
                }

                if (llight.LightObject != null && llight.LightComp != null)
                {
                    list.Add(llight);
                }
            }

            foreach (var kvp in mapLightsToSegment)
            {
                m_geometry.Segments[kvp.Key].Lights = kvp.Value.ToArray();
            }

            // Provide an empty list for the other segments
            SegmentLightInfo[] dummyList = new SegmentLightInfo[0];
            for (int segIndex = 0; segIndex < NumSegments; ++segIndex)
            {
                if (mapLightsToSegment.ContainsKey(segIndex))
                {
                    continue;
                }
                m_geometry.Segments[segIndex].Lights = dummyList;
            }
        }

        // Associate reflection probes to segments
        {
            Dictionary <int, List <SegmentReflectionProbeInfo> > mapProbesToSegment = new Dictionary <int, List <SegmentReflectionProbeInfo> >();

            foreach (var lprobe in m_level_reflection_probes)
            {
                if (lprobe.SegmentIndex < 0 || lprobe.SegmentIndex >= NumSegments)
                {
                    Debug.LogErrorFormat("Level reflection probe at invalid segment index {0}", lprobe.SegmentIndex);
                    continue;
                }

                List <SegmentReflectionProbeInfo> list;
                if (!mapProbesToSegment.TryGetValue(lprobe.SegmentIndex, out list))
                {
                    list = new List <SegmentReflectionProbeInfo>();
                    mapProbesToSegment.Add(lprobe.SegmentIndex, list);
                }

                if (lprobe.ProbeObject != null)
                {
                    list.Add(lprobe);
                }
            }

            foreach (var kvp in mapProbesToSegment)
            {
                m_geometry.Segments[kvp.Key].ReflectionProbes = kvp.Value.ToArray();
            }

            // Provide an empty list for the other segments
            SegmentReflectionProbeInfo[] dummyList = new SegmentReflectionProbeInfo[0];
            for (int segIndex = 0; segIndex < NumSegments; ++segIndex)
            {
                if (mapProbesToSegment.ContainsKey(segIndex))
                {
                    continue;
                }
                m_geometry.Segments[segIndex].ReflectionProbes = dummyList;
            }
        }

        //Find connecting portals for chunk portals
        foreach (ChunkPortal chunk_portal in m_geometry.ChunkPortals)
        {
            if (chunk_portal.ConnectedPortal == -1)
            {
                PortalData seg_portal       = m_geometry.Portals[m_geometry.Segments[chunk_portal.Segnum].Portals[chunk_portal.Sidenum]];
                int        connected_segnum = (seg_portal.MasterSegmentIndex == chunk_portal.Segnum) ? seg_portal.SlaveSegmentIndex : seg_portal.MasterSegmentIndex;
                foreach (int connected_chunk_portal_index in m_geometry.Chunks[chunk_portal.ConnectedChunk].PortalIndices)
                {
                    ChunkPortal connected_chunk_portal = m_geometry.ChunkPortals[connected_chunk_portal_index];
                    if (connected_chunk_portal.Segnum == connected_segnum)
                    {
                        chunk_portal.ConnectedPortal           = connected_chunk_portal.Num;
                        connected_chunk_portal.ConnectedPortal = chunk_portal.Num;
                    }
                }
                Assert.True(chunk_portal.ConnectedPortal != -1);
            }
        }

        //Make list of Chunks
        CreateChunkList();

        //Set up object to access segment visibility
        if (m_geometry.SegmentToSegmentVisibility == null)
        {
            var stopWatch = new System.Diagnostics.Stopwatch();
            stopWatch.Start();
            Segment2SegmentVis.ComputeSegmentVisibility(m_geometry, 55.0f);
            stopWatch.Stop();
            UnityEngine.Debug.LogFormat("ComputeSegmentVisibility took {0} ms", stopWatch.ElapsedMilliseconds);
        }
        if (m_geometry.SegmentToSegmentVisibility != null)
        {
            m_segment_visibility = new IndexAs2D(m_geometry.SegmentToSegmentVisibility, NumSegments);
        }
        else
        {
            m_segment_visibility = null;
        }

        //Make a list of ambient sound sources in the level.  Might make sense to keep that list here, but the gather function is a little audio-specific
        if (GameManager.m_audio != null)                        //Don't do this on game startup
        {
            GameManager.m_audio.GatherAmbientSounds();
        }

        //Find the reactor, if one exists
        Reactor[] reactors = FindObjectsOfType <Reactor>();
        if (reactors.Length == 0)
        {
            //Debug.Log("There is no reactor in this level!");
            Reactor = null;
        }
        else
        {
            if (reactors.Length > 1)
            {
                Debug.Log("There are " + reactors.Length + " reactors in this level!  There should be no more than one!  Will only use the first one found");
            }
            Reactor = reactors[0];
        }

        // Find the alien warper if one exists.
        GameObject alien_warp = GameObject.FindGameObjectWithTag("AlienWarp");
        if (alien_warp != null)
        {
            m_alien_warp_segment = GameManager.m_level_data.FindSegmentContainingWorldPosition(alien_warp.transform.position);
            Debug.Log("Alien warper is in segment " + m_alien_warp_segment);
        }
        else
        {
            m_alien_warp_segment = -1;                          // It's OK if there is no alien warper, most levels don't have one!
        }

        //Reset LevelCustomInfo statics in case the level doesn't have a LevelCustomInfo component
        LevelCustomInfo.Reset();

        //Find segments for spawn points
        SetSpawnPointSegments(m_robot_spawn_points);
        SetSpawnPointSegments(m_item_spawn_points);
        SetSpawnPointSegments(m_player_spawn_points);
        SetSpawnPointSegments(m_mp_camera_points);

        TriggerWindTunnel.UpdateSegmentsForWindTunnels();             // Deal with Wind Tunnels (WindTunnels)
        Forcefield.UpdateSegmentsForForcefields();                    // Deal with Forcefields

        // Deal with teleporters.
        for (int i = 0; i < GameManager.m_level_data.Segments.Length; i++)
        {
            GameManager.m_level_data.Segments[i].WarpDestinationSegs = new int[6];
            for (int j = 0; j < 6; j++)
            {
                GameManager.m_level_data.Segments[i].WarpDestinationSegs[j] = -1;
            }
        }

        //Find & initialize cryotubes
        InitCryotubes();

        // Explode the hierarchy (for optimization reasons)
        if (CrushHierarchy)
        {
            GameManager.m_mesh_container.transform.DetachChildren();

            GameObject container = GameObject.Find("_container_level_lava_meshes");
            container.transform.DetachChildren();

            //container = GameObject.Find("_container_placed_entities");
            //int count = container.transform.childCount;
            //for (int i = count - 1; i >= 0; i--) {
            //	container.transform.GetChild(i).DetachChildren();
            //}
            LevelCustomInfo.TryToCrush();
        }

        Debug.Log("LevelData Awake DONE " + Time.realtimeSinceStartup);
#endif // !OVERLOAD_LEVEL_EDITOR
    }