Ejemplo n.º 1
0
        public static void PlayerAction_Build_SetCopyInfo_Postfix(ref PlayerAction_Build __instance, int objectId)
        {
            if (bpMode)
            {
                EndBpMode(true);
            }
            BlueprintManager.Reset();
            if (objectId < 0)
            {
                return;
            }

            var itemProto = LDB.items.Select(__instance.factory.entityPool[objectId].protoId);

            if (itemProto.prefabDesc.insertPoses.Length > 0)
            {
                var toAdd = new List <int>()
                {
                    objectId
                };
                BlueprintManager.CopyEntities(toAdd);

                if (BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings[0].recipeId = __instance.copyRecipeId;
                    __instance.yaw = 0f;
                }
            }
        }
Ejemplo n.º 2
0
        public static void StartBpMode()
        {
            if (bpMode)
            {
                return;
            }

            bpMode = true;
            var actionBuild = GameMain.data.mainPlayer.controller.actionBuild;

            actionBuild.altitude = 0;
            actionBuild.player.SetHandItems(0, 0, 0);
            actionBuild.controller.cmd.type = ECommand.Build;
            actionBuild.controller.cmd.mode = 0;

            BuildLogic.lastPosition = Vector3.zero;
            BlueprintManager.Reset();
            if (circleGizmo == null)
            {
                circleGizmo = CircleGizmo.Create(6, Vector3.zero, 10);

                circleGizmo.fadeOutScale = circleGizmo.fadeInScale = 1.8f;
                circleGizmo.fadeOutTime  = circleGizmo.fadeInTime = 0.15f;
                circleGizmo.autoRefresh  = true;
                circleGizmo.Open();
            }
        }
Ejemplo n.º 3
0
        public static void EndBpMode(bool ignoreBlueprint = false)
        {
            if (!bpMode)
            {
                return;
            }
            bpMode = false;


            BlueprintManager.CopyEntities(bpSelection.Keys.ToList());
            foreach (var selectionGizmo in bpSelection.Values)
            {
                selectionGizmo.Close();
            }


            bpSelection.Clear();
            if (circleGizmo != null)
            {
                circleGizmo.Close();
                circleGizmo = null;
            }

            if (BlueprintManager.hasData && !ignoreBlueprint)
            {
                BlueprintManager.EnterBuildModeAfterBp();
            }

            GC.Collect();
        }
Ejemplo n.º 4
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))
            {
                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.Reset();
                }

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

                lastCmdMode = __instance.cmd.mode;
                lastCmdType = __instance.cmd.type;
            }
        }
Ejemplo n.º 5
0
 internal void OnDestroy()
 {
     // For ScriptEngine hot-reloading
     BlueprintCreator.EndBpMode(true);
     BlueprintManager.Reset();
     foreach (var tooltip in tooltips.Values)
     {
         allTips.Remove(tooltip);
     }
     harmony.UnpatchSelf();
 }
Ejemplo n.º 6
0
        public static void EndBpMode(bool ignoreBlueprint = false)
        {
            if (!bpMode)
            {
                return;
            }

            if (!ignoreBlueprint)
            {
                var ids = bpSelection.Keys.ToList();

                BlueprintManager.Copy(ids, referenceId);

                if (BlueprintManager.hasData)
                {
                    BlueprintManager.EnterBuildModeAfterBp();
                }
            }

            bpMode      = false;
            referenceId = 0;
            foreach (var selectionGizmo in bpSelection.Values)
            {
                selectionGizmo.Close();
            }

            bpSelection.Clear();
            if (areaSelectionGizmo != null)
            {
                areaSelectionGizmo.Close();
                areaSelectionGizmo = null;
            }
            if (referenceGizmo != null)
            {
                referenceGizmo.Close();
                referenceGizmo = null;
            }
            if (referenceSelectionGizmo != null)
            {
                referenceSelectionGizmo.Close();
                referenceSelectionGizmo = null;
            }



            GC.Collect();
        }
Ejemplo n.º 7
0
        public static void StartBpMode()
        {
            if (bpMode)
            {
                return;
            }

            bpMode = true;
            var actionBuild = GameMain.data.mainPlayer.controller.actionBuild;

            actionBuild.altitude = 0;
            actionBuild.player.SetHandItems(0, 0, 0);
            actionBuild.controller.cmd.type = ECommand.Build;
            actionBuild.controller.cmd.mode = 0;

            BuildLogic.lastPosition = Vector3.zero;
            BlueprintManager.PrepareNew();
        }
Ejemplo n.º 8
0
        public static bool PlayerAction_Build_DetermineBuildPreviews_Prefix(ref PlayerAction_Build __instance)
        {
            if (__instance.controller.cmd.mode != 1 ||
                __instance.player.planetData.type == EPlanetType.Gas ||
                !__instance.cursorValid ||
                __instance.groundSnappedPos == Vector3.zero ||
                (__instance.handPrefabDesc != null && __instance.handPrefabDesc.minerType != EMinerType.None)
                )
            {
                lastRunOriginal = true;
                return(true);
            }

            __instance.waitConfirm        = __instance.cursorValid;
            __instance.multiLevelCovering = false;
            if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.multiLevel)
            {
                int objectProtoId = __instance.GetObjectProtoId(__instance.castObjId);
                if (objectProtoId == __instance.handItem.ID)
                {
                    __instance.multiLevelCovering = true;
                }
            }

            if (!MultiBuild.IsMultiBuildRunning() && (__instance.multiLevelCovering || !BlueprintManager.hasData))
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            // full hijacking of DetermineBuildPreviews
            lastRunOriginal = false;
            if (VFInput._switchSplitter.onDown)
            {
                __instance.modelOffset++;
                forceRecalculation = true;
            }

            if (VFInput._rotate.onDown)
            {
                __instance.yaw    += 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }
            if (VFInput._counterRotate.onDown)
            {
                __instance.yaw    -= 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }

            __instance.yaw = Mathf.Round(__instance.yaw / 90f) * 90f;
            __instance.previewPose.position = Vector3.zero;
            __instance.previewPose.rotation = Quaternion.identity;

            if (lastPosition == __instance.groundSnappedPos && !forceRecalculation)
            {
                // no update necessary
                runUpdate = false;
                return(false);
            }
            lastPosition       = __instance.groundSnappedPos;
            forceRecalculation = false;

            List <BuildPreview> previews = new List <BuildPreview>();

            if (MultiBuild.IsMultiBuildRunning())
            {
                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.Add(new BuildingCopy()
                    {
                        itemProto  = __instance.handItem,
                        recipeId   = __instance.copyRecipeId,
                        modelIndex = __instance.handPrefabDesc.modelIndex
                    });
                }
                var building = BlueprintManager.data.copiedBuildings[0];// BlueprintManager.data.copiedBuildings.First();

                int snapPath = path;


                var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(MultiBuild.startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                var        desc        = BlueprintManager.GetPrefabDesc(building);
                Collider[] colliders   = new Collider[desc.buildColliders.Length];
                Vector3    previousPos = Vector3.zero;

                var copiesCounter = 0;
                for (int s = 0; s < snappedPointCount; s++)
                {
                    var pos = snaps[s];
                    var rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);

                    if (s > 0)
                    {
                        var sqrDistance = (previousPos - pos).sqrMagnitude;

                        // power towers
                        if (desc.isPowerNode && !desc.isAccumulator && sqrDistance < 12.25f)
                        {
                            continue;
                        }

                        // wind turbines
                        if (desc.windForcedPower && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // ray receivers
                        if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // logistic stations
                        if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                        {
                            continue;
                        }

                        // ejector
                        if (desc.isEjector && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        if (desc.hasBuildCollider)
                        {
                            var foundCollision = false;
                            for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                            {
                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                            }

                            if (foundCollision)
                            {
                                continue;
                            }
                        }
                    }

                    if (s > 0 && MultiBuild.spacingStore[MultiBuild.spacingIndex] > 0 && copiesCounter % MultiBuild.spacingPeriod == 0)
                    {
                        s += MultiBuild.spacingStore[MultiBuild.spacingIndex];

                        if (s >= snappedPointCount)
                        {
                            break;
                        }
                        pos = snaps[s];
                        rot = Maths.SphericalRotation(snaps[s], __instance.yaw);
                    }

                    copiesCounter++;
                    previousPos = pos;

                    if (desc.hasBuildCollider)
                    {
                        for (var j = 0; j < desc.buildColliders.Length; j++)
                        {
                            // create temporary collider entities for the latest 'positioned' building
                            if (colliders[j] != null)
                            {
                                ColliderPool.PutCollider(colliders[j]);
                            }

                            var colliderData = desc.buildColliders[j];
                            colliderData.pos = pos + rot * colliderData.pos;
                            colliderData.q   = rot * colliderData.q;
                            colliders[j]     = ColliderPool.TakeCollider(colliderData);
                            colliders[j].gameObject.layer = 27;
                        }
                    }

                    previews = previews.Concat(BlueprintManager.Paste(pos, __instance.yaw, MultiBuild.multiBuildInserters)).ToList();
                }

                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.RemoveAt(0);
                }
                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        ColliderPool.PutCollider(collider);
                    }
                }
            }
            else
            {
                var pasteInserters = MultiBuild.multiBuildInserters || (BlueprintManager.data.copiedBuildings.Count + BlueprintManager.data.copiedBelts.Count > 1);
                previews = BlueprintManager.Paste(__instance.groundSnappedPos, __instance.yaw, pasteInserters);
            }

            // synch previews
            var availableModelPreviews = new Dictionary <int, Queue <int> >();

            foreach (var bp in __instance.buildPreviews)
            {
                if (bp.previewIndex >= 0)
                {
                    int modelId = bp.desc.modelIndex;
                    if (!availableModelPreviews.TryGetValue(modelId, out Queue <int> availableIndexes))
                    {
                        availableIndexes = new Queue <int>();
                        availableModelPreviews.Add(modelId, availableIndexes);
                    }
                    availableIndexes.Enqueue(bp.previewIndex);
                }

                bp.Free();
            }

            __instance.buildPreviews.Clear();

            var restored = 0;

            foreach (var bp in previews)
            {
                int modelId = bp.desc.modelIndex;
                if (availableModelPreviews.TryGetValue(modelId, out Queue <int> availableIndexes) && availableIndexes.Count > 0)
                {
                    restored++;
                    bp.previewIndex = availableIndexes.Dequeue();
                }
                __instance.AddBuildPreview(bp);
            }

            var removed = 0;

            foreach (var availableIndexes in availableModelPreviews.Values)
            {
                foreach (var previewIndex in availableIndexes)
                {
                    if (__instance.previewRenderers[previewIndex] != null)
                    {
                        removed++;
                        UnityEngine.Object.Destroy(__instance.previewRenderers[previewIndex].sharedMaterial);
                        __instance.previewRenderers[previewIndex].gameObject.SetActive(false);
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 9
0
        public static BuildingCopy CopyBuilding(BlueprintData data, EntityData sourceEntity, EntityData referenceEntity)
        {
            PlanetFactory factory = GameMain.data.localPlanet.factory;

            ItemProto sourceEntityProto = LDB.items.Select(sourceEntity.protoId);

            Vector3    sourcePos = sourceEntity.pos;
            Quaternion sourceRot = sourceEntity.rot;

            Quaternion zeroRot = Maths.SphericalRotation(sourcePos, 0f);
            float      yaw     = Vector3.SignedAngle(zeroRot.Forward(), sourceRot.Forward(), zeroRot.Up());


            BuildingCopy copiedBuilding = new BuildingCopy()
            {
                originalId = sourceEntity.id,
                protoId    = sourceEntityProto.ID,
                itemProto  = sourceEntityProto,
                modelIndex = sourceEntity.modelIndex,
            };

            var prefabDesc = BlueprintManager.GetPrefabDesc(copiedBuilding);

            if (sourceEntity.assemblerId > 0)
            {
                copiedBuilding.recipeId = factory.factorySystem.assemblerPool[sourceEntity.assemblerId].recipeId;
            }
            else if (sourceEntity.labId > 0)
            {
                LabComponent labComponent = factory.factorySystem.labPool[sourceEntity.labId];
                copiedBuilding.recipeId = ((!labComponent.researchMode) ? labComponent.recipeId : -1);
            }
            else if (sourceEntity.powerGenId > 0)
            {
                PowerGeneratorComponent powerGeneratorComponent = factory.powerSystem.genPool[sourceEntity.powerGenId];
                if (powerGeneratorComponent.gamma)
                {
                    copiedBuilding.recipeId = ((powerGeneratorComponent.productId <= 0) ? 0 : 1);
                }
            }
            else if (sourceEntity.powerExcId > 0)
            {
                copiedBuilding.recipeId = Mathf.RoundToInt(factory.powerSystem.excPool[sourceEntity.powerExcId].targetState);
            }
            else if (sourceEntity.ejectorId > 0)
            {
                copiedBuilding.recipeId = factory.factorySystem.ejectorPool[sourceEntity.ejectorId].orbitId;
            }
            else if (sourceEntity.stationId > 0)
            {
                StationComponent stationComponent = factory.transport.stationPool[sourceEntity.stationId];

                copiedBuilding.stationConfig = new StationConfig()
                {
                    workEnergyPerTick     = factory.powerSystem.consumerPool[stationComponent.pcId].workEnergyPerTick,
                    tripRangeDrones       = stationComponent.tripRangeDrones,
                    tripRangeShips        = stationComponent.tripRangeShips,
                    warpEnableDist        = stationComponent.warpEnableDist,
                    warperNecessary       = stationComponent.warperNecessary,
                    includeOrbitCollector = stationComponent.includeOrbitCollector,
                    deliveryDrones        = stationComponent.deliveryDrones,
                    deliveryShips         = stationComponent.deliveryShips
                };

                for (int i = 0; i < stationComponent.slots.Length; i++)
                {
                    if (stationComponent.slots[i].storageIdx != 0)
                    {
                        copiedBuilding.slotFilters.Add(new SlotFilter()
                        {
                            slotIndex  = i,
                            storageIdx = stationComponent.slots[i].storageIdx
                        });
                    }
                }

                for (int i = 0; i < stationComponent.storage.Length; i++)
                {
                    if (stationComponent.storage[i].itemId != 0)
                    {
                        copiedBuilding.stationSettings.Add(new StationSetting()
                        {
                            index       = i,
                            itemId      = stationComponent.storage[i].itemId,
                            max         = stationComponent.storage[i].max,
                            localLogic  = stationComponent.storage[i].localLogic,
                            remoteLogic = stationComponent.storage[i].remoteLogic
                        });
                    }
                }
            }
            else if (sourceEntity.splitterId > 0)
            {
                var splitterComponent = factory.cargoTraffic.splitterPool[sourceEntity.splitterId];
                copiedBuilding.splitterSettings = new SplitterSettings()
                {
                    inPriority  = splitterComponent.inPriority,
                    outPriority = splitterComponent.outPriority,
                    outFilter   = splitterComponent.outFilter
                };

                var slots = new List <int>(4)
                {
                    splitterComponent.beltA, splitterComponent.beltB, splitterComponent.beltC, splitterComponent.beltD
                };
                if (copiedBuilding.splitterSettings.inPriority)
                {
                    copiedBuilding.splitterSettings.inPrioritySlot = slots.IndexOf(splitterComponent.input0);
                }
                if (copiedBuilding.splitterSettings.outPriority)
                {
                    copiedBuilding.splitterSettings.outPrioritySlot = slots.IndexOf(splitterComponent.output0);
                }
                // TODO: find a way to restore splitter settings
                // SplitterComponent splitterComponent = factory.cargoTraffic.splitterPool[sourceEntity.splitterId];
            }
            else if (sourceEntity.storageId > 0)
            {
                copiedBuilding.recipeId = factory.factoryStorage.storagePool[sourceEntity.storageId].bans;
            }

            Vector2 sourceSprPos = sourcePos.ToSpherical();

            if (sourceEntity.id == referenceEntity.id)
            {
                data.referencePos = sourceSprPos;
                copiedBuilding.cursorRelativeYaw = yaw;
            }
            else
            {
                copiedBuilding.originalSegmentCount = sourceSprPos.GetSegmentsCount();
                copiedBuilding.cursorRelativePos    = (sourceSprPos - data.referencePos).Clamp();
                copiedBuilding.cursorRelativeYaw    = yaw;
            }

            data.copiedBuildings.Add(copiedBuilding);

            for (int i = 0; i < sourceEntityProto.prefabDesc.insertPoses.Length; i++)
            {
                factory.ReadObjectConn(sourceEntity.id, i, out bool _, out int otherObjId, out int _);

                if (otherObjId > 0)
                {
                    EntityData inserterEntity = factory.entityPool[otherObjId];
                    CopyInserter(data, inserterEntity, sourceEntity);
                }
            }

            if (sourceEntityProto.prefabDesc.multiLevel)
            {
                copiedBuilding.altitude = Mathf.RoundToInt((sourceEntity.pos.magnitude - GameMain.localPlanet.realRadius - 0.2f) / prefabDesc.lapJoint.magnitude);

                if (copiedBuilding.altitude > 0)
                {
                    copiedBuilding.connectedBuildingId = referenceEntity.id;
                }

                factory.ReadObjectConn(sourceEntity.id, 15, out bool _, out int otherObjId, out int _);

                if (otherObjId > 0)
                {
                    EntityData stackedEntity = factory.entityPool[otherObjId];
                    CopyBuilding(data, stackedEntity, sourceEntity);
                }
            }


            return(copiedBuilding);
        }
Ejemplo n.º 10
0
        internal void Awake()
        {
            harmony             = new Harmony("com.brokenmass.plugin.DSP.MultiBuild" + CHANNEL);
            itemSpecificSpacing = Config.Bind <bool>("General", "itemSpecificSpacing", true, "If this option is set to true, the mod will remember the last spacing used for a specific building. Otherwise the spacing will be the same for all entities.");
            spacingStore[0]     = 0;

            //StartCoroutine(CheckForUpdates());

            try
            {
                foreach (var pluginInfo in BepInEx.Bootstrap.Chainloader.PluginInfos)
                {
                    if (BLACKLISTED_MODS.Contains(pluginInfo.Value.Metadata.GUID))
                    {
                        incompatiblePlugins.Add(" - " + pluginInfo.Value.Metadata.Name);
                    }
                }

                if (incompatiblePlugins.Count > 0)
                {
                    isValidInstallation = false;
                    harmony.PatchAll(typeof(IncompatibilityNotice));
                }


                if (isValidInstallation)
                {
                    harmony.PatchAll(typeof(MultiBuild));
                    harmony.PatchAll(typeof(BlueprintManager));
                    harmony.PatchAll(typeof(BuildLogic));
                    harmony.PatchAll(typeof(BlueprintCreator));
                    harmony.PatchAll(typeof(InserterPoses));

                    UIBlueprintGroup.onCreate  = () => BlueprintCreator.StartBpMode();
                    UIBlueprintGroup.onRestore = () =>
                    {
                        if (BlueprintCreator.bpMode)
                        {
                            BlueprintCreator.EndBpMode(true);
                        }
                        BlueprintManager.Restore();
                    };
                    UIBlueprintGroup.onImport = () =>
                    {
                        if (BlueprintCreator.bpMode)
                        {
                            BlueprintCreator.EndBpMode(true);
                        }
                        HashSet <int> incompatibleIds;
                        var           data = BlueprintData.Import(GUIUtility.systemCopyBuffer, out incompatibleIds);
                        if (data != null)
                        {
                            BlueprintManager.Restore(data);
                            UIRealtimeTip.Popup("Blueprint successfully imported from your clipboard", false);
                        }
                        else
                        {
                            string message = "Error while importing data from your clipboard";
                            if (incompatibleIds.Count > 0)
                            {
                                message += $" - Found {incompatibleIds.Count} incompatible entities.\nIds: [{incompatibleIds.Join(null, ", ")}]";
                            }
                            UIRealtimeTip.Popup(message, true);
                        }
                    };
                    UIBlueprintGroup.onExport = () =>
                    {
                        if (BlueprintCreator.bpMode)
                        {
                            BlueprintCreator.EndBpMode();
                        }
                        if (BlueprintManager.hasData)
                        {
                            GUIUtility.systemCopyBuffer = BlueprintManager.data.Export();
                            UIRealtimeTip.Popup("Blueprint successfully exported to your clipboard", false);
                        }
                        else
                        {
                            UIRealtimeTip.Popup("No blueprint data to export", true);
                        }
                    };
                }
            }
            catch (Exception e)
            {
                isValidInstallation = false;
                Console.WriteLine(e.ToString());
            }
        }
Ejemplo n.º 11
0
        public static bool PlayerAction_Build_DetermineBuildPreviews_Prefix(ref PlayerAction_Build __instance)
        {
            if (__instance.controller.cmd.mode != 1 ||
                __instance.player.planetData.type == EPlanetType.Gas ||
                !__instance.cursorValid ||
                __instance.groundSnappedPos == Vector3.zero ||
                (__instance.handPrefabDesc != null && __instance.handPrefabDesc.minerType != EMinerType.None)
                )
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            __instance.waitConfirm        = __instance.cursorValid;
            __instance.multiLevelCovering = false;
            if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.multiLevel)
            {
                int objectProtoId = __instance.GetObjectProtoId(__instance.castObjId);
                if (objectProtoId == __instance.handItem.ID)
                {
                    __instance.multiLevelCovering = true;
                }
            }

            if (!IsMultiBuildRunning() && (__instance.multiLevelCovering || !BlueprintManager.hasData))
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            // full hijacking of DetermineBuildPreviews

            if (VFInput._switchSplitter.onDown)
            {
                __instance.modelOffset++;
                forceRecalculation = true;
            }

            if (VFInput._rotate.onDown)
            {
                __instance.yaw    += 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }
            if (VFInput._counterRotate.onDown)
            {
                __instance.yaw    -= 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }

            __instance.yaw = Mathf.Round(__instance.yaw / 90f) * 90f;
            __instance.previewPose.position = Vector3.zero;
            __instance.previewPose.rotation = Quaternion.identity;

            if (lastPosition == __instance.groundSnappedPos && !forceRecalculation)
            {
                // no update necessary
                runUpdate       = false;
                lastRunOriginal = false;
                return(false);
            }
            lastPosition       = __instance.groundSnappedPos;
            forceRecalculation = false;

            if (lastRunOriginal)
            {
                __instance.ClearBuildPreviews();
            }
            BlueprintManager.PreparePaste();
            if (IsMultiBuildRunning())
            {
                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.Add(new BuildingCopy()
                    {
                        originalId = 0,
                        itemProto  = __instance.handItem,
                        recipeId   = __instance.copyRecipeId,
                        modelIndex = __instance.handPrefabDesc.modelIndex
                    });
                }
                var building = BlueprintManager.data.copiedBuildings[0];// BlueprintManager.data.copiedBuildings.First();

                int snapPath = path;

                var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                var        desc            = BlueprintManager.GetPrefabDesc(building);
                var        pastedPositions = new List <Vector3>();
                Collider[] colliders       = new Collider[desc.buildColliders.Length];

                var copiesCounter = 0;
                for (int s = 0; s < snappedPointCount; s++)
                {
                    var pos = snaps[s];
                    var rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);

                    if (s > 0)
                    {
                        var sqrDistance = (pastedPositions.Last() - pos).sqrMagnitude;

                        // power towers
                        if (desc.isPowerNode && !desc.isAccumulator && sqrDistance < 12.25f)
                        {
                            continue;
                        }

                        // wind turbines
                        if (desc.windForcedPower && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // ray receivers
                        if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // logistic stations
                        if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                        {
                            continue;
                        }

                        // ejector
                        if (desc.isEjector && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        if (desc.hasBuildCollider)
                        {
                            var foundCollision = false;
                            for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                            {
                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                            }

                            if (foundCollision)
                            {
                                continue;
                            }
                        }
                    }


                    if (s > 0 && spacingStore[spacingIndex] > 0 && copiesCounter % spacingPeriod == 0)
                    {
                        s += spacingStore[spacingIndex];
                        if (s >= snappedPointCount)
                        {
                            break;
                        }
                        pos = snaps[s];
                        rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);
                    }

                    BlueprintManager.Paste(pos, __instance.yaw, false, pastedPositions.Count);
                    pastedPositions.Add(pos);

                    if (desc.hasBuildCollider)
                    {
                        for (var j = 0; j < desc.buildColliders.Length; j++)
                        {
                            // create temporary collider entities for the latest 'positioned' building
                            if (colliders[j] != null)
                            {
                                ColliderPool.PutCollider(colliders[j]);
                            }

                            var colliderData = desc.buildColliders[j];
                            colliderData.pos = pos + rot * colliderData.pos;
                            colliderData.q   = rot * colliderData.q;
                            colliders[j]     = ColliderPool.TakeCollider(colliderData);
                            colliders[j].gameObject.layer = 27;
                        }
                    }
                }
                if (multiBuildInserters)
                {
                    for (var i = 0; i < pastedPositions.Count; i++)
                    {
                        BlueprintManager.PasteInsertersOnly(pastedPositions[i], __instance.yaw, i, true);
                    }
                }

                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.RemoveAt(0);
                }
                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        ColliderPool.PutCollider(collider);
                    }
                }
            }
            else
            {
                var pasteInserters = multiBuildInserters || (BlueprintManager.data.copiedBuildings.Count + BlueprintManager.data.copiedBelts.Count > 1);
                BlueprintManager.Paste(__instance.groundSnappedPos, __instance.yaw, pasteInserters);
            }
            BlueprintManager.AfterPaste();

            lastRunOriginal = false;
            return(false);
        }
Ejemplo n.º 12
0
        public static PastedEntity ConcurrentPasteBuilding(int threadIndex, BuildingCopy building, Vector2 targetSpr, float yaw, int pasteIndex)
        {
            var actionBuild = _abs[threadIndex];
            int pasteId     = PASTE_INDEX_MULTIPLIER * pasteIndex + building.originalId;

            if (!BlueprintManager.pastedEntities.TryGetValue(pasteId, out PastedEntity pastedEntity))
            {
                PrefabDesc   desc = BlueprintManager.GetPrefabDesc(building);
                BuildPreview bp   = BuildPreview.CreateSingle(building.itemProto, desc, true);
                bp.ResetInfos();
                bp.desc     = desc;
                bp.item     = building.itemProto;
                bp.recipeId = building.recipeId;

                pastedEntity = new PastedEntity()
                {
                    pasteIndex     = pasteIndex,
                    pasteId        = pasteId,
                    status         = EPastedStatus.NEW,
                    type           = EPastedType.BUILDING,
                    sourceBuilding = building,
                    buildPreview   = bp,
                };

                BlueprintManager.pastedEntities.TryAdd(pasteId, pastedEntity);

                lock (actionBuild.buildPreviews)
                {
                    actionBuild.buildPreviews.Add(bp);
                }
            }
            else
            {
                pastedEntity.status = EPastedStatus.UPDATE;
            }

            Vector2 newRelative = building.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, building.originalSegmentCount);
            Vector2 sprPos      = newRelative + targetSpr;

            int newSegmentCount = Util.GetSegmentsCount(sprPos);

            float sizeDeviation = building.originalSegmentCount / (float)newSegmentCount;

            sprPos = new Vector2(newRelative.x, newRelative.y * sizeDeviation) + targetSpr;

            Vector3    absoluteBuildingPos = sprPos.SnapToGrid();
            Quaternion absoluteBuildingRot = Maths.SphericalRotation(absoluteBuildingPos, yaw + building.cursorRelativeYaw);

            absoluteBuildingPos += absoluteBuildingRot * (building.altitude * pastedEntity.buildPreview.desc.lapJoint);

            Pose pose = new Pose(absoluteBuildingPos, absoluteBuildingRot);

            pastedEntity.objId = InserterPoses.AddOverride(pose, building.itemProto);
            pastedEntity.pose  = pose;

            pastedEntity.buildPreview.lpos      = absoluteBuildingPos;
            pastedEntity.buildPreview.lrot      = absoluteBuildingRot;
            pastedEntity.buildPreview.condition = EBuildCondition.Ok;

            pastedEntity.connectedEntities.Clear();

            return(pastedEntity);
        }