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; } } }
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(); } }
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(); }
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; } }
internal void OnDestroy() { // For ScriptEngine hot-reloading BlueprintCreator.EndBpMode(true); BlueprintManager.Reset(); foreach (var tooltip in tooltips.Values) { allTips.Remove(tooltip); } harmony.UnpatchSelf(); }
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(); }
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(); }
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); }
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); }
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()); } }
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); }
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); }