public static void PreparePaste() { InserterPoses.ResetOverrides(); BlueprintManager_Paste.PrepareThreads(); foreach (var pastedEntity in pastedEntities.Values) { pastedEntity.status = EPastedStatus.REMOVE; } }
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); }
public static void PlayerAction_Build_ClearBuildPreviews_Prefix() { pastedEntities.Clear(); InserterPoses.ResetOverrides(); }