示例#1
0
    private bool MatchesConstraints(ChunkMetadata chunkMeta, List <Constraint> constraints)
    {
        bool isMatching = true;

        constraints.ForEach(c => isMatching &= c.IsConstraintSatisfied(chunkMeta, progress));
        return(isMatching);
    }
示例#2
0
    //Other than IsConstraintSatisfied, this method depends on the current context of the chunk generation
    //Returns true, if the ConstraintAmount has not YET been satisfied
    public bool HandleRoomAmount(ChunkMetadata meta, ChunkHelperProgress progress, bool previousResult)
    {
        float remaining     = progress.Remaining(target) + 0.0001f; //Remaining rooms that need be created
        float priorityBonus = (absoluteAmount / remaining);         //A chunk gets a priority bonus if the constrain is satisfied and not all chunks have been created
        int   wantedAmount  = GetAmountValue(progress.TotalRoomCount(target));

        bool enoughCreated = matchingChunksUsed >= wantedAmount;

        meta.Priority += previousResult && !enoughCreated ? priorityBonus: 0f;

        if (previousResult)
        {
            meta.RegisterAsMatching(this);              //Registers this constraint at the chunkmeta and will be notified, if the chunk has been created
        }

        bool stillSatisfied = true;

        switch (amount)
        {
        case ConstraintAmount.AtLeast:
            stillSatisfied = true;             //Allways true, since there is no upper limit
            break;

        case ConstraintAmount.Exactly:        //Exactly and AtMost are handled identically.
        case ConstraintAmount.AtMost:         //The upper amount for AtMost is randomly specified in the GetAmountMethod
            stillSatisfied = !previousResult || (previousResult && !enoughCreated);
            break;
        }

        return(stillSatisfied);
    }
示例#3
0
    //Externally called by ProceduralLevel
    //Returns a chunk that satisfies all constraints and has the same amount of doors definied by the node
    public GameObject PickRandomChunk(RoomNode node)
    {
        ResetMetadata();
        List <ChunkMetadata> candidates = FindChunks(node);

        candidates = candidates.OrderByDescending(cm => cm.Priority).ToList();
        ChunkMetadata selectedMeta  = candidates.Count > 0 ? candidates [0] : null;
        GameObject    selectedChunk = selectedMeta == null ? null : selectedMeta.Chunk;

        progress.NoteChunkUsed(selectedMeta, node.NodeType);          //Informs all constraints, that this chunk has been used
        return(selectedChunk);
    }
示例#4
0
 //Fills a list of objects containing chunks and their metadata required for the following selection of chunks
 //Only needs to be built once per level generation process
 private void BuildMetadata(GameObject[] chunks)
 {
     foreach (GameObject chunk in chunks)
     {
         DoorManager doorManager = chunk.GetComponent <DoorManager> ();
         if (doorManager != null)
         {
             ChunkMetadata meta = new ChunkMetadata();
             meta.Chunk       = chunk;
             meta.DoorManager = doorManager;
             meta.ChunkTags   = chunk.GetComponent <ChunkTags> ();
             meta.Priority    = Random.value;              //Used to naturally shuffle the list (is sorted by Priority)
             chunkMetaData.Add(meta);
         }
     }
 }
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (this.currentChunk == null || this.currentChunkPosition == this.currentChunk.Length)
            {
                this.currentChunkIndex   += 1;
                this.currentChunk         = this.chunks[this.currentChunkIndex];
                this.currentChunkPosition = 0;
                this.currentSourceStream  = this.GetCurrentChunkStreamAsync().GetAwaiter().GetResult();
            }

            var toRead    = Math.Min(count, this.currentChunk.Length - this.currentChunkPosition);
            var readBytes = this.currentSourceStream.Read(buffer, offset, (int)toRead);

            this.position             += readBytes;
            this.currentChunkPosition += readBytes;

            return(readBytes);
        }
示例#6
0
    public void NoteChunkUsed(ChunkMetadata meta, NodeType nodeType)
    {
        if (meta != null)
        {
            meta.NotifyConstraints();
            created.Add(meta);

            switch (nodeType)
            {
            case NodeType.MIDDLE:
                middleRoomsCreated++;
                break;

            case NodeType.SIDE:
                sideRoomsCreated++;
                break;
            }
        }
    }
示例#7
0
    //Used only for Chunks by the ChunkHelper Class
    public bool IsConstraintSatisfied(ChunkMetadata meta, ChunkHelperProgress progress)
    {
        ChunkTags chunkTags = meta.Chunk.GetComponent <ChunkTags> ();
        bool      result    = ConstraintResult(chunkTags);

        if (amount == ConstraintAmount.None)
        {
            //Eventhough the amount is none, we don't want to return false
            //If the result was true, meaning the constraint applies to this chunk, we want to negate it to false
            //This will result in the chunk not being used. If the result was false before, this means that this constraint
            //Doesn't apply to the given chunk, meaning, that we don't want to affect it's creation by returning false, thus returning true
            result = !result;
        }
        else if (amount != ConstraintAmount.All)
        {
            result = HandleRoomAmount(meta, progress, result);
        }

        return(result);
    }