Пример #1
0
    void GenerateNewBuildings(int minAmount, int maxAmount, bool isNewGame = false)
    {
        // first create building and floors
        List <Floor> allGeneratedFloors = new List <Floor>();
        int          amountOfBuildings  = UnityEngine.Random.Range(minAmount, maxAmount);

        // "tutorial"
        if (isNewGame)
        {
            amountOfBuildings = 1;
        }

        for (int i = 0; i < amountOfBuildings; i++)
        {
            GameObject newBuildingObject = Instantiate(BuildingPrefab);
            Building   newBuilding       = newBuildingObject.GetComponent <Building>();

            newBuilding.transform.SetParent(LevelParent);
            Vector3 buildingPos = Vector3.zero;
            buildingPos.x = BUILDING_WIDTH * (float)(((int)(i + MaxBuildingIndex + 1)) / 2);

            if ((i + MaxBuildingIndex) % 2 == 0)
            {
                buildingPos.x *= -1f;
            }

            newBuilding.transform.localPosition = buildingPos;
            newBuilding.transform.localScale    = Vector3.one;

            int buildingHeight = UnityEngine.Random.Range(BUILDING_MIN_HEIGHT, BUILDING_MAX_HEIGHT + 1);
            newBuilding.BaseLevel = UnityEngine.Random.Range(BUILDING_MIN_BASE_LEVEL, BUILDING_MAX_BASE_LEVEL + 1);

            // make sure each building is at least above the ground, we don't want any bunkers
            if (buildingHeight + newBuilding.BaseLevel < BUILDING_MIN_HEIGHT)
            {
                buildingHeight = BUILDING_MIN_HEIGHT - newBuilding.BaseLevel;
            }

            // "tutorial"
            if (isNewGame && IsFirstGame)
            {
                newBuilding.BaseLevel = -1;
                buildingHeight        = 3;
            }

            // select facade
            newBuilding.Init();

            int buildingsIndex = 0;
            if ((i + MaxBuildingIndex) % 2 == 1)
            {
                buildingsIndex = CurrentLevel.Buildings.Count;
                CurrentLevel.Buildings.Add(newBuilding);
            }
            else
            {
                CurrentLevel.Buildings.Insert(0, newBuilding);
            }

            for (int j = 0; j < buildingHeight; j++)
            {
                GameObject newFloorObject = Instantiate(FloorPrefab);
                Floor      newFloor       = newFloorObject.GetComponent <Floor>();

                newFloor.Init(newBuilding.PatternColor, j == buildingHeight - 1, j + newBuilding.BaseLevel == 0, j + newBuilding.BaseLevel < 0);

                newFloor.transform.SetParent(newBuilding.transform);
                Vector3 floorPos = Vector3.zero;
                floorPos.y = FLOOR_HEIGHT * (newBuilding.BaseLevel + j);
                newFloor.transform.localPosition = floorPos;
                newFloor.transform.localScale    = Vector3.one;

                newBuilding.Floors.Add(newFloor);
                allGeneratedFloors.Add(newFloor);

                // assign vertical neighbours
                if (j > 0)
                {
                    newFloor.nextFloors[(int)Dir.S] = newBuilding.Floors[newBuilding.Floors.Count - 2];
                    newBuilding.Floors[newBuilding.Floors.Count - 2].nextFloors[(int)Dir.N] = newFloor;
                }
            }

            // assign horizontal neighbours
            if (buildingsIndex > 0)
            {
                newBuilding.GetGroundFloor().nextFloors[(int)Dir.W] = CurrentLevel.Buildings[CurrentLevel.Buildings.Count - 2].GetGroundFloor();
                CurrentLevel.Buildings[CurrentLevel.Buildings.Count - 2].GetGroundFloor().nextFloors[(int)Dir.E] = newBuilding.GetGroundFloor();
            }
            else if (!isNewGame)
            {
                newBuilding.GetGroundFloor().nextFloors[(int)Dir.E] = CurrentLevel.Buildings[buildingsIndex + 1].GetGroundFloor();
                CurrentLevel.Buildings[buildingsIndex + 1].GetGroundFloor().nextFloors[(int)Dir.W] = newBuilding.GetGroundFloor();
            }

            // generate ground if needed
            if (MaxBuildingIndex > maxGroundX / 5f)
            {
                GameObject ground1 = Instantiate(GroundPrefab);
                ground1.transform.SetParent(ParallaxesParent);
                Vector3 ground1Pos = Vector3.zero;
                minGroundX  -= 108f;
                ground1Pos.x = minGroundX;
                ground1.transform.localPosition = ground1Pos;
                ground1.transform.localScale    = Vector3.one;

                GameObject ground2 = Instantiate(GroundPrefab);
                ground2.transform.SetParent(ParallaxesParent);
                Vector3 ground2Pos = Vector3.zero;
                maxGroundX  += 108f;
                ground2Pos.x = maxGroundX;
                ground2.transform.localPosition = ground2Pos;
                ground2.transform.localScale    = Vector3.one;
            }

            // add roof on top of the building
            GameObject newRoof = Instantiate(RoofPrefab);
            newRoof.transform.SetParent(newBuilding.transform);
            Vector3 roofPos = Vector3.zero;
            roofPos.y = FLOOR_HEIGHT * (newBuilding.BaseLevel + buildingHeight);
            newRoof.transform.localPosition = roofPos;
            newRoof.transform.localScale    = Vector3.one;
            newRoof.GetComponent <Roof>().Init();
        }

        // we'll need this next time
        MaxBuildingIndex += amountOfBuildings;

        // don't have any items on ground floor of the first building
        if (isNewGame)
        {
            allGeneratedFloors.RemoveAt(0 - CurrentLevel.Buildings[0].BaseLevel);
        }

        // now distribute POIs and pickable objects
        int availableFloorsAmount = allGeneratedFloors.Count;

        for (int i = 0; i < availableFloorsAmount; i += 2)
        {
            // first generate thought
            List <Thought> ApplicableThoughts = new List <Thought>();
            foreach (Thought t in ThoughtsPrefabs)
            {
                if (!thoughtsGeneratedDuringThisRound.Contains(t.ThoughtType))
                {
                    ApplicableThoughts.Add(t);
                }
            }

            // no unique thoguhts available, fallback to any
            if (ApplicableThoughts.Count == 0)
            {
                foreach (Thought t in ThoughtsPrefabs)
                {
                    ApplicableThoughts.Add(t);
                }
            }

            // OK, allow thoughts to repeat again if all already exist
            if (thoughtsGeneratedDuringThisRound.Count == ThoughtsPrefabs.Count)
            {
                thoughtsGeneratedDuringThisRound.Clear();
            }

            Thought thought = Instantiate(ApplicableThoughts[UnityEngine.Random.Range(0, ApplicableThoughts.Count)]);
            thoughtsGeneratedDuringThisRound.Add(thought.ThoughtType);

            // then generate person
            List <PersonOfInterest> ApplicablePeople = new List <PersonOfInterest>();
            foreach (PersonOfInterest p in PeopleOfInterestPrefabs)
            {
                if (thought.CanBeAppliedToCharacter(p))
                {
                    ApplicablePeople.Add(p);
                }
            }

            PersonOfInterest person = Instantiate(ApplicablePeople[UnityEngine.Random.Range(0, ApplicablePeople.Count)]);
            person.CurrentThought = thought;
            person.Init();

            int selectedFloorIndex = UnityEngine.Random.Range(0, allGeneratedFloors.Count);

            // tutorial - always person on 1st, then item on 2nd
            if (isNewGame && IsFirstGame)
            {
                selectedFloorIndex = i;
            }

            allGeneratedFloors[selectedFloorIndex].Person = person;

            person.transform.SetParent(allGeneratedFloors[selectedFloorIndex].transform);
            person.transform.localPosition = Vector3.zero;
            person.transform.localScale    = Vector3.one;

            allGeneratedFloors.RemoveAt(selectedFloorIndex);

            if (allGeneratedFloors.Count <= 0)
            {
                return;
            }

            AmountOfMatchesLeft++;
            MaxAmountOfMatches++;

            // then corresponding pickable object
            PickableObject pickable;
            if (i > availableFloorsAmount / 2)
            {
                pickable = Instantiate(PickablePrefabs[UnityEngine.Random.Range(0, PickablePrefabs.Count)]);
            }
            else
            {
                pickable = Instantiate(person.CurrentThought.ContraryObjects[UnityEngine.Random.Range(0, person.CurrentThought.ContraryObjects.Count)]);
            }

            selectedFloorIndex = UnityEngine.Random.Range(0, allGeneratedFloors.Count);
            PutObjectOnFloor(pickable, allGeneratedFloors[selectedFloorIndex]);

            allGeneratedFloors.RemoveAt(selectedFloorIndex);
        }
    }