public void SendRoomChangeDone(Entity ent, LevelRoom to, LevelRoom from, EntityEventsOwner.RoomEventData data)
 {
     if (this.RoomChangeDoneListener != null)
     {
         this.RoomChangeDoneListener(ent, to, from, data);
     }
 }
示例#2
0
    private void Assimilate(LevelRoom room, LevelRoom toAssimilate)
    {
        LevelRoomMaterials materials = room.mats;

        foreach (LevelCell cell in toAssimilate.cells)
        {
            cell.transform.GetChild(0).GetComponent <Renderer>().material = materials.floorMaterial;
            cell.twoDImage.color = materials.floorMaterial.color;
            foreach (LevelCellEdge edge in cell.edges)
            {
                if (edge is LevelPassage)
                {
                    if (edge.image != null)
                    {
                        edge.image.color = materials.floorMaterial.color;
                    }
                }
            }
            foreach (LevelCellEdge edge in cell.edges)
            {
                if (edge is LevelWall)
                {
                    ((LevelWall)(edge)).wall.GetComponent <Renderer>().material = materials.wallMaterial;
                }
                else if (edge is LevelBreakableWall)
                {
                    ((LevelBreakableWall)(edge)).wall.GetComponent <Renderer>().material = breakableMats[room.matIndex];
                }
            }
        }
        room.Join(toAssimilate);
    }
示例#3
0
        public override bool Build(LevelRoom room)
        {
            foreach (var entityPool in entityPools)
            {
                var success = false;

                foreach (var entity in entityPool.entities.OrderByDescending(o => o.roomType))
                {
                    success = RenderEntity(room, entity);
                    if (success && entityPool.singleton)
                    {
                        break;
                    }
                    RollbackRenderContainer();
                }

                if (!success && entityPool.required)
                {
                    return(false);
                }
            }

            BuildFill(room);

            return(true);
        }
示例#4
0
    protected override void DoActivate(LevelRoom room)
    {
        int num = 0;

        for (int i = this.trackEnts.Count - 1; i >= 0; i--)
        {
            Entity entity = this.trackEnts[i];
            this.trackEnts[i] = null;
            if (EntitySpawner.IsValid(entity))
            {
                entity.Deactivate();
                num++;
            }
        }
        this.totalSpawned = 0;
        this.timer        = this._delay;
        base.enabled      = this._startEnabled;
        if (num > 0)
        {
            UnityEngine.Debug.LogWarning(string.Concat(new object[]
            {
                base.name,
                " had ",
                num,
                " active ents"
            }), this);
        }
    }
 public void Join(LevelRoom room)
 {
     for (int i = 0; i < room.cells.Count; i++)
     {
         Add(room.cells[i]);
     }
 }
示例#6
0
    private IEnumerator AssimilateCinematically(LevelRoom room, LevelRoom toAssimilate)
    {
        LevelRoomMaterials materials = room.mats;

        foreach (LevelCell cell in toAssimilate.cells)
        {
            cell.transform.GetChild(0).GetComponent <Renderer>().material = materials.floorMaterial;
            cell.twoDImage.color = materials.floorMaterial.color;
            foreach (LevelCellEdge edge in cell.edges)
            {
                if (edge is LevelPassage)
                {
                    if (edge.image != null)
                    {
                        edge.image.color = materials.floorMaterial.color;
                    }
                }
            }
            foreach (LevelCellEdge edge in cell.edges)
            {
                if (edge is LevelWall)
                {
                    ((LevelWall)(edge)).wall.GetComponent <Renderer>().material = materials.wallMaterial;
                }
                else if (edge is LevelBreakableWall)
                {
                    ((LevelBreakableWall)(edge)).wall.GetComponent <Renderer>().material = breakableMats[room.matIndex];
                }
            }
            yield return(new WaitForSeconds(0.0f));
        }
        room.Join(toAssimilate);
    }
    static void Snap(LevelRoom A, LevelRoom B, int exitA, int exitB)
    {
        SerializedObject newObj     = new SerializedObject(A);
        SerializedObject currentObj = new SerializedObject(B);

        var propNew     = newObj.FindProperty("ExitDestination");
        var propCurrent = currentObj.FindProperty("ExitDestination");

        newObj.Update();
        currentObj.Update();

        propCurrent.GetArrayElementAtIndex(exitB).objectReferenceValue = A;
        propNew.GetArrayElementAtIndex(exitA).objectReferenceValue     = B;

        var exitAObj        = new SerializedObject(A.Exits[exitA].gameObject);
        var exitAActiveProp = exitAObj.FindProperty("m_IsActive");

        exitAActiveProp.boolValue = false;

        var exitBObj        = new SerializedObject(B.Exits[exitB].gameObject);
        var exitBActiveProp = exitBObj.FindProperty("m_IsActive");

        exitBActiveProp.boolValue = false;

        exitAObj.ApplyModifiedProperties();
        exitBObj.ApplyModifiedProperties();
        newObj.ApplyModifiedProperties();
        currentObj.ApplyModifiedProperties();
    }
示例#8
0
    public void DoRespawn()
    {
        this.inForceRespawn = false;
        if (this._doDeathOffset && this.levelRoot != null)
        {
            this.levelRoot.gameObject.SetActive(true);
        }
        ProjectileFactory.Instance.DeactivateAll();
        Vector3 vector = (!this.useRoomSpawn) ? this.spawnPos : this.roomSpawnPos;
        Vector3 dir    = (!this.useRoomSpawn) ? this.spawnDir : this.roomSpawnDir;

        this.ent.RealTransform.position = vector;
        this.ent.Activate();
        this.ent.TurnTo(dir, 0f);
        if (this.varOverrider != null)
        {
            this.varOverrider.Apply(this.ent);
        }
        this.RegEvents(this.ent);
        base.enabled      = false;
        this.roomSpawnPos = vector;
        this.roomSpawnDir = dir;
        this.controller.ControlEntity(this.ent);
        if (this.attachTag != null)
        {
            this.attachTag.Free();
        }
        this.attachTag = null;
        if (this.attacher != null)
        {
            this.attachTag = this.attacher.Attach(this.ent);
        }
        if (this.followCam != null)
        {
            this.followCam.ClearFollowScale();
        }
        LevelRoom roomForPosition = LevelRoom.GetRoomForPosition(vector + Vector3.up * 0.25f, null);

        if (roomForPosition != null)
        {
            roomForPosition.SetImportantPoint(vector);
            LevelRoom.SetCurrentActiveRoom(roomForPosition, true);
            if (this.levelCam != null)
            {
                this.levelCam.SetRoom(roomForPosition);
            }
        }
        if (this.hud != null)
        {
            this.hud.Observe(this.ent, this.controller);
        }
        if (this._fadeIn != null || this._fadeOut != null)
        {
            FadeEffectData data  = this._fadeIn ?? this._fadeOut;
            Vector3        value = new Vector3(0f, 0f, 0f);
            OverlayFader.StartFade(data, false, null, new Vector3?(value));
        }
        EventListener.PlayerSpawn(true);         // Invoke custom event
    }
示例#9
0
        public void Render(ref LevelRoom room)
        {
            var suiteGameobject = new GameObject("Suite");

            suiteGameobject.transform.parent = room.renderContainer.transform;

            //Main Entity Pass
            foreach (var entity in renderContainer.entities)
            {
                var position  = entity.Key.Item1;
                var direction = entity.Key.Item2;

                var instance = Instantiate(entity.Value, position, new Quaternion());
                instance.transform.Rotate(new Vector3(0, 1, 0), (int)direction.ToAngle());
                instance.transform.parent = suiteGameobject.transform;
            }

            //Fill Entity Pass
            foreach (var entity in renderContainer.fillEntities)
            {
                SuiteEntity_Scaffold instance;
                switch (entity.Key.Item1) //Node Type
                {
                case ScaffoldNodeType.Floor_Main:
                case ScaffoldNodeType.Floor_Column:
                    instance = Instantiate(entity.Value, entity.Key.Item2.PositionBetween(), new Quaternion());
                    instance.transform.parent = suiteGameobject.transform;
                    break;

                case ScaffoldNodeType.Floor_Connector:
                    instance = Instantiate(entity.Value, entity.Key.Item2.PositionBetween(), new Quaternion());
                    instance.transform.Rotate(new Vector3(0, 1, 0), entity.Key.Item3.Opposite().ToAngle());
                    instance.transform.parent = suiteGameobject.transform;
                    break;

                case ScaffoldNodeType.Wall_Main:
                case ScaffoldNodeType.Wall_Connector:
                    instance = Instantiate(entity.Value, OffsetWall(entity.Key.Item2.PositionBetween(), entity.Key.Item3), new Quaternion());
                    instance.transform.Rotate(new Vector3(0, 1, 0), entity.Key.Item3.Opposite().ToAngle());
                    instance.transform.parent = suiteGameobject.transform;
                    break;

                case ScaffoldNodeType.Ceiling_Main:
                case ScaffoldNodeType.Ceiling_Column:
                    instance = Instantiate(entity.Value, entity.Key.Item2.PositionBetween(), new Quaternion());
                    instance.transform.parent = suiteGameobject.transform;
                    break;

                case ScaffoldNodeType.Ceiling_Connector:
                    instance = Instantiate(entity.Value, entity.Key.Item2.PositionBetween(), new Quaternion());
                    instance.transform.Rotate(new Vector3(0, 1, 0), entity.Key.Item3.Opposite().ToAngle());
                    instance.transform.parent = suiteGameobject.transform;
                    break;

                default:
                    break;
                }
            }
        }
 void Clean()
 {
     if (m_CurrentInstance != null)
     {
         DestroyImmediate(m_CurrentInstance.gameObject);
         m_CurrentInstance = null;
     }
 }
示例#11
0
 void RoomChanged(Entity ent, LevelRoom ro, LevelRoom from, EntityEventsOwner.RoomEventData data)
 {
     if (!this.overrideRoomSpawn)
     {
         this.roomSpawnPos = data.targetPos;
         this.roomSpawnDir = data.targetDir;
     }
     ProjectileFactory.Instance.DeactivateAll();
 }
示例#12
0
        public static void SpawnInTheTruck(string GhostState)
        {
            // Keep a record of GhostStates to use as our trigger
            Previous = Current;
            Current  = GhostState;

            // When a hunt ends restore outside
            if (Current == "Favourite Room" && Previous == "Hunting")
            {
                Main.levelController.field_Public_LevelRoom_2 = Outside;
            }

            // when a new hunt happens check to see if it should be a vanhunt
            if (Current == "Hunting" && Previous == "Idle")
            {
                // 1/5 chance to spawn in van
                int spawnChance = UnityEngine.Random.Range(0, 5);
                MelonLogger.Log("Spawn Chance: " + spawnChance);
                // delete me after debug
                spawnChance = 4;
                // delete me after debug

                if (spawnChance == 4)
                {
                    MelonLogger.Log("VanHunt Triggered");

                    // temp store reference to outside room
                    // pretty sure field_Public_LevelRoom_0 is any room in house
                    // pretty sure field_Public_LevelRoom_1 is ghost room
                    // field_Public_LevelRoom_2 is outside

                    // store the actual 'outside' for later restoration
                    Outside = Main.levelController.field_Public_LevelRoom_2;

                    //Attempt to declare the outside to be the ghost room
                    Main.levelController.field_Public_LevelRoom_2 = Main.levelController.field_Public_LevelRoom_1;

                    // warp ghost to player spawn
                    Main.ghostAI.field_Public_NavMeshAgent_0.Warp(Main.playerSpawnPosition);

                    // Open all doors to give van peepz a shot
                    foreach (Door door in Main.doors)
                    {
                        door.DisableOrEnableDoor(true);
                        door.DisableOrEnableCollider(true);
                        door.UnlockDoor();
                    }
                }

                else
                {
                    return;
                }
            }
        }
示例#13
0
    void PlayerDied(Entity player)
    {
        Killable entityComponent = player.GetEntityComponent <Killable>();
        bool     flag            = entityComponent != null && (entityComponent.CurrentHp > 0f || entityComponent.SilentDeath);

        this.mayChangeLevel = !flag;
        this.UnregEvents(player);
        base.enabled = true;
        this.timer   = this._deathTime;
        player.SaveState();
        if (!flag)
        {
            ProjectileFactory.Instance.DeactivateAll();
            if (this._doDeathOffset)
            {
                LevelRoom roomForPosition = LevelRoom.GetRoomForPosition(player.WorldTracePosition, null);
                this.levelCam.ReleaseRoom(this._releaseCamTime);
                player.RealTransform.position = player.WorldPosition + this._deathOffset;
                if (roomForPosition != null)
                {
                    this.levelRoot = roomForPosition.LevelRoot;
                    LevelRoom.SetCurrentActiveRoom(null, false);
                    if (this.levelRoot != null)
                    {
                        this.levelRoot.gameObject.SetActive(false);
                    }
                }
            }
            if (this.backCam != null)
            {
                this.fadeTimer     = this._bgFadeTime;
                this.fadeTimeScale = 1f / this.fadeTimer;
            }
            this.useRoomSpawn = false;
        }
        else
        {
            this.timer        = this._weakDeathTime;
            this.fadeTimer    = 0f;
            this.useRoomSpawn = true;
        }
        if (this.followCam != null)
        {
            this.followCam.SetFollowScale(new Vector3(0.9f, 0.25f, 0.9f));
        }
        this.noFadeOut = false;
        if (entityComponent != null && entityComponent.SilentDeath)
        {
            this.mayChangeLevel = true;
            this.useRoomSpawn   = false;
            this.noFadeOut      = true;
            this.timer          = 0f;
        }
    }
示例#14
0
        //[HideInInspector]

        public override bool ValidateRoom(LevelRoom room)
        {
            var cellCount = CellCollection.GetByRoom(room.roomId).Count;

            //A required entity pool wouldn't even fit
            if (entityPools.Any(x => cellCount < x.smallestEntitySize && x.required))
            {
                return(false);
            }

            return(true);
        }
示例#15
0
        public void ResetRenderContainer(LevelRoom room)
        {
            renderContainer = new SuiteRenderingContainer();

            var roomCells = CellCollection.GetByRoom(room.roomId);
            var doorways  = Level.doors.Where(x => roomCells.Any(c => x.rootCells.Contains(c)));
            var openCells = roomCells.Where(x => doorways.Any(a => a.rootCells.Contains(x)));

            renderContainer.spaces.AddRange(openCells.Select(s => (Vector4)s.position));

            nextContainerInstance = renderContainer.Copy();
        }
示例#16
0
 protected override void DoDeactivate(LevelRoom room)
 {
     for (int i = this.trackEnts.Count - 1; i >= 0; i--)
     {
         Entity entity = this.trackEnts[i];
         if (EntitySpawner.IsValid(entity))
         {
             this.trackEnts[i] = null;
             entity.Deactivate();
         }
     }
 }
示例#17
0
    private LevelRoom CreateRoom(int excludedIndex)
    {
        LevelRoom room = ScriptableObject.CreateInstance <LevelRoom>();

        room.matIndex = Random.Range(0, roomMats.Length);
        if (room.matIndex == excludedIndex)
        {
            room.matIndex = (room.matIndex + 1) % roomMats.Length;
        }
        room.mats = roomMats[room.matIndex];
        rooms.Add(room);
        return(room);
    }
示例#18
0
    // Token: 0x0600097D RID: 2429 RVA: 0x0003A720 File Offset: 0x00038920
    private LevelRoom GetCurrentRoom()
    {
        LevelRoom[] array     = Object.FindObjectsOfType <LevelRoom>();
        LevelRoom   levelRoom = array[0];

        for (int i = 0; i < array.Length; i++)
        {
            if (Vector3.Distance(base.transform.position, array[i].transform.position) < Vector3.Distance(base.transform.position, levelRoom.transform.position))
            {
                levelRoom = array[i];
            }
        }
        return(levelRoom);
    }
示例#19
0
 // Token: 0x060009AF RID: 2479 RVA: 0x0003BAB4 File Offset: 0x00039CB4
 public void SetTemperatureValue(LevelRoom room)
 {
     if (room == LevelController.instance.outsideRoom && GameController.instance.myPlayer.player.currentRoom != room)
     {
         return;
     }
     if (room.floorType != GameController.instance.myPlayer.player.currentRoom.floorType)
     {
         return;
     }
     this.room = room;
     if (room.temperature < 10f && MissionTemperature.instance != null && room != LevelController.instance.outsideRoom && !MissionTemperature.instance.completed)
     {
         MissionTemperature.instance.CompleteMission();
     }
 }
示例#20
0
 public static LevelRoom GetRoomForPosition(Vector3 pos, List <LevelRoom> rooms = null)
 {
     if (rooms == null)
     {
         rooms = LevelRoom.currentRooms;
     }
     for (int i = 0; i < rooms.Count; i++)
     {
         LevelRoom levelRoom = rooms[i];
         if (levelRoom.Bounds.Contains(pos))
         {
             return(levelRoom);
         }
     }
     return(null);
 }
示例#21
0
    private void CreatePassageInSameRoom(LevelCell cell, LevelCell otherCell, LevelDirection direction, Canvas twoDMap)
    {
        LevelPassage passage = Instantiate(passagePrefab) as LevelPassage;

        passage.Initialize(cell, otherCell, direction);
        passage = Instantiate(passagePrefab) as LevelPassage;
        passage.Initialize(otherCell, cell, direction.GetOpposite());
        if (cell.room != otherCell.room)
        {
            LevelRoom joinRoom = otherCell.room;
            cell.room.Join(joinRoom);
            rooms.Remove(joinRoom);
            Destroy(joinRoom);
        }
        CreateTwoDPassage(cell, twoDMap, direction);
    }
        public static LevelRoom GetLoadedRoom()
        {
            // TODO: In the case of multiple rooms being loaded, check if setting is enabled, then add each active room to a list and if multiple are indeed active, call GetRoomPlayerIsIn() to get current room

            Transform levelRoot = GameObject.Find("LevelRoot").transform;

            for (int i = 0; i < levelRoot.childCount; i++)
            {
                LevelRoom room = levelRoot.GetChild(i).GetComponent <LevelRoom>();

                if (room != null && room.IsActive && room.RoomName != "DunLgR")
                {
                    return(room);
                }
            }

            return(null);
        }
示例#23
0
        private static bool RenderRoom(LevelRoom room, Suite suite)
        {
            if (!suite.ValidateRoom(room))
            {
                return(false);                           //Check if room even has a chance with this suite
            }
            var success = suite.Build(room);

            suite.renderContainer.roomId = room.roomId;

            if (success)
            {
                room.renderContainer.name = suite.suiteName;
                suite.Render(ref room);
                suite.renderContainer.claimedScaffolds.ForEach(x => Level.roomScaffolds[room.roomId].SetNodeClaimed(x.id));
                room.SaveChanges();
            }

            return(success);
        }
示例#24
0
 public static void SetCurrentActiveRoom(LevelRoom room, bool forceReset = false)
 {
     for (int i = 0; i < LevelRoom.currentRooms.Count; i++)
     {
         LevelRoom levelRoom = LevelRoom.currentRooms[i];
         if (levelRoom.IsDummy)
         {
             if (!levelRoom.IsActive)
             {
                 levelRoom.SetRoomActive(true, false);
             }
         }
         else if (levelRoom != room || forceReset)
         {
             levelRoom.SetRoomActive(false, true);
         }
     }
     if (room != null)
     {
         room.SetRoomActive(true, true);
     }
 }
示例#25
0
        public override bool Build(LevelRoom room)
        {
            var success = false;

            ResetRenderContainer(room);

            foreach (var entity in featurePool.entities)
            {
                success = RenderEntity(room, entity);
                if (success)
                {
                    break;
                }
                RollbackRenderContainer();
            }

            foreach (var entityPool in entityPools)
            {
                foreach (var entity in entityPool.entities)
                {
                    success = RenderEntity(room, entity);
                    if (success && entityPool.singleton)
                    {
                        break;
                    }
                    RollbackRenderContainer();
                }

                if (!success && entityPool.required)
                {
                    return(false);
                }
            }

            BuildFill(room);

            return(true);
        }
示例#26
0
    void DoSpawn(Vector3 P, Vector3 dir)
    {
        Vector3 vector;

        if (this._spawnOnFloor && PhysicsUtility.GetFloorPoint(P, 20f, 50f, this._floorLayer, out vector))
        {
            P.y = vector.y;
        }
        Vector3    vector2    = P + this._playerEnt.transform.localPosition;
        GameObject gameObject = Object.Instantiate <GameObject>(this._playerCamera, vector2 + this._playerCamera.transform.localPosition, this._playerCamera.transform.localRotation);

        gameObject.transform.localScale = this._playerCamera.transform.localScale;
        gameObject.name = this._playerCamera.name;
        CameraContainer component = gameObject.GetComponent <CameraContainer>();

        component.Init(this._playerCamera);
        Entity entity = Object.Instantiate <Entity>(this._playerEnt, vector2, base.transform.rotation);

        entity.name = this._playerEnt.name;
        if (component != null)
        {
            RoomSwitchable componentInChildren = entity.GetComponentInChildren <RoomSwitchable>();
            if (componentInChildren != null)
            {
                componentInChildren.SetLevelCamera(component);
            }
        }
        if (this._playerGraphics != null)
        {
            GameObject gameObject2 = Object.Instantiate <GameObject>(this._playerGraphics, entity.transform.position + this._playerGraphics.transform.localPosition, this._playerGraphics.transform.localRotation);
            gameObject2.transform.parent     = entity.transform;
            gameObject2.transform.localScale = this._playerGraphics.transform.localScale;
            gameObject2.name = this._playerGraphics.name;
        }
        entity.Init();
        entity.TurnTo(dir, 0f);
        FollowTransform componentInChildren2 = gameObject.GetComponentInChildren <FollowTransform>();

        if (componentInChildren2 != null)
        {
            componentInChildren2.SetTarget(entity.transform);
        }
        LevelCamera componentInChildren3 = gameObject.GetComponentInChildren <LevelCamera>();

        if (componentInChildren3 != null)
        {
            LevelRoom roomForPosition = LevelRoom.GetRoomForPosition(entity.WorldTracePosition, null);
            if (roomForPosition != null)
            {
                componentInChildren3.SetRoom(roomForPosition);
                roomForPosition.SetImportantPoint(vector2);
                LevelRoom.SetCurrentActiveRoom(roomForPosition, false);
            }
        }
        PlayerController controller = ControllerFactory.Instance.GetController <PlayerController>(this._controller);

        controller.ControlEntity(entity);
        controller.name = this._controller.name;
        entity.Activate();
        if (this._varOverrider != null)
        {
            this._varOverrider.Apply(entity);
        }
        EntityHUD componentInChildren4 = gameObject.GetComponentInChildren <EntityHUD>();

        if (componentInChildren4 != null)
        {
            componentInChildren4.Observe(entity, controller);
        }
        EntityObjectAttacher.Attacher attacher   = null;
        EntityObjectAttacher          component2 = base.GetComponent <EntityObjectAttacher>();

        if (component2 != null)
        {
            attacher = component2.GetAttacher();
        }
        EntityObjectAttacher.AttachTag attachTag = null;
        if (attacher != null)
        {
            attachTag = attacher.Attach(entity);
        }
        PlayerRespawner playerRespawner;

        if (this._respawner != null)
        {
            playerRespawner      = Object.Instantiate <PlayerRespawner>(this._respawner);
            playerRespawner.name = this._respawner.name;
        }
        else
        {
            GameObject gameObject3 = new GameObject("PlayerRespawer");
            playerRespawner = gameObject3.AddComponent <PlayerRespawner>();
        }
        playerRespawner.Init(entity, controller, componentInChildren3, componentInChildren2, componentInChildren4, this._gameSaver, attacher, attachTag, this._varOverrider, P, dir);
        VarHelper.PlayerObj = entity.gameObject;         // Store reference to player obj
        PlayerSpawner.OnSpawnedFunc onSpawnedFunc = PlayerSpawner.onSpawned;
        PlayerSpawner.onSpawned = null;
        if (onSpawnedFunc != null)
        {
            onSpawnedFunc(entity, gameObject, controller);
        }
        EventListener.PlayerSpawn(false);         // Invoke custom event
        Object.Destroy(base.gameObject);
    }
    public override void OnInspectorGUI()
    {
        bool editing = GUILayout.Toggle(m_EditingLayout, "Editing Layout", "Button");

        if (editing != m_EditingLayout)
        {
            if (!editing)
            {//disabled editing, cleanup
                if (m_CurrentInstance != null)
                {
                    DestroyImmediate(m_CurrentInstance.gameObject);
                }
                m_CurrentGroup    = null;
                m_CurrentInstance = null;
                m_SelectedRoom    = null;
            }
            else
            {
                if (!SceneView.lastActiveSceneView.drawGizmos)
                {
                    if (EditorUtility.DisplayDialog("Warning", "Gizmos are globally disabled, which prevents the layout editing tools from working. Do you want to re-enable Gizmos?", "Yes", "No"))
                    {
                        SceneView.lastActiveSceneView.drawGizmos = true;
                    }
                    else
                    {
                        editing = false;
                    }
                }
            }

            m_EditingLayout = editing;
        }

        if (m_EditingLayout)
        {
            EditorGUILayout.HelpBox("Press R to change which door the room use to connect to other room", MessageType.Info);

            EditorGUILayout.BeginHorizontal();

            int editingMode = GUILayout.Toolbar(m_EditingMode, new[] { "Add", "Remove" }, GUILayout.Width(120));
            if (editingMode != m_EditingMode)
            {
                if (editingMode == 1)
                {
                    if (m_CurrentInstance != null)
                    {
                        DestroyImmediate(m_CurrentInstance.gameObject);
                    }

                    m_SelectedRoom = null;
                }

                m_EditingMode = editingMode;
            }

            if (m_CurrentInstance != null)
            {
                EditorGUILayout.LabelField("Flip : ", GUILayout.Width(32));
                EditorGUI.BeginChangeCheck();

                bool flipX = GUILayout.Toggle(m_CurrentScale.x < 0, "X", "button", GUILayout.Width(32));
                bool flipY = GUILayout.Toggle(m_CurrentScale.y < 0, "Y", "button", GUILayout.Width(32));
                bool flipZ = GUILayout.Toggle(m_CurrentScale.z < 0, "Z", "button", GUILayout.Width(32));

                GUILayout.FlexibleSpace();

                if (EditorGUI.EndChangeCheck())
                {
                    m_CurrentScale = new Vector3(flipX ? -1 : 1, flipY ? -1 : 1, flipZ ? -1 : 1);
                    m_CurrentInstance.transform.localScale = m_CurrentScale;
                }
            }

            EditorGUILayout.EndHorizontal();

            //we repaint all scene view to be sure they get a notification so they can "steal" focus in edit mode
            SceneView.RepaintAll();
        }

        GUILayout.BeginHorizontal();

        GUILayout.BeginVertical();
        GUILayout.Label("Group");
        GUILayout.BeginScrollView(m_PaletteSelectionScroll);

        foreach (var p in m_AvailablesPalettes)
        {
            GUI.enabled = m_CurrentGroup != p;
            if (GUILayout.Button(p.name))
            {
                Debug.Log($"clicked on {p.name}");
                if (!m_EditingLayout)
                {
                    if (!SceneView.lastActiveSceneView.drawGizmos)
                    {
                        if (EditorUtility.DisplayDialog("Warning", "Gizmos are globally disabled, which prevent the layout editing tool to work. Do you want to re-enable Gizmos?", "Yes", "No"))
                        {
                            SceneView.lastActiveSceneView.drawGizmos = true;
                            m_EditingLayout = true;
                        }
                    }
                    else
                    {
                        m_EditingLayout = true;
                    }
                }

                if (m_EditingLayout)
                {
                    m_CurrentGroup = p;
                }
            }
        }

        GUI.enabled = true;

        GUILayout.EndScrollView();
        GUILayout.EndVertical();

        m_PaletteSelectionScroll = GUILayout.BeginScrollView(m_PaletteSelectionScroll, GUILayout.Width(72 * 3));
        GUILayout.BeginVertical();

        if (m_CurrentGroup != null)
        {
            bool horizontalOpen = false;

            for (int i = 0; i < m_CurrentGroup.levelPart.Length; ++i)
            {
                LevelRoom part = m_CurrentGroup.levelPart[i];

                if (i % 3 == 0 && i != 0)
                {
                    GUILayout.EndHorizontal();
                    horizontalOpen = false;
                }

                if (!horizontalOpen)
                {
                    GUILayout.BeginHorizontal();
                    horizontalOpen = true;
                }

                Texture2D preview = AssetPreview.GetAssetPreview(part.gameObject);

                GUI.enabled = part != m_SelectedRoom;
                if (GUILayout.Button(preview, GUILayout.Width(64), GUILayout.Height(64)))
                {
                    m_SelectedRoom = part;

                    if (m_CurrentInstance != null)
                    {
                        DestroyImmediate(m_CurrentInstance.gameObject);
                    }

                    m_CurrentInstance = Instantiate(m_SelectedRoom, m_LevelLayout.transform);
                    m_CurrentInstance.gameObject.isStatic = false;
                    m_CurrentInstance.gameObject.tag      = "EditorOnly";
                    m_CurrentInstance.name = "TempInstance";
                    m_CurrentUsedExit      = 0;

                    m_CurrentInstance.transform.localScale = m_CurrentScale;

                    m_EditingMode = 0;
                }
            }

            if (horizontalOpen)
            {
                GUILayout.EndHorizontal();
            }
        }

        GUI.enabled = true;
        GUILayout.EndVertical();
        GUILayout.EndScrollView();

        GUILayout.EndHorizontal();
    }
    void RemovePiece()
    {
        int controlID = GUIUtility.GetControlID(FocusType.Keyboard);

        if (GUIUtility.hotControl == 0)
        {
            HandleUtility.AddDefaultControl(controlID);
        }

        if (m_CurrentInstance != null)
        {
            m_CurrentInstance.gameObject.SetActive(false);
        }

        var       mousePos     = Event.current.mousePosition;
        LevelRoom closestPiece = null;
        Bounds    closestBound = new Bounds();

        float closestSqrDist = float.MaxValue;

        for (int i = 0; i < m_LevelLayout.rooms.Length; ++i)
        {
            LevelRoom r = m_LevelLayout.rooms[i];

            if (r == null)
            {
                continue;
            }

            //This bit is inneficient, but should be enough for our purpose here in the kit. In very big scene
            //it could slow down the editing process. Bound should probably be stored in local space or better should
            //find a way to use the built-in picking but that require more complexity than necessary for those small kit
            Bounds b    = new Bounds();
            bool   init = false;

            MeshRenderer[] renderers = r.GetComponentsInChildren <MeshRenderer>();

            if (renderers.Length > 0)
            {
                for (int k = 0; k < renderers.Length; ++k)
                {
                    if (!init)
                    {
                        b    = renderers[k].bounds;
                        init = true;
                    }
                    else
                    {
                        b.Encapsulate(renderers[k].bounds);
                    }
                }
            }
            else
            {
                //if the piece got no collider, it may be an "empty" piece used to introduce gap, so instead look for
                //a collider to find it's size.
                Collider[] colliders = r.GetComponentsInChildren <Collider>();
                for (int k = 0; k < colliders.Length; ++k)
                {
                    if (k == 0)
                    {
                        b = colliders[k].bounds;
                    }
                    else
                    {
                        b.Encapsulate(colliders[k].bounds);
                    }
                }
            }

            var guiPts = HandleUtility.WorldToGUIPoint(b.center);

            Handles.DrawWireDisc(b.center, Vector3.up, 0.5f);

            float dist = (guiPts - mousePos).sqrMagnitude;

            if (dist < closestSqrDist)
            {
                closestSqrDist = dist;
                closestPiece   = r;
                closestBound   = b;
            }
        }

        if (closestPiece != null)
        {
            if (Event.current.type == EventType.Repaint)
            {
                MeshFilter[] filter = closestPiece.GetComponentsInChildren <MeshFilter>();

                if (filter != null)
                {
                    m_HighlightMaterial.SetPass(0);
                    foreach (var f in filter)
                    {
                        if (f.sharedMesh == null)
                        {
                            continue;
                        }

                        Graphics.DrawMeshNow(f.sharedMesh, f.transform.localToWorldMatrix);
                    }
                }

                Handles.DrawWireCube(closestBound.center, closestBound.size);
            }
            else if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && GUIUtility.hotControl == 0)
            {
                closestPiece.Removed();
                Undo.DestroyObjectImmediate(closestPiece.gameObject);
            }
            else
            {
                SceneView.currentDrawingSceneView.Repaint();
            }
        }
    }
    void AddPiece()
    {
        if (m_CurrentInstance == null)
        {
            return;
        }

        m_CurrentInstance.gameObject.SetActive(true);

        //Since the scene view is not having focus after we choose a new room, pressing R won't rotate it until
        //we click on the scene view. So we force focus on windows. But we only do it if the cursor is above the
        //scene view otherwise we mess focus on OSX with the scene view always stealing focus from other app
        if (SceneView.currentDrawingSceneView.position.Contains(GUIUtility.GUIToScreenPoint(Event.current.mousePosition)))
        {
            SceneView.currentDrawingSceneView.Focus();
        }

        int controlID = GUIUtility.GetControlID(FocusType.Keyboard);

        if (GUIUtility.hotControl == 0)
        {
            HandleUtility.AddDefaultControl(controlID);
        }

        if (Event.current.GetTypeForControl(controlID) == EventType.KeyDown)
        {
            if (Event.current.keyCode == KeyCode.R)
            {
                m_CurrentUsedExit = m_CurrentUsedExit + 1 >= m_CurrentInstance.Exits.Length ? 0 : m_CurrentUsedExit + 1;
            }
        }


        LevelRoom currentClosestPiece = null;
        int       currentClosestExit  = -1;

        if (m_LevelLayout.rooms.Length == 0)
        {//if we have no piece, we force the instance in 0,0,0, as it's the seed piece
            m_CurrentInstance.transform.position = m_LevelLayout.transform.TransformPoint(Vector3.zero);
        }
        else
        {
            var mousePos = Event.current.mousePosition;

            float closestSqrDist = float.MaxValue;
            for (int i = 0; i < m_LevelLayout.rooms.Length; ++i)
            {
                LevelRoom r = m_LevelLayout.rooms[i];

                if (r == null)
                {
                    continue;
                }

                for (int k = 0; k < r.Exits.Length; ++k)
                {
                    if (r.ExitDestination[k] != null)
                    {
                        continue;
                    }

                    var guiPts = HandleUtility.WorldToGUIPoint(r.Exits[k].transform.position);

                    float dist = (guiPts - mousePos).sqrMagnitude;

                    if (dist < closestSqrDist)
                    {
                        closestSqrDist      = dist;
                        currentClosestPiece = r;
                        currentClosestExit  = k;
                    }
                }
            }

            if (currentClosestPiece != null)
            {
                m_CurrentInstance.transform.rotation = Quaternion.identity;

                Transform closest  = currentClosestPiece.Exits[currentClosestExit];
                Transform usedExit = m_CurrentInstance.Exits[m_CurrentUsedExit];

                Quaternion targetRotation = Quaternion.LookRotation(-closest.forward, closest.up);
                Quaternion difference     = targetRotation * Quaternion.Inverse(usedExit.rotation);

                Quaternion rotation = m_CurrentInstance.transform.rotation * difference;
                m_CurrentInstance.transform.rotation = rotation;

                m_CurrentInstance.transform.position = closest.position + m_CurrentInstance.transform.TransformVector(-usedExit.transform.localPosition);
            }
        }


        //if hot control is not 0, that mean we clicked a gizmo and we don't want that.
        if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && GUIUtility.hotControl == 0)
        {
            var c = PrefabUtility.InstantiatePrefab(m_SelectedRoom) as LevelRoom;

            int i = Undo.GetCurrentGroup();
            Undo.SetCurrentGroupName("Added new piece");

            Undo.RegisterCreatedObjectUndo(c.gameObject, "Added new piece");

            c.gameObject.hideFlags = HideFlags.HideInHierarchy;
            c.transform.SetParent(m_LevelLayout.transform, false);

            c.transform.position   = m_CurrentInstance.transform.position;
            c.transform.rotation   = m_CurrentInstance.transform.rotation;
            c.transform.localScale = m_CurrentInstance.transform.localScale;

            c.name = m_SelectedRoom.gameObject.name;
            c.gameObject.isStatic = true;

            c.Placed(m_LevelLayout);

            m_PieceProperty.serializedObject.Update();

            m_PieceProperty.InsertArrayElementAtIndex(m_PieceProperty.arraySize);
            m_PieceProperty.GetArrayElementAtIndex(m_PieceProperty.arraySize - 1).objectReferenceValue = c;

            if (currentClosestPiece != null)
            {
                Snap(currentClosestPiece, c, currentClosestExit, m_CurrentUsedExit);

                //go through all remaining exit and will find if it is close to another to link it
                for (int k = 0; k < c.Exits.Length; ++k)
                {
                    if (k == m_CurrentUsedExit)
                    {
                        continue;
                    }

                    bool      exitLinked = false;
                    Transform testedExit = c.Exits[k];

                    for (int r = 0; r < m_LevelLayout.rooms.Length && !exitLinked; ++r)
                    {
                        for (int re = 0; re < m_LevelLayout.rooms[r].Exits.Length; ++re)
                        {
                            //this is an already used exit no need to test here
                            if (m_LevelLayout.rooms[r].ExitDestination[re] != null)
                            {
                                continue;
                            }

                            //if we are close enough, let's consider those 2 exit Linked.
                            if (Vector3.SqrMagnitude(m_LevelLayout.rooms[r].Exits[re].position - testedExit.position) < 0.2f * 0.2f)
                            {
                                Snap(m_LevelLayout.rooms[r], c, re, k);
                                exitLinked = true;
                                break;
                            }
                        }
                    }
                }
            }

            Undo.CollapseUndoOperations(i);

            m_PieceProperty.serializedObject.ApplyModifiedProperties();
        }
    }
示例#30
0
    /// <summary>
    /// Adds a Room to the world
    /// </summary>
    /// <returns><c>true</c>, if room could be added, <c>false</c> if world space is, at least partially, occupied</returns>
    /// <param name="objRoom">Object room.</param>
    /// <param name="pos">Position.</param>
    /// <param name="dir">Dir.</param>
    public bool AddRoom(GameObject objRoom, Vector2 pos, LookingDirection dir)
    {
        // create instance
        GameObject newRoomObj = Instantiate(objRoom) as GameObject;
        LevelRoom  newRoom    = newRoomObj.GetComponent <LevelRoom>();

        // rotate to correct orientation
        for (int i = 0; i < (int)dir; i++)
        {
            newRoom.Rotate();
        }

        // test if there is enough space for the room in worldspace
        LevelTile testTile;

        foreach (LevelTile tile in newRoom.mLevelTileList)
        {
            testTile = GetTileByPos(pos + tile.Pos);
            if (testTile != null)
            {
                // delete level room transform
                if (Application.isEditor)
                {
                    DestroyImmediate(newRoom.gameObject);
                }
                else
                {
                    Destroy(newRoom.gameObject);
                }

                return(false);
            }
        }

        // add tile to correct position in worldspace, and add to world tile list
        foreach (LevelTile tile in newRoom.mLevelTileList)
        {
            mLevelTileList.Add(tile);
            tile.Reposition(pos + tile.Pos, this, true);
        }

        // rearrange gameobjects to world object
        List <Transform> transList = new List <Transform>();

        // Tiles
        foreach (Transform trans in newRoom.mTilesAnchor)
        {
            transList.Add(trans);
        }
        for (int i = 0; i < transList.Count; i++)
        {
            transList[i].parent = World.Instance.mTilesAnchor;
        }
        transList.Clear();

        // Decals
        foreach (Transform trans in newRoom.mDecalObjectsAnchor)
        {
            transList.Add(trans);
        }
        for (int i = 0; i < transList.Count; i++)
        {
            transList[i].parent = World.Instance.mDecalObjectsAnchor;
        }
        transList.Clear();

        // Triggerables
        foreach (Transform trans in newRoom.mTriggableListAnchor)
        {
            transList.Add(trans);
        }
        for (int i = 0; i < transList.Count; i++)
        {
            transList[i].parent = World.Instance.mTriggableListAnchor;
        }
        transList.Clear();

        // Enemies
        foreach (Transform trans in newRoom.mEnemiesAnchor)
        {
            transList.Add(trans);
        }
        for (int i = 0; i < transList.Count; i++)
        {
            transList[i].parent = World.Instance.mEnemiesAnchor;
        }
        transList.Clear();

        // Items
        foreach (Transform trans in newRoom.mItemObjectsAnchor)
        {
            transList.Add(trans);
        }
        for (int i = 0; i < transList.Count; i++)
        {
            transList[i].parent = World.Instance.mItemObjectsAnchor;
        }

        // delete level room transform
        if (Application.isEditor)
        {
            DestroyImmediate(newRoom.gameObject);
        }
        else
        {
            Destroy(newRoom.gameObject);
        }

        //finish up
        // set connectiong wall to not existent
        GetTileByPos(pos).SetWallStatus(GetOppositeDirection(dir), false);

        return(true);
    }