Ejemplo n.º 1
0
    public int ScatterResources(SurfaceRect fill_rect, ResourceType rtype, int volume)
    {
        if (volume == 0 | fill_rect.size == 0)
        {
            return(volume);
        }
        else
        {
            // ScalableHarvestableResource stick rect size == 2
            int   rowcount = fill_rect.size / 2;
            float rowCount_f = rowcount;
            byte  val = 0, limitVal = ScalableHarvestableResource.MAX_STICK_VOLUME, minVal = ScalableHarvestableResource.RESOURCES_PER_LEVEL;

            float maxStickVolume = volume; maxStickVolume /= fill_rect.size; maxStickVolume /= fill_rect.size;
            if (maxStickVolume < limitVal)
            {
                maxStickVolume = limitVal;
            }
            int x0, z0;

            ScalableHarvestableResource scr = null;
            for (int x = 0; x < rowcount; x++)
            {
                for (int z = 0; z < rowcount; z++)
                {
                    if (volume <= minVal)
                    {
                        goto ENDCYCLE;
                    }
                    x0  = fill_rect.x + x * 2;
                    z0  = fill_rect.z + z * 2;
                    val = (byte)(Mathf.PerlinNoise(x / rowCount_f, z / rowCount_f) * maxStickVolume);
                    if (val < minVal)
                    {
                        val = minVal;
                    }
                    else
                    {
                        if (val > limitVal)
                        {
                            val = limitVal;
                        }
                    }

                    if (!map[x0 * INNER_RESOLUTION + z0] & !map[(x0 + 1) * INNER_RESOLUTION + z0] &
                        !map[x0 * INNER_RESOLUTION + z0 + 1] & !map[(x0 + 1) * INNER_RESOLUTION + z0 + 1])
                    {
                        if (val < volume)
                        {
                            scr     = ScalableHarvestableResource.Create(rtype, val, myPlane, new PixelPosByte(x0, z0));
                            volume -= val;
                        }
                        else
                        {
                            scr    = ScalableHarvestableResource.Create(rtype, (byte)volume, myPlane, new PixelPosByte(x0, z0));
                            volume = 0;
                        }
                    }
                }
            }
        }
ENDCYCLE:
        return(volume);
    }
    override protected void LabourResult(int iterations)
    {
        if (iterations < 1)
        {
            return;
        }
        workflow   -= iterations;
        actionLabel = "";
        int length = PlaneExtension.INNER_RESOLUTION / ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE;

        bool?[,] pillarsMap = new bool?[length, length]; // true - full pillar, false - unfinished, null - no pillar
        for (int a = 0; a < length; a++)
        {
            for (int b = 0; b < length; b++)
            {
                pillarsMap[a, b] = null;
            }
        }
        int maxPillarsCount = length * length;
        int emptyPositions  = maxPillarsCount;

        int finishedPillarsCount = 0, totalResourcesCount = 0, deletedStructures = 0;
        var unfinishedPillarsList       = new List <ScalableHarvestableResource>();
        ScalableHarvestableResource shr = null;
        PlaneExtension pe = workplace.FORCED_GetExtension(); // создаем запросом, так как все равно понадобится

        while (iterations > 0)
        {
            iterations--;
            if (pe.fulfillStatus != FullfillStatus.Empty)
            { // на поверхности есть какие-то структуры
                byte maxVolume = ScalableHarvestableResource.MAX_STICK_VOLUME;
                int  i         = 0;
                var  strs      = pe.GetStructuresList();

                while (i < strs.Count)
                {
                    shr = strs[i] as ScalableHarvestableResource;
                    if (shr != null)
                    {
                        if (shr.mainResource != rtype)
                        {
                            shr.Harvest();
                        }
                        else
                        {
                            if (shr.resourceCount == maxVolume)
                            {
                                finishedPillarsCount++;
                                pillarsMap[shr.surfaceRect.x / ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE, shr.surfaceRect.z / ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE] = true;
                            }
                            else
                            {
                                unfinishedPillarsList.Add(shr);
                                pillarsMap[shr.surfaceRect.x / ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE, shr.surfaceRect.z / ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE] = false;
                                totalResourcesCount += shr.resourceCount;
                            }
                        }
                    }
                    else
                    {
                        Structure s = strs[i];
                        if (s.isArtificial)
                        {
                            s.Annihilate(StructureAnnihilationOrder.GrindedByWorksite);
                            return;
                        }
                        else
                        {
                            if (s.ID == Structure.PLANT_ID)
                            {
                                (s as Plant).Harvest(false);
                            }
                            else
                            {
                                s.Annihilate(StructureAnnihilationOrder.GrindedByWorksite);
                            }
                            deletedStructures++;
                            if (deletedStructures >= 4)
                            {
                                break;                         // не больше 4-х удалений за тик
                            }
                        }
                    }
                    i++;
                }
            }
            shr = null;

            if (finishedPillarsCount == maxPillarsCount)
            {
                if (iterations == 0)
                {
                    actionLabel = Localization.GetActionLabel(LocalizationActionLabels.BlockCompleted);
                }
                var cpos = workplace.pos;
                switch (workplace.faceIndex)
                {
                case Block.FWD_FACE_INDEX: cpos = new ChunkPos(cpos.x, cpos.y, cpos.z + 1); break;

                case Block.RIGHT_FACE_INDEX: cpos = new ChunkPos(cpos.x + 1, cpos.y, cpos.z); break;

                case Block.BACK_FACE_INDEX: cpos = new ChunkPos(cpos.x, cpos.y, cpos.z - 1); break;

                case Block.LEFT_FACE_INDEX: cpos = new ChunkPos(cpos.x - 1, cpos.y, cpos.z); break;

                case Block.UP_FACE_INDEX: cpos = new ChunkPos(cpos.x, cpos.y + 1, cpos.z); break;

                case Block.DOWN_FACE_INDEX: cpos = new ChunkPos(cpos.x, cpos.y - 1, cpos.z); break;
                }
                workplace.myChunk.AddBlock(cpos, rtype.ID, false, true);
                pe.ClearSurface(PlaneAnnihilationOrder.BlockbuildingPartsReplacement);
                StopWork(true);
                return;
            }
            else
            {
                totalResourcesCount += finishedPillarsCount * ScalableHarvestableResource.MAX_STICK_VOLUME;
                int   unfinishedCount     = unfinishedPillarsList.Count;
                byte  resourceNeeded      = ScalableHarvestableResource.RESOURCES_PER_LEVEL;
                float resourceTaken       = colony.storage.GetResources(rtype, resourceNeeded);
                bool  newContainerCreated = false;

                if (unfinishedCount + finishedPillarsCount < maxPillarsCount)
                {
                    if (Random.value > 0.5f && resourceTaken == resourceNeeded) // creating new container
                    {
                        var emptyPositionsIndexes = new List <int>();
                        for (int x = 0; x < length; x++)
                        {
                            for (int z = 0; z < length; z++)
                            {
                                if (pillarsMap[x, z] == null)
                                {
                                    emptyPositionsIndexes.Add(x * length + z);
                                }
                            }
                        }
                        int epcount = emptyPositionsIndexes.Count;
                        if (epcount > 0)
                        {
                            int combinedIndex = emptyPositionsIndexes[Random.Range(0, epcount)];
                            ScalableHarvestableResource.Create(rtype, resourceNeeded, workplace,
                                                               new PixelPosByte(
                                                                   (combinedIndex / length) * ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE,
                                                                   (combinedIndex % length) * ScalableHarvestableResource.RESOURCE_STICK_RECT_SIZE)
                                                               );
                            newContainerCreated = true;
                        }
                        emptyPositionsIndexes = null;
                    }
                }
                // докидываем в существующий
                if (unfinishedCount > 0)
                {
                    if (newContainerCreated)
                    {
                        resourceTaken = colony.storage.GetResources(rtype, resourceNeeded);
                    }
                    if (resourceTaken > 1)
                    {
                        shr           = unfinishedPillarsList[Random.Range(0, unfinishedCount)];
                        resourceTaken = shr.AddResource(rtype, resourceTaken);
                        if (resourceTaken > 0)
                        {
                            colony.storage.AddResource(rtype, resourceTaken);
                        }
                    }
                    else
                    {
                        if (showOnGUI && iterations == 0)
                        {
                            actionLabel = Localization.GetAnnouncementString(GameAnnouncements.NotEnoughResources);
                        }
                    }
                }
            }
        }
    }