Beispiel #1
0
        public static void PreparePaste()
        {
            InserterPoses.ResetOverrides();

            BlueprintManager_Paste.PrepareThreads();

            foreach (var pastedEntity in pastedEntities.Values)
            {
                pastedEntity.status = EPastedStatus.REMOVE;
            }
        }
Beispiel #2
0
        public static List <BuildPreview> Paste(Vector3 targetPos, float yaw, bool pasteInserters = true)
        {
            PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild;

            pastedEntities.Clear();
            parallelPastedEntities.Clear();
            previews.Clear();
            InserterPoses.ResetOverrides();

            Vector2 targetSpr = targetPos.ToSpherical();
            float   yawRad    = yaw * Mathf.Deg2Rad;


            for (int i = 0; i < data.copiedBuildings.Count; i++)
            {
                PasteBuilding(i, data.copiedBuildings[i], targetSpr, yaw);
            }

            for (int i = 0; i < data.copiedBelts.Count; i++)
            {
                PasteBelt(i, data.copiedBelts[i], targetSpr, yaw);
            }

            if (pasteInserters && data.copiedInserters.Count > 16)
            {
                var maxThreads        = Environment.ProcessorCount - 1;
                var runningThreads    = 0;
                var next              = -1;
                ManualResetEvent done = new ManualResetEvent(false);

                for (int i = 0; i < maxThreads; i++)
                {
                    ThreadPool.QueueUserWorkItem(_ =>
                    {
                        int item;
                        Interlocked.Increment(ref runningThreads);

                        try
                        {
                            PlayerAction_Build ab = BuildLogic.ClonePlayerAction_Build(actionBuild);
                            while ((item = Interlocked.Increment(ref next)) < data.copiedInserters.Count)
                            {
                                PasteInserter(ab, item, data.copiedInserters[item], yaw);
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.ToString());
                        }
                        finally
                        {
                            if (Interlocked.Decrement(ref runningThreads) == 0)
                            {
                                done.Set();
                            }
                        }
                    });
                }

                done.WaitOne();
            }
            else if (pasteInserters)
            {
                for (var i = 0; i < data.copiedInserters.Count; i++)
                {
                    PasteInserter(actionBuild, i, data.copiedInserters[i], yaw);
                }
            }
            // merge the inserter pastedEntities in the main dictionaries
            foreach (var item in parallelPastedEntities)
            {
                previews.Add(item.Value.buildPreview);
                pastedEntities.Add(item.Key, item.Value);
            }

            // after creating the belt previews this restore the correct connection to other belts and buildings
            foreach (BeltCopy belt in data.copiedBelts)
            {
                BuildPreview preview = pastedEntities[belt.originalId].buildPreview;

                if (belt.outputId != 0 &&
                    pastedEntities.TryGetValue(belt.outputId, out PastedEntity otherEntity) &&
                    Vector3.Distance(preview.lpos, otherEntity.buildPreview.lpos) < 10) // if the belts are too far apart ignore connection
                {
                    preview.output = otherEntity.buildPreview;
                    var otherBelt = data.copiedBelts[otherEntity.index];

                    if (otherBelt.backInputId == belt.originalId)
                    {
                        preview.outputToSlot = 1;
                    }
                    if (otherBelt.leftInputId == belt.originalId)
                    {
                        preview.outputToSlot = 2;
                    }
                    if (otherBelt.rightInputId == belt.originalId)
                    {
                        preview.outputToSlot = 3;
                    }
                }

                if (belt.connectedBuildingId != 0 && pastedEntities.TryGetValue(belt.connectedBuildingId, out PastedEntity otherBuilding))
                {
                    if (belt.connectedBuildingIsOutput)
                    {
                        preview.output       = otherBuilding.buildPreview;
                        preview.outputToSlot = belt.connectedBuildingSlot;
                    }
                    else
                    {
                        preview.input         = otherBuilding.buildPreview;
                        preview.inputFromSlot = belt.connectedBuildingSlot;
                    }
                }

                bool beltHasInput  = pastedEntities.ContainsKey(belt.backInputId) || pastedEntities.ContainsKey(belt.leftInputId) || pastedEntities.ContainsKey(belt.rightInputId);
                bool beltHasOutput = pastedEntities.ContainsKey(belt.outputId);

                if (!beltHasInput || !beltHasOutput)
                {
                    int found = actionBuild.nearcdLogic.GetBuildingsInAreaNonAlloc(preview.lpos, 0.34f, _nearObjectIds, false);
                    for (int x = 0; x < found; x++)
                    {
                        int overlappingEntityId = _nearObjectIds[x];

                        if (overlappingEntityId <= 0)
                        {
                            continue;
                        }

                        EntityData overlappingEntityData = actionBuild.factory.entityPool[overlappingEntityId];

                        if (overlappingEntityData.beltId <= 0)
                        {
                            continue;
                        }

                        BeltComponent overlappingBelt = actionBuild.factory.cargoTraffic.beltPool[overlappingEntityData.beltId];

                        bool overlappingBeltHasInput  = (overlappingBelt.backInputId + overlappingBelt.leftInputId + overlappingBelt.rightInputId) != 0;
                        bool overlappingBeltHasOutput = overlappingBelt.outputId != 0;

                        if ((beltHasOutput && !overlappingBeltHasOutput) || (beltHasInput && !overlappingBeltHasInput))
                        {
                            // found overlapping belt that can be 'replaced' to connect to existing belts
                            preview.coverObjId     = overlappingEntityId;
                            preview.ignoreCollider = true;
                            preview.willCover      = true;
                        }
                    }
                }
            }


            return(previews);
        }
Beispiel #3
0
 public static void PlayerAction_Build_ClearBuildPreviews_Prefix()
 {
     pastedEntities.Clear();
     InserterPoses.ResetOverrides();
 }