/**
     * Computes the 'intensity' of each {@link MZRoom}. MZRooms generally Get more
     * intense the deeper they are into the dungeon.
     *
     * @param levels    the keyLevel -> room-set mapping to update
     * @ if it fails
     * @see KeyLevelRoomMapping
     * @see MZRoom
     */
    protected void ComputeIntensity(KeyLevelRoomMapping levels)
    {
        double nextLevelBaseIntensity = 0.0;

        for (int level = 0; level < levels.KeyCount(); ++level)
        {
            double intensity = nextLevelBaseIntensity *
                               (1.0 - intensityEaseOff);

            foreach (MZRoom room in levels.GetRooms(level))
            {
                if (room.GetParent() == null ||
                    !room.GetParent().GetPrecond().
                    Implies(room.GetPrecond()))
                {
                    nextLevelBaseIntensity = Math.Max(
                        nextLevelBaseIntensity,
                        ApplyIntensity(room, intensity));
                }
            }
        }

        NormalizeIntensity();

        dungeon.FindBoss().SetIntensity(1.0);
        MZRoom goalRoom = dungeon.FindGoal();

        if (goalRoom != null)
        {
            goalRoom.SetIntensity(0.0);
        }
    }
Beispiel #2
0
    public void Add(MZRoom room)
    {
        rooms[room.id] = room;

        foreach (Vector2Int xy in room.GetCoords())
        {
            if (xy.x < bounds.Left)
            {
                bounds = new MZRect(xy.x, bounds.Top,
                                    bounds.Right, bounds.Bottom);
            }
            if (xy.x >= bounds.Right)
            {
                bounds = new MZRect(bounds.Left, bounds.Top,
                                    xy.x + 1, bounds.Bottom);
            }
            if (xy.y < bounds.Top)
            {
                bounds = new MZRect(bounds.Left, xy.y,
                                    bounds.Right, bounds.Bottom);
            }
            if (xy.y >= bounds.Bottom)
            {
                bounds = new MZRect(bounds.Left, bounds.Top,
                                    bounds.Right, xy.y + 1);
            }
        }
    }
 /**
  * Removes the given {@link MZRoom} and all its descendants from the given
  * list.
  *
  * @param rooms the list of MZRooms to remove nodes from
  * @param room  the MZRoom whose descendants to remove from the list
  */
 protected void RemoveDescendantsFromList(List <MZRoom> rooms, MZRoom room)
 {
     rooms.Remove(room);
     foreach (MZRoom child in room.GetChildren())
     {
         RemoveDescendantsFromList(rooms, child);
     }
 }
 /**
  * Adds extra conditions to the given {@link MZRoom}'s preconditions and all
  * of its descendants.
  *
  * @param room  the MZRoom to Add extra preconditions to
  * @param cond  the extra preconditions to Add
  */
 protected void AddPrecond(MZRoom room, MZCondition cond)
 {
     room.SetPrecond(room.GetPrecond().And(cond));
     foreach (MZRoom child in room.GetChildren())
     {
         AddPrecond(child, cond);
     }
 }
    /**
     * Fill the dungeon's space with rooms and doors (some locked).
     * Keys are not inserted at this point.
     *
     * @param levels    the keyLevel -> room-set mapping to update
     * @ if it fails
     * @see KeyLevelRoomMapping
     */
    protected void PlaceRooms(KeyLevelRoomMapping levels, int roomsPerLock)
    {
        // keyLevel: the number of keys required to Get to the new room
        int      keyLevel  = 0;
        MZSymbol latestKey = null;
        // condition that must hold true for the player to reach the new room
        // (the set of keys they must have).
        MZCondition cond = new MZCondition();

        // Loop to place rooms and link them
        while (dungeon.RoomCount() < constraints.GetMaxRooms())
        {
            bool doLock = false;

            // Decide whether we need to place a new lock
            // (Don't place the last lock, since that's reserved for the boss)
            if (ShouldAddNewLock(keyLevel, levels.GetRooms(keyLevel).Count, roomsPerLock))
            {
                latestKey = new MZSymbol(keyLevel++);
                cond      = cond.And(latestKey);
                doLock    = true;
            }

            // Find an existing room with a free edge:
            MZRoom parentRoom = null;
            if (!doLock && UnityEngine.Random.Range(0, 10) > 0)
            {
                parentRoom = ChooseRoomWithFreeEdge(levels.GetRooms(keyLevel),
                                                    keyLevel);
            }
            if (parentRoom == null)
            {
                parentRoom = ChooseRoomWithFreeEdge(new List <MZRoom>(dungeon.GetRooms()),
                                                    keyLevel);
                doLock = true;
            }

            if (parentRoom == null)
            {
                throw new OutOfRoomsException();
            }

            // Decide which direction to put the new room in relative to the
            // parent
            int nextId = ChooseFreeEdge(parentRoom, keyLevel);
            List <Vector2Int> coords = constraints.GetCoords(nextId);
            MZRoom            room   = new MZRoom(nextId, coords, parentRoom, null, cond);

            // Add the room to the dungeon
            dungeon.Add(room);
            parentRoom.AddChild(room);
            dungeon.Link(parentRoom, room, doLock ? latestKey : null);
            levels.AddRoom(keyLevel, room);
        }
    }
    /**
     * Returns a path from the goal to the dungeon entrance, along the 'parent'
     * relations.
     *
     * @return  a list of linked {@link MZRoom}s starting with the goal room and
     *          ending with the start room.
     */
    protected List <MZRoom> GetSolutionPath()
    {
        List <MZRoom> solution = new List <MZRoom>();
        MZRoom        room     = dungeon.FindGoal();

        while (room != null)
        {
            solution.Add(room);
            room = room.GetParent();
        }
        return(solution);
    }
    /**
     * Sets up the dungeon's entrance room.
     *
     * @param levels    the keyLevel -> room-set mapping to update
     * @see KeyLevelRoomMapping
     */
    protected void InitEntranceRoom(KeyLevelRoomMapping levels)
    {
        int        id;
        List <int> possibleEntries = new List <int>(constraints.InitialRooms());

        id = possibleEntries[UnityEngine.Random.Range(0, possibleEntries.Count)];

        MZRoom entry = new MZRoom(id, constraints.GetCoords(id), null,
                                  new MZSymbol((int)MZSymbol.MZSymbolValue.Start), new MZCondition());

        dungeon.Add(entry);

        levels.AddRoom(0, entry);
    }
    /**
     * Randomly chooses a {@link Direction} in which the given {@link MZRoom} has
     * an adjacent empty space.
     *
     * @param room  the room
     * @return  the Direction of the empty space chosen adjacent to the MZRoom or
     *          null if there are no adjacent empty spaces
     */
    protected int ChooseFreeEdge(MZRoom room, int keyLevel)
    {
        List <KeyValuePair <Double, int> > neighbors = new List <KeyValuePair <Double, int> >(
            constraints.GetAdjacentRooms(room.id, keyLevel));

        Shuffle(neighbors);
        while (neighbors.Count > 0)
        {
            int choice = neighbors[0].Value;
            if (dungeon.Get(choice) == null)
            {
                return(choice);
            }
            neighbors.RemoveAt(0);
        }
        throw new MZGenerationFailureException("Internal error: MZRoom doesn't have a free edge");
    }
Beispiel #9
0
    /**
     * Creates a MZRoom at the given coordinates, with the given parent,
     * containing a specific item, and having a certain pre-{@link MZCondition}.
     * <p>
     * The parent of a room is the parent node of this MZRoom in the initial
     * tree of the dungeon during
     * {@link generators.MZDungeonGenerator#Generate()}, and
     * before
     * {@link generators.MZDungeonGenerator#Graphify()}.
     *
     * @param coords    the coordinates of the new room
     * @param parent    the parent room or null if it is the root / entry room
     * @param item      the symbol to place in the room or null if no item
     * @param precond   the precondition of the room
     * @see MZCondition
     */
    public MZRoom(int id, List <Vector2Int> coords, MZRoom parent, MZSymbol item, MZCondition precond)
    {
        this.id        = id;
        this.coords    = coords;
        this.item      = item;
        this.edges     = new List <MZEdge>();
        this.precond   = precond;
        this.intensity = 0.0;
        this.parent    = parent;
        this.children  = new List <MZRoom>(3);
        // all edges initially null
        int x = 0, y = 0;

        foreach (Vector2Int xy in coords)
        {
            x += xy.x; y += xy.y;
        }
        center = new Vector2Int(x / coords.Count, y / coords.Count);
    }
    /**
     * Recursively applies the given intensity to the given {@link MZRoom}, and
     * higher intensities to each of its descendants that are within the same
     * keyLevel.
     * <p>
     * Intensities set by this method may (will) be outside of the normal range
     * from 0.0 to 1.0. See {@link #NormalizeIntensity} to correct this.
     *
     * @param room      the room to set the intensity of
     * @param intensity the value to set intensity to (some randomn variance is
     *                  Added)
     * @see MZRoom
     */
    protected double ApplyIntensity(MZRoom room, double intensity)
    {
        intensity *= 1.0 - intensityGrowthJitter / 2.0 +
                     intensityGrowthJitter * UnityEngine.Random.value;

        room.SetIntensity(intensity);

        double maxIntensity = intensity;

        foreach (MZRoom child in room.GetChildren())
        {
            if (room.GetPrecond().Implies(child.GetPrecond()))
            {
                maxIntensity = Math.Max(maxIntensity, ApplyIntensity(child,
                                                                     intensity + 1.0));
            }
        }

        return(maxIntensity);
    }
    /**
     * Randomly chooses a {@link MZRoom} within the given collection that has at
     * least one adjacent empty space.
     *
     * @param roomCollection    the collection of rooms to choose from
     * @return  the room that was chosen, or null if there are no rooms with
     *          adjacent empty spaces
     */
    protected MZRoom ChooseRoomWithFreeEdge(List <MZRoom> roomCollection,
                                            int keyLevel)
    {
        List <MZRoom> rooms = new List <MZRoom>(roomCollection);

        Shuffle(rooms);
        for (int i = 0; i < rooms.Count; ++i)
        {
            MZRoom room = rooms[i];
            foreach (KeyValuePair <Double, int> next in
                     constraints.GetAdjacentRooms(room.id, keyLevel))
            {
                if (dungeon.Get(next.Value) == null)
                {
                    return(room);
                }
            }
        }
        return(null);
    }
    /**
     * Randomly locks descendant rooms of the given {@link MZRoom} with
     * {@link MZEdge}s that require the switch to be in the given state.
     * <p>
     * If the given state is Either, the required states will be random.
     *
     * @param room          the room whose child to lock
     * @param givenState    the state to require the switch to be in for the
     *                      child rooms to be accessible
     * @return              true if any locks were Added, false if none were
     *                      Added (which can happen due to the way the random
     *                      decisions are made)
     * @see MZCondition.SwitchState
     */
    protected bool SwitchLockChildRooms(MZRoom room,
                                        MZCondition.SwitchState givenState)
    {
        bool anyLocks = false;

        MZCondition.SwitchState state = givenState != MZCondition.SwitchState.Either
                ? givenState
                : (UnityEngine.Random.Range(0, 2) == 0
                    ? MZCondition.SwitchState.On
                    : MZCondition.SwitchState.Off);

        foreach (MZEdge edge in room.GetEdges())
        {
            int    neighborId = edge.GetTargetRoomId();
            MZRoom nextRoom   = dungeon.Get(neighborId);
            if (room.GetChildren().Contains(nextRoom))
            {
                if (room.GetEdge(neighborId).GetSymbol() == null &&
                    UnityEngine.Random.Range(0, 4) != 0)
                {
                    dungeon.Link(room, nextRoom, state.ToSymbol());
                    AddPrecond(nextRoom, new MZCondition(state.ToSymbol()));
                    anyLocks = true;
                }
                else
                {
                    anyLocks |= SwitchLockChildRooms(nextRoom, state);
                }

                if (givenState == MZCondition.SwitchState.Either)
                {
                    state = state.Invert();
                }
            }
        }
        return(anyLocks);
    }
    /**
     * Randomly links up some adjacent rooms to make the dungeon graph less of
     * a tree.
     *
     * @ if it fails
     */
    protected void Graphify()
    {
        foreach (MZRoom room in dungeon.GetRooms())
        {
            if (room.IsGoal() || room.IsBoss())
            {
                continue;
            }

            foreach (KeyValuePair <Double, int> next in
                     // Doesn't matter what the keyLevel is; later checks about
                     // preconds ensure linkage doesn't trivialize the puzzle.
                     constraints.GetAdjacentRooms(room.id, Int32.MaxValue))
            {
                int nextId = next.Value;

                if (room.GetEdge(nextId) != null)
                {
                    continue;
                }

                MZRoom nextRoom = dungeon.Get(nextId);
                if (nextRoom == null || nextRoom.IsGoal() || nextRoom.IsBoss())
                {
                    continue;
                }

                if (room.GetCoords()[0].x == -1 && room.GetCoords()[0].y == -3)
                {
                    //Debug.Log(nextRoom.GetCoords()[0].x + " " + nextRoom.GetCoords()[0].y);
                    Debug.Log(room.GetEdges().Count);
                }

                bool forwardImplies  = room.GetPrecond().Implies(nextRoom.GetPrecond()),
                     backwardImplies = nextRoom.GetPrecond().Implies(room.GetPrecond());
                if (forwardImplies && backwardImplies)
                {
                    // both rooms are at the same keyLevel.
                    if (UnityEngine.Random.value >=
                        constraints.EdgeGraphifyProbability(room.id, nextRoom.id))
                    {
                        continue;
                    }

                    dungeon.Link(room, nextRoom);
                }
                else
                {
                    MZSymbol difference = room.GetPrecond().SingleSymbolDifference(
                        nextRoom.GetPrecond());
                    if (difference == null || (!difference.IsSwitchState() &&
                                               UnityEngine.Random.value >=
                                               constraints.EdgeGraphifyProbability(room.id, nextRoom.id)))
                    {
                        continue;
                    }

                    dungeon.Link(room, nextRoom, difference);
                }
            }
        }
    }
    /**
     * Makes some {@link MZEdge}s within the dungeon require the dungeon's switch
     * to be in a particular state, and places the switch in a room in the
     * dungeon.
     *
     * @ if it fails
     */
    protected void PlaceSwitches()
    {
        // Possible TODO: have multiple switches on separate circuits
        // At the moment, we only have one switch per dungeon.
        if (constraints.GetMaxSwitches() <= 0)
        {
            return;
        }

        List <MZRoom> solution = GetSolutionPath();

        for (int attempt = 0; attempt < 10; ++attempt)
        {
            List <MZRoom> rooms = new List <MZRoom>(dungeon.GetRooms());
            Shuffle(rooms);
            Shuffle(solution);

            // Pick a base room from the solution path so that the player
            // will have to encounter a switch-lock to solve the dungeon.
            MZRoom baseRoom = null;
            foreach (MZRoom room in solution)
            {
                if (room.GetChildren().Count > 1 && room.GetParent() != null)
                {
                    baseRoom = room;
                    break;
                }
            }
            if (baseRoom == null)
            {
                throw new RetryException();
            }
            MZCondition baseRoomCond = baseRoom.GetPrecond();

            RemoveDescendantsFromList(rooms, baseRoom);

            MZSymbol switchSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Switch);

            MZRoom switchRoom = null;
            foreach (MZRoom room in rooms)
            {
                if (room.GetItem() == null &&
                    baseRoomCond.Implies(room.GetPrecond()) &&
                    constraints.RoomCanFitItem(room.id, switchSym))
                {
                    switchRoom = room;
                    break;
                }
            }
            if (switchRoom == null)
            {
                continue;
            }

            if (SwitchLockChildRooms(baseRoom, MZCondition.SwitchState.Either))
            {
                switchRoom.SetItem(switchSym);
                return;
            }
        }
        throw new RetryException();
    }
Beispiel #15
0
 public MZRoom(int id, Vector2Int coords, MZRoom parent, MZSymbol item, MZCondition precond) :
     this(id, new List <Vector2Int> {
     coords
 }, parent, item, precond)
 {
 }
Beispiel #16
0
 public void Link(MZRoom room1, MZRoom room2)
 {
     Link(room1, room2, null);
 }
    /*
     * private int keyLevel;
     *
     * public AStarClient(int keyLevel)
     * {
     *  this.keyLevel = keyLevel;
     * }
     *
     * public override List<int> GetNeighbors(int roomId)
     * {
     *  List<int> ids = new List<int>();
     *  foreach (MZEdge edge in dungeon.Get(roomId).GetEdges())
     *  {
     *      if (!edge.HasSymbol() || edge.GetSymbol().GetValue() < keyLevel)
     *      {
     *          ids.Add(edge.GetTargetRoomId());
     *      }
     *  }
     *  return ids;
     * }
     * public override Vector2Int GetVector2Int(int roomId)
     * {
     *  return dungeon.Get(roomId).GetCenter();
     * }
     * }
     */
    /*
     * private List<int> AStar(int start, int goal, int keyLevel)
     * {
     *  AStar<int> astar = new AStar<int>();
     *  return astar.Solve();
     * }
     */

    /**
     * Nonlinearity is measured as the number of rooms the player would have to
     * pass through multiple times to Get to the goal room (collecting keys and
     * unlocking doors along the way).
     *
     * Uses A* to find a path from the entry to the first key, from each key to
     * the next key and from the last key to the goal.
     *
     * @return  The number of rooms passed through multiple times
     **/
    public int MeasureNonlinearity()
    {
        List <MZRoom> keyRooms = new List <MZRoom>(constraints.GetMaxKeys());

        for (int i = 0; i < constraints.GetMaxKeys(); ++i)
        {
            keyRooms.Add(null);
        }
        foreach (MZRoom room in dungeon.GetRooms())
        {
            if (room.GetItem() == null)
            {
                continue;
            }
            MZSymbol item = room.GetItem();
            if (item.GetValue() >= 0 && item.GetValue() < keyRooms.Count)
            {
                keyRooms.Insert(item.GetValue(), room);
            }
        }
        //for N >= 0: keyRooms[N] = location of key N

        MZRoom current = dungeon.FindStart(), goal = dungeon.FindGoal();

        //clients may disable generation of the goal room if redundant, in which case the equivalent 'ending' room becomes the boss room
        if (goal == null)
        {
            goal = dungeon.FindBoss();
        }
        Debug.Assert(current != null && goal != null);
        int nextKey = 0, nonlinearity = 0;

        List <int> visitedRooms = new List <int>();

        while (current != goal)
        {
            MZRoom intermediateGoal;

            //Debug.Log("Current room ID: " + current.id);
            //Debug.Log("Max Keys:" + constraints.GetMaxKeys());
            //Debug.Log("Next Key: " + nextKey);

            if (nextKey == constraints.GetMaxKeys())
            {
                intermediateGoal = goal;
            }

            else
            {
                intermediateGoal = keyRooms[nextKey];
            }
            //Debug.Log("Current goal ID: " + intermediateGoal.id);
            ///*
            //Debug.Log("Dungeon: " + dungeon.GetType());
            //*/
            //Debug.Log("A* running...");
            List <int> steps = astar(current.id, intermediateGoal.id, nextKey, dungeon); //ちゃんとこれを作ってよ
            //Debug.Log("Reversing steps!");
            steps.Reverse();

            foreach (int id in steps)
            {
                Debug.Log("Visited Room: " + id);
                if (visitedRooms.Contains(id))
                {
                    ++nonlinearity;
                }
            }
            visitedRooms.AddRange(steps);

            nextKey++;
            current = dungeon.Get(steps[0]);
            MZRoom test = current;
        }
        return(nonlinearity);
    }
    /**
     * Places the BOSS and GOAL rooms within the dungeon, in existing rooms.
     * These rooms are moved into the next keyLevel.
     *
     * @param levels    the keyLevel -> room-set mapping to update
     * @ if it fails
     * @see KeyLevelRoomMapping
     */
    protected void PlaceBossGoalRooms(KeyLevelRoomMapping levels)
    {
        List <MZRoom> possibleGoalRooms = new List <MZRoom>(dungeon.RoomCount());

        MZSymbol goalSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Goal),
                 bossSym = new MZSymbol((int)MZSymbol.MZSymbolValue.Boss);

        foreach (MZRoom room in dungeon.GetRooms())
        {
            if (room.GetChildren().Count > 0 || room.GetItem() != null)
            {
                continue;
            }
            MZRoom parent = room.GetParent();
            if (parent == null)
            {
                continue;
            }
            if (IsGenerateGoal() && (parent.GetChildren().Count != 1 ||
                                     !parent.GetPrecond().Implies(room.GetPrecond())))
            {
                continue;
            }
            if (IsGenerateGoal())
            {
                if (!constraints.RoomCanFitItem(room.id, goalSym) ||
                    !constraints.RoomCanFitItem(parent.id, bossSym))
                {
                    continue;
                }
            }
            else
            {
                if (!constraints.RoomCanFitItem(room.id, bossSym))
                {
                    continue;
                }
            }
            possibleGoalRooms.Add(room);
        }

        if (possibleGoalRooms.Count == 0)
        {
            throw new RetryException();
        }

        MZRoom goalRoom = possibleGoalRooms[UnityEngine.Random.Range(0,
                                                                     possibleGoalRooms.Count)],
               bossRoom = goalRoom.GetParent();

        if (!IsGenerateGoal())
        {
            bossRoom = goalRoom;
            goalRoom = null;
        }

        if (goalRoom != null)
        {
            goalRoom.SetItem(goalSym);
        }
        bossRoom.SetItem(bossSym);

        int oldKeyLevel = bossRoom.GetPrecond().GetKeyLevel(),
            newKeyLevel = Math.Min(levels.KeyCount(), constraints.GetMaxKeys());

        if (oldKeyLevel != newKeyLevel)
        {
            List <MZRoom> oklRooms = levels.GetRooms(oldKeyLevel);
            if (goalRoom != null)
            {
                oklRooms.Remove(goalRoom);
            }
            oklRooms.Remove(bossRoom);

            if (goalRoom != null)
            {
                levels.AddRoom(newKeyLevel, goalRoom);
            }
            levels.AddRoom(newKeyLevel, bossRoom);

            MZSymbol    bossKey = new MZSymbol(newKeyLevel - 1);
            MZCondition precond = bossRoom.GetPrecond().And(bossKey);
            bossRoom.SetPrecond(precond);
            if (goalRoom != null)
            {
                goalRoom.SetPrecond(precond);
            }

            if (newKeyLevel == 0)
            {
                dungeon.Link(bossRoom.GetParent(), bossRoom);
            }
            else
            {
                dungeon.Link(bossRoom.GetParent(), bossRoom, bossKey);
            }
            if (goalRoom != null)
            {
                dungeon.Link(bossRoom, goalRoom);
            }
        }
    }
Beispiel #19
0
 public bool RoomsAreLinked(MZRoom room1, MZRoom room2)
 {
     return(room1.GetEdge(room2.id) != null || room2.GetEdge(room1.id) != null);
 }
Beispiel #20
0
 /**
  * Registers this MZRoom as a parent of another.
  * Does not modify the child room's parent property.
  *
  * @param child the room to parent
  */
 public void AddChild(MZRoom child)
 {
     children.Add(child);
 }
 public void AddRoom(int keyLevel, MZRoom room)
 {
     GetRooms(keyLevel).Add(room);
 }
Beispiel #22
0
 public void Link(MZRoom room1, MZRoom room2, MZSymbol cond)
 {
     LinkOneWay(room1, room2, cond);
     LinkOneWay(room2, room1, cond);
 }
Beispiel #23
0
 public void LinkOneWay(MZRoom room1, MZRoom room2, MZSymbol cond)
 {
     room1.SetEdge(room2.id, cond);
 }
Beispiel #24
0
    public void CreateDungeon()
    {
        float roomRatio = 0.6875f; // 256x176


        // Use CountConstraints to make a truly random map.

        /*
         * CountConstraints constraints = new CountConstraints((int)maxSpaces, (int)maxKeys, (int)maxSwitches);
         * Debug.Log("Constraints: " + maxSpaces + "," + maxKeys + "," + maxSwitches);
         */

        // Use SpaceConstraints to make a map fitting to a shape.
        ///*
        MZSpaceMap spaceMap = new MZSpaceMap();

        //random tile map
        //tileMap = tileMapObjects[Random.Range(0, tileMapObjects.Length)].GetComponentInChildren<Tilemap>();
        tileMap = tileMapObjects[0].GetComponentInChildren <Tilemap>();
        foreach (Vector3Int posWithZ in tileMap.cellBounds.allPositionsWithin.GetEnumerator())
        {
            if (tileMap.HasTile(posWithZ))
            {
                Vector2Int pos = new Vector2Int(posWithZ.x, posWithZ.y);
                spaceMap.Set(pos, true);
            }
        }

        SpaceConstraints constraints = new SpaceConstraints(spaceMap, (int)maxKeys, (int)maxSwitches);

        //*/
        generator = new LinearDungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms, (int)maxGenerations);
        //generator = new DungeonGenerator(Random.Range(0, int.MaxValue), constraints, numberOfRooms);

        Debug.Log("Generate()");
        generator.Generate();
        dungeon = generator.GetMZDungeon();
        foreach (MZRoom room in dungeon.GetRooms())
        {
            MZSymbol   item          = room.GetItem();
            GameObject toInstantiate = normalRoom;
            Color      roomColor     = new Color((float)room.GetIntensity(), 1.0f - (float)room.GetIntensity(), 0.5f - (float)room.GetIntensity() / 2);
            if (item != null)
            {
                switch (item.GetValue())
                {
                case (int)MZSymbol.MZSymbolValue.Start:
                    toInstantiate = entranceRoom;
                    roomColor     = Color.white;
                    break;

                case (int)MZSymbol.MZSymbolValue.Boss:
                    toInstantiate = bossRoom;
                    break;

                case (int)MZSymbol.MZSymbolValue.Goal:
                    toInstantiate = goalRoom;
                    roomColor     = Color.white;
                    break;

                default:
                    break;
                }

                if (item.GetValue() >= 0)
                {
                    GameObject keyObjectInstance = Instantiate(key, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
                    keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColors[item.GetValue()];
                    keyObjectInstance.transform.localScale += new Vector3(2, 2, 2);
                    instances.Add(keyObjectInstance);
                }
                else if (item.GetValue() == (int)MZSymbol.MZSymbolValue.Switch)
                {
                    GameObject keyObjectInstance = Instantiate(roomSwitch, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
                    keyObjectInstance.transform.localScale += new Vector3(2, 2, 2);
                    instances.Add(keyObjectInstance);
                }
            }

            GameObject roomObject = Instantiate(toInstantiate, new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio, 0), Quaternion.identity, transform);
            roomObject.GetComponent <SpriteRenderer>().color = roomColor;
            instances.Add(roomObject);

            foreach (MZEdge edge in room.GetEdges())
            {
                MZRoom     targetRoom = dungeon.Get(edge.GetTargetRoomId());
                Vector2Int edgeDir    = targetRoom.GetCoords()[0] - room.GetCoords()[0];

                toInstantiate = openDoor;
                GameObject keyObject = null;
                Color      keyColor  = Color.white;
                if (edge.GetSymbol() != null)
                {
                    switch (edge.GetSymbol().GetValue())
                    {
                    case (int)MZSymbol.MZSymbolValue.SwitchOn:
                        toInstantiate = blockedDoor;
                        keyObject     = roomSwitchOn;
                        break;

                    case (int)MZSymbol.MZSymbolValue.SwitchOff:
                        toInstantiate = blockedDoor;
                        keyObject     = roomSwitchOff;
                        break;

                    default:
                        break;
                    }

                    if (edge.GetSymbol().GetValue() >= 0)
                    {
                        toInstantiate = lockedDoor;
                        keyObject     = key;
                        keyColor      = keyColors[edge.GetSymbol().GetValue()];
                    }
                }

                //this only works for identically sized rooms
                Vector3 pos = Vector3.zero;
                if (edgeDir == Vector2Int.right)
                {
                    pos = new Vector3(room.GetCoords()[0].x + 0.5f, room.GetCoords()[0].y * roomRatio, 0);
                    GameObject doorObject = Instantiate(toInstantiate, pos, Quaternion.identity, transform);
                    instances.Add(doorObject);
                    if (keyObject != null)
                    {
                        GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform);
                        instances.Add(keyObjectInstance);
                        keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor;
                        keyObjectInstance.transform.localScale += new Vector3(1, 1, 1);
                    }
                }
                else if (edgeDir == Vector2Int.down)
                {
                    pos = new Vector3(room.GetCoords()[0].x, room.GetCoords()[0].y * roomRatio - (roomRatio / 2), 0);
                    Vector2Int relativePos = Vector2Int.zero + Vector2Int.up;
                    float      angle       = Mathf.Atan2(relativePos.y, relativePos.x) * Mathf.Rad2Deg;
                    Quaternion rotation    = Quaternion.AngleAxis(angle, Vector3.forward); //90 degrees
                    GameObject doorObject  = Instantiate(toInstantiate, pos, rotation, transform);
                    instances.Add(doorObject);
                    if (keyObject != null)
                    {
                        GameObject keyObjectInstance = Instantiate(keyObject, pos, Quaternion.identity, transform);
                        instances.Add(keyObjectInstance);
                        keyObjectInstance.GetComponent <SpriteRenderer>().color = keyColor;
                        keyObjectInstance.transform.localScale += new Vector3(1, 1, 1);
                    }
                }
            }
        }
        foreach (var room in dungeon.GetRooms())
        {
            foreach (var edge in room.GetEdges())
            {
                //wrap this up laterino
            }
        }
    }
Beispiel #25
0
 /**
  * @param parent the MZRoom to set this MZRoom's parent to
  * @see MZRoom#Room
  */
 public void SetParent(MZRoom parent)
 {
     this.parent = parent;
 }
Beispiel #26
0
 public void LinkOneWay(MZRoom room1, MZRoom room2)
 {
     LinkOneWay(room1, room2, null);
 }