Пример #1
0
        public static void UpdateCommandState_Prefix(PlayerController __instance)
        {
            if (__instance.cmd.type != ECommand.None && __instance.cmd.type != ECommand.Follow &&
                (__instance.cmd.mode != lastCmdMode || __instance.cmd.type != lastCmdType))
            {
                if (__instance.cmd.type != ECommand.Build || __instance.cmd.mode != 1)
                {
                    BuildLogic.ResetMultiBuild();
                }
                if (__instance.cmd.type != ECommand.Build || __instance.cmd.mode != 0)
                {
                    BlueprintCreator.EndBpMode();
                }

                // the preivous command might force us to stau in BuildMode (Even though we were leaving)
                if (__instance.cmd.type == ECommand.Build && lastCmdMode == 1 && __instance.cmd.mode != 1)
                {
                    BlueprintManager.PrepareNew();
                }

                if (__instance.cmd.type != ECommand.Build)
                {
                    BlueprintManager.PrepareNew();
                }

                lastCmdMode = __instance.cmd.mode;
                lastCmdType = __instance.cmd.type;
            }
        }
Пример #2
0
        internal void Update()
        {
            if (!isValidInstallation)
            {
                return;
            }

            BuildLogic.OnUpdate();
            BlueprintCreator.OnUpdate();
        }
Пример #3
0
        public static void UIGeneralTips__OnUpdate_Postfix(ref Text ___modeText)
        {
            if (BuildLogic.IsMultiBuildAvailable() && BuildLogic.multiBuildEnabled)
            {
                ___modeText.text += $"\nMultiBuild [{(BuildLogic.startPos == Vector3.zero ? "START" : "END")}]";

                if (BuildLogic.spacingStore[BuildLogic.spacingIndex] > 0)
                {
                    ___modeText.text += $" - Spacing {BuildLogic.spacingStore[BuildLogic.spacingIndex]}";
                    if (BuildLogic.spacingPeriod > 1)
                    {
                        ___modeText.text += $" every {BuildLogic.spacingPeriod} copies";
                    }
                }
            }

            if (BlueprintCreator.bpMode)
            {
                ___modeText.text = "Blueprint Mode";
            }
        }
Пример #4
0
        public static void PasteInsertersOnly(BlueprintData data, Vector3 targetPos, float yaw, int pasteIndex = 0, bool connectToPasted = false)
        {
            PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild;
            var backupMechaBuildArea       = actionBuild.player.mecha.buildArea;

            actionBuild.player.mecha.buildArea = 10000f;

            Vector2 targetSpr = targetPos.ToSpherical();

            ConcurrentQueue <InserterCopy> inserterQueue = new ConcurrentQueue <InserterCopy>(data.copiedInserters);

            Util.Parallelize((threadIndex) =>
            {
                while (inserterQueue.TryDequeue(out InserterCopy inserter))
                {
                    var pastedEntity = ConcurrentPasteInserter(threadIndex, inserter, yaw, pasteIndex, connectToPasted);
                    BuildLogic.CheckBuildConditionsWorker(_abs[threadIndex], pastedEntity.buildPreview);
                }
            });

            actionBuild.player.mecha.buildArea = backupMechaBuildArea;
        }
Пример #5
0
        public static void UIKeyTips_UpdateTipDesiredState_Prefix(ref UIKeyTips __instance, ref List <UIKeyTipNode> ___allTips)
        {
            if (tooltips.Count == 0)
            {
                allTips = ___allTips;
                tooltips.Add("toggle-build", __instance.RegisterTip("L-ALT", "Toggle multiBuild mode"));
                tooltips.Add("toggle-inserters", __instance.RegisterTip("TAB", "Toggle inserters copy"));
                tooltips.Add("increase-spacing", __instance.RegisterTip("+", "Increase space between copies"));
                tooltips.Add("decrease-spacing", __instance.RegisterTip("-", "Decrease space between copies"));
                tooltips.Add("increase-period", __instance.RegisterTip("CTRL", "+", "Increase spacing period"));
                tooltips.Add("decrease-period", __instance.RegisterTip("CTRL", "-", "Decrease spacing period"));
                tooltips.Add("zero-spacing", __instance.RegisterTip("0", "Reset space between copies"));
                tooltips.Add("rotate-path", __instance.RegisterTip("Z", "Rotate build path"));

                tooltips.Add("increase-radius", __instance.RegisterTip("+", "Increase selection area"));
                tooltips.Add("decrease-radius", __instance.RegisterTip("-", "Decrease selection area"));
                tooltips.Add("bp-select", __instance.RegisterTip(0, "Add building to blueprint"));
                tooltips.Add("bp-deselect", __instance.RegisterTip("CTRL", 0, "Remove building from blueprint"));
                tooltips.Add("bp-reference", __instance.RegisterTip("ALT", 0, "Select reference building"));
            }
            tooltips["toggle-build"].desired = tooltips["toggle-inserters"].desired = BuildLogic.IsMultiBuildAvailable();

            tooltips["rotate-path"].desired                         =
                tooltips["zero-spacing"].desired                    =
                    tooltips["decrease-spacing"].desired            =
                        tooltips["increase-spacing"].desired        =
                            tooltips["decrease-period"].desired     =
                                tooltips["increase-period"].desired =
                                    BuildLogic.IsMultiBuildRunning();

            tooltips["increase-radius"].desired              =
                tooltips["decrease-radius"].desired          =
                    tooltips["bp-select"].desired            =
                        tooltips["bp-deselect"].desired      =
                            tooltips["bp-reference"].desired =
                                BlueprintCreator.bpMode;
        }
Пример #6
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);
        }
Пример #7
0
        public static void Paste(BlueprintData data, Vector3 targetPos, float yaw, bool pasteInserters = true, int pasteIndex = 0)
        {
            PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild;
            var backupMechaBuildArea       = actionBuild.player.mecha.buildArea;

            actionBuild.player.mecha.buildArea = 10000f;

            Vector2 targetSpr = targetPos.ToSpherical();

            ConcurrentQueue <BuildingCopy> buildingsQueue = new ConcurrentQueue <BuildingCopy>(data.copiedBuildings);

            Util.Parallelize((int threadIndex) =>
            {
                while (buildingsQueue.TryDequeue(out BuildingCopy building))
                {
                    var pastedEntity = ConcurrentPasteBuilding(threadIndex, building, targetSpr, yaw, pasteIndex);

                    lock (actionBuild.nearcdLogic)
                    {
                        actionBuild.nearcdLogic.ActiveEntityBuildCollidersInArea(pastedEntity.pose.position, 5f);
                    }
                }
            });

            buildingsQueue = new ConcurrentQueue <BuildingCopy>(data.copiedBuildings);
            Util.Parallelize((int threadIndex) =>
            {
                while (buildingsQueue.TryDequeue(out BuildingCopy building))
                {
                    int pasteId      = PASTE_INDEX_MULTIPLIER * pasteIndex + building.originalId;
                    var pastedEntity = BlueprintManager.pastedEntities[pasteId];

                    ConcurrentConnectBuildings(threadIndex, pastedEntity);
                    BuildLogic.CheckBuildConditionsWorker(_abs[threadIndex], pastedEntity.buildPreview);
                }
            });

            ConcurrentQueue <BeltCopy> beltsQueue = new ConcurrentQueue <BeltCopy>(data.copiedBelts);

            Util.Parallelize((int threadIndex) =>
            {
                while (beltsQueue.TryDequeue(out BeltCopy belt))
                {
                    var pastedEntity = ConcurrentPasteBelt(threadIndex, belt, targetSpr, yaw, pasteIndex);
                }
            });

            // after creating the belt previews this restore the correct connection to other belts and buildings
            beltsQueue = new ConcurrentQueue <BeltCopy>(data.copiedBelts);
            Util.Parallelize((int threadIndex) =>
            {
                while (beltsQueue.TryDequeue(out BeltCopy belt))
                {
                    int pasteId      = PASTE_INDEX_MULTIPLIER * pasteIndex + belt.originalId;
                    var pastedEntity = BlueprintManager.pastedEntities[pasteId];

                    ConcurrentConnectBelt(threadIndex, pastedEntity);
                    BuildLogic.CheckBuildConditionsWorker(_abs[threadIndex], pastedEntity.buildPreview);
                }
            });

            if (pasteInserters)
            {
                ConcurrentQueue <InserterCopy> inserterQueue = new ConcurrentQueue <InserterCopy>(data.copiedInserters);
                Util.Parallelize((threadIndex) =>
                {
                    while (inserterQueue.TryDequeue(out InserterCopy inserter))
                    {
                        var pastedEntity = ConcurrentPasteInserter(threadIndex, inserter, yaw, pasteIndex);
                        BuildLogic.CheckBuildConditionsWorker(_abs[threadIndex], pastedEntity.buildPreview);
                    }
                });
            }

            actionBuild.player.mecha.buildArea = backupMechaBuildArea;
        }