public static PastedEntity ConcurrentPasteBelt(int threadIndex, BeltCopy belt, Vector2 targetSpr, float yaw, int pasteIndex) { var actionBuild = _abs[threadIndex]; int pasteId = PASTE_INDEX_MULTIPLIER * pasteIndex + belt.originalId; if (!BlueprintManager.pastedEntities.TryGetValue(pasteId, out PastedEntity pastedEntity)) { BuildPreview bp = BuildPreview.CreateSingle(belt.itemProto, belt.itemProto.prefabDesc, false); pastedEntity = new PastedEntity() { pasteIndex = pasteIndex, pasteId = pasteId, status = EPastedStatus.NEW, type = EPastedType.BELT, sourceBelt = belt, buildPreview = bp, }; BlueprintManager.pastedEntities.TryAdd(pasteId, pastedEntity); lock (actionBuild.buildPreviews) { actionBuild.buildPreviews.Add(bp); } } else { pastedEntity.status = EPastedStatus.UPDATE; } Vector2 newRelative = belt.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, belt.originalSegmentCount); Vector2 sprPos = newRelative + targetSpr; int newSegmentCount = Util.GetSegmentsCount(sprPos); float sizeDeviation = belt.originalSegmentCount / (float)newSegmentCount; sprPos = new Vector2(newRelative.x, newRelative.y * sizeDeviation) + targetSpr; Vector3 absoluteBeltPos = sprPos.SnapToGrid(belt.altitude * 1.3333333f / 2); // belts have always 0 yaw Quaternion absoluteBeltRot = Maths.SphericalRotation(absoluteBeltPos, 0f); Pose pose = new Pose(absoluteBeltPos, absoluteBeltRot); pastedEntity.objId = InserterPoses.AddOverride(pose, belt.itemProto); pastedEntity.pose = pose; pastedEntity.buildPreview.lpos = absoluteBeltPos; pastedEntity.buildPreview.lrot = absoluteBeltRot; pastedEntity.buildPreview.condition = EBuildCondition.Ok; return(pastedEntity); }
public static void PreparePaste() { InserterPoses.ResetOverrides(); BlueprintManager_Paste.PrepareThreads(); foreach (var pastedEntity in pastedEntities.Values) { pastedEntity.status = EPastedStatus.REMOVE; } }
public static void PasteInserter(PlayerAction_Build actionBuild, int index, InserterCopy inserter, float yaw) { InserterPosition positionData = InserterPoses.GetPositions(actionBuild, inserter, yaw * Mathf.Deg2Rad); BuildPreview bp = BuildPreview.CreateSingle(LDB.items.Select(inserter.itemProto.ID), inserter.itemProto.prefabDesc, true); bp.lpos = positionData.absoluteInserterPos; bp.lpos2 = positionData.absoluteInserterPos2; bp.lrot = positionData.absoluteInserterRot; bp.lrot2 = positionData.absoluteInserterRot2; bp.inputToSlot = 1; bp.outputFromSlot = 0; bp.inputOffset = positionData.pickOffset; bp.outputOffset = positionData.insertOffset; bp.outputToSlot = positionData.endSlot; bp.inputFromSlot = positionData.startSlot; bp.condition = positionData.condition; bp.filterId = inserter.filterId; if (pastedEntities.TryGetValue(positionData.inputOriginalId, out PastedEntity inputEntity)) { bp.input = inputEntity.buildPreview; } else { bp.inputObjId = positionData.inputObjId; } if (pastedEntities.TryGetValue(positionData.outputOriginalId, out PastedEntity outputEntity)) { bp.output = outputEntity.buildPreview; } else { bp.outputObjId = positionData.outputObjId; } lock (parallelPastedEntities) { parallelPastedEntities.Add(inserter.originalId, new PastedEntity() { type = EPastedType.INSERTER, index = index, buildPreview = bp, }); } }
public static void PasteBelt(int index, BeltCopy belt, Vector2 targetSpr, float yaw) { Vector2 newRelative = belt.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, belt.originalSegmentCount); Vector2 sprPos = newRelative + targetSpr; float rawLatitudeIndex = (sprPos.x - Mathf.PI / 2) / 6.2831855f * 200; int latitudeIndex = Mathf.FloorToInt(Mathf.Max(0f, Mathf.Abs(rawLatitudeIndex) - 0.1f)); int newSegmentCount = PlanetGrid.DetermineLongitudeSegmentCount(latitudeIndex, 200); float sizeDeviation = belt.originalSegmentCount / (float)newSegmentCount; sprPos = new Vector2(newRelative.x, newRelative.y * sizeDeviation) + targetSpr; Vector3 absoluteBeltPos = sprPos.SnapToGrid(belt.altitude * 1.3333333f / 2); // belts have always 0 yaw Quaternion absoluteBeltRot = Maths.SphericalRotation(absoluteBeltPos, 0f); BuildPreview bp = BuildPreview.CreateSingle(belt.itemProto, belt.itemProto.prefabDesc, false); bp.lpos = absoluteBeltPos; bp.lrot = absoluteBeltRot; bp.outputToSlot = -1; bp.outputFromSlot = 0; bp.inputFromSlot = -1; bp.inputToSlot = 1; bp.outputOffset = 0; bp.inputOffset = 0; Pose pose = new Pose(absoluteBeltPos, absoluteBeltRot); int objId = InserterPoses.AddOverride(pose, belt.itemProto); pastedEntities.Add(belt.originalId, new PastedEntity() { type = EPastedType.BELT, index = index, pose = pose, objId = objId, buildPreview = bp, }); previews.Add(bp); }
public static void PasteBuilding(int index, BuildingCopy building, Vector2 targetSpr, float yaw) { Vector2 newRelative = building.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, building.originalSegmentCount); Vector2 sprPos = newRelative + targetSpr; float rawLatitudeIndex = (sprPos.x - Mathf.PI / 2) / 6.2831855f * 200; int latitudeIndex = Mathf.FloorToInt(Mathf.Max(0f, Mathf.Abs(rawLatitudeIndex) - 0.1f)); int newSegmentCount = PlanetGrid.DetermineLongitudeSegmentCount(latitudeIndex, 200); 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); PrefabDesc desc = GetPrefabDesc(building); BuildPreview bp = BuildPreview.CreateSingle(building.itemProto, desc, true); bp.ResetInfos(); bp.desc = desc; bp.item = building.itemProto; bp.recipeId = building.recipeId; bp.lpos = absoluteBuildingPos; bp.lrot = absoluteBuildingRot; Pose pose = new Pose(absoluteBuildingPos, absoluteBuildingRot); int objId = InserterPoses.AddOverride(pose, building.itemProto); pastedEntities.Add(building.originalId, new PastedEntity() { type = EPastedType.BUILDING, index = index, sourceBuilding = building, pose = pose, objId = objId, buildPreview = bp }); ActivateColliders(absoluteBuildingPos); previews.Add(bp); }
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 InserterCopy CopyInserter(EntityData sourceEntity, EntityData referenceEntity) { PlanetFactory factory = GameMain.data.localPlanet.factory; PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild; if (sourceEntity.inserterId == 0) { return(null); } InserterComponent inserter = factory.factorySystem.inserterPool[sourceEntity.inserterId]; if (data.copiedInserters.FindIndex(x => x.originalId == inserter.entityId) != -1) { return(null); } int pickTarget = inserter.pickTarget; int insertTarget = inserter.insertTarget; ItemProto itemProto = LDB.items.Select(sourceEntity.protoId); bool incoming = insertTarget == referenceEntity.id; int otherId = incoming ? pickTarget : insertTarget; Vector2 referenceSprPos = referenceEntity.pos.ToSpherical(); Vector2 sourceSprPos = sourceEntity.pos.ToSpherical(); Vector2 sourceSprPos2 = inserter.pos2.ToSpherical(); // The belt or other building this inserter is attached to Vector2 otherSprPos; ItemProto otherProto; if (otherId > 0) { otherProto = LDB.items.Select(factory.entityPool[otherId].protoId); otherSprPos = factory.entityPool[otherId].pos.ToSpherical(); } else if (otherId < 0) { otherProto = LDB.items.Select(factory.prebuildPool[-otherId].protoId); otherSprPos = factory.prebuildPool[-otherId].pos.ToSpherical(); } else { otherSprPos = sourceSprPos2; otherProto = null; } bool otherIsBelt = otherProto == null || otherProto.prefabDesc.isBelt; // Cache info for this inserter InserterCopy copiedInserter = new InserterCopy { itemProto = itemProto, protoId = itemProto.ID, originalId = inserter.entityId, pickTarget = pickTarget, insertTarget = insertTarget, referenceBuildingId = referenceEntity.id, incoming = incoming, // rotations + deltas relative to the source building's rotation rot = Quaternion.Inverse(referenceEntity.rot) * sourceEntity.rot, rot2 = Quaternion.Inverse(referenceEntity.rot) * inserter.rot2, posDelta = sourceSprPos - referenceSprPos, // Delta from copied building to inserter pos pos2Delta = sourceSprPos2 - referenceSprPos, // Delta from copied building to inserter pos2 posDeltaCount = sourceSprPos.GetSegmentsCount(), pos2DeltaCount = sourceSprPos2.GetSegmentsCount(), otherPosDelta = otherSprPos - referenceSprPos, otherPosDeltaCount = otherSprPos.GetSegmentsCount(), // not important? pickOffset = inserter.pickOffset, insertOffset = inserter.insertOffset, filterId = inserter.filter, startSlot = -1, endSlot = -1, otherIsBelt = otherIsBelt }; InserterPoses.CalculatePose(actionBuild, pickTarget, insertTarget); if (actionBuild.posePairs.Count > 0) { float minDistance = 1000f; for (int j = 0; j < actionBuild.posePairs.Count; ++j) { var posePair = actionBuild.posePairs[j]; float startDistance = Vector3.Distance(posePair.startPose.position, sourceEntity.pos); float endDistance = Vector3.Distance(posePair.endPose.position, inserter.pos2); float poseDistance = startDistance + endDistance; if (poseDistance < minDistance) { minDistance = poseDistance; copiedInserter.startSlot = posePair.startSlot; copiedInserter.endSlot = posePair.endSlot; copiedInserter.pickOffset = (short)posePair.startOffset; copiedInserter.insertOffset = (short)posePair.endOffset; } } } /* factory.ReadObjectConn(sourceEntity.id, 1, out bool isOutput, out int connectedId, out int connectedSlot); * * if (connectedId != 0) * { * copiedInserter.startSlot = connectedSlot; * } * * * factory.ReadObjectConn(sourceEntity.id, 0, out _, out connectedId, out connectedSlot); * if (connectedId != 0) * { * copiedInserter.endSlot = connectedSlot; * } */ data.copiedInserters.Add(copiedInserter); return(copiedInserter); }
public static InserterPosition GetPositions(PlayerAction_Build actionBuild, InserterCopy copiedInserter, float yawRad, int pasteIndex, bool connectToPasted) { var pastedEntities = BlueprintManager.pastedEntities; var player = actionBuild.player; var pastedReferenceEntityId = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.referenceBuildingId; var pastedReferenceEntity = pastedEntities[pastedReferenceEntityId]; var pastedReferenceEntityBuildPreview = pastedReferenceEntity.buildPreview; Quaternion absoluteBuildingRot = pastedReferenceEntity.pose.rotation; Vector3 absoluteBuildingPos = pastedReferenceEntity.pose.position; Vector2 absoluteBuildingPosSpr = absoluteBuildingPos.ToSpherical(); var posDelta = copiedInserter.posDelta.Rotate(yawRad, copiedInserter.posDeltaCount); Vector3 absoluteInserterPos = absoluteBuildingPosSpr .ApplyDelta(posDelta, copiedInserter.posDeltaCount) .ToCartesian(GameMain.localPlanet.realRadius + 0.2f); var pos2Delta = copiedInserter.pos2Delta.Rotate(yawRad, copiedInserter.pos2DeltaCount); Vector3 absoluteInserterPos2 = absoluteBuildingPosSpr .ApplyDelta(pos2Delta, copiedInserter.pos2DeltaCount) .ToCartesian(GameMain.localPlanet.realRadius + 0.2f); if (pastedReferenceEntity.sourceBuilding == null) { absoluteBuildingRot = Maths.SphericalRotation(absoluteBuildingPos, yawRad * Mathf.Rad2Deg); } Quaternion absoluteInserterRot = absoluteBuildingRot * copiedInserter.rot; Quaternion absoluteInserterRot2 = absoluteBuildingRot * copiedInserter.rot2; int startSlot = copiedInserter.startSlot; int endSlot = copiedInserter.endSlot; short pickOffset = copiedInserter.pickOffset; short insertOffset = copiedInserter.insertOffset; var referenceObjId = pastedReferenceEntity.objId; var otherPastedId = 0; var otherEntityId = 0; var otherObjId = 0; var pastedPickTargetId = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.pickTarget; var pastedInsertTargetId = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.insertTarget; if (pastedEntities.ContainsKey(pastedPickTargetId) && pastedEntities.ContainsKey(pastedInsertTargetId)) { // cool we copied both source and target of the inserters otherPastedId = pastedPickTargetId == pastedReferenceEntityId ? pastedInsertTargetId : pastedPickTargetId; otherObjId = pastedEntities[otherPastedId].objId; } else { // Find the other entity at the target location var nearcdLogic = actionBuild.nearcdLogic; var factory = actionBuild.factory; // Find the desired belt/building position // As delta doesn't work over distance, re-trace the Grid Snapped steps from the original // to find the target belt/building for this inserters other connection var otherPosDelta = copiedInserter.otherPosDelta.Rotate(yawRad, copiedInserter.otherPosDeltaCount); Vector3 testPos = absoluteBuildingPosSpr .ApplyDelta(otherPosDelta, copiedInserter.otherPosDeltaCount) .SnapToGrid(); if (connectToPasted) { var compatibleType = copiedInserter.otherIsBelt ? EPastedType.BELT : EPastedType.BUILDING; foreach (var pastedEntity in BlueprintManager.pastedEntities.Values) { // find the first compatible entity that will not been removed, that has in the same/previous/next pasteIndex and that is near enough if (pastedEntity.type == compatibleType && pastedEntity.status != EPastedStatus.REMOVE && pastedEntity.pasteId != pastedReferenceEntityId && Math.Abs(pastedEntity.pasteIndex - pasteIndex) <= 1 && Vector3.Distance(pastedEntity.pose.position, testPos) < 0.2) { // found a pasted entity that we can connect to ! otherPastedId = pastedEntity.pasteId; otherObjId = pastedEntity.objId; break; } } } if (otherObjId == 0) { int[] _nearObjectIds = new int[256]; // find building nearby int found = nearcdLogic.GetBuildingsInAreaNonAlloc(testPos, 0.2f, _nearObjectIds, false); // find nearest building float maxDistance = 1f; for (int x = 0; x < found; x++) { var id = _nearObjectIds[x]; float distance; ItemProto proto; if (id == 0 || id == pastedReferenceEntityBuildPreview.objId) { continue; } else if (id > 0) { EntityData entityData = factory.entityPool[id]; proto = LDB.items.Select((int)entityData.protoId); // ignore buildings without inserter poses if (!proto.prefabDesc.isBelt && proto.prefabDesc.insertPoses.Length == 0) { continue; } distance = Vector3.Distance(entityData.pos, testPos); } else { PrebuildData prebuildData = factory.prebuildPool[-id]; proto = LDB.items.Select((int)prebuildData.protoId); // ignore unbuilt belts and buildings without inserter poses if (proto.prefabDesc.isBelt || proto.prefabDesc.insertPoses.Length == 0) { continue; } distance = Vector3.Distance(prebuildData.pos, testPos); } // ignore entitites that ore not (built) belts or don't have inserterPoses if ((proto.prefabDesc.isBelt == copiedInserter.otherIsBelt || proto.prefabDesc.insertPoses.Length > 0) && distance < maxDistance) { otherObjId = otherEntityId = id; maxDistance = distance; } } } } if (otherObjId != 0) { if (copiedInserter.incoming) { InserterPoses.CalculatePose(actionBuild, otherObjId, referenceObjId); } else { InserterPoses.CalculatePose(actionBuild, referenceObjId, otherObjId); } bool hasNearbyPose = false; if (actionBuild.posePairs.Count > 0) { float minDistance = 1000f; PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair(); for (int j = 0; j < actionBuild.posePairs.Count; ++j) { var posePair = actionBuild.posePairs[j]; if ( (copiedInserter.incoming && copiedInserter.endSlot != posePair.endSlot && copiedInserter.endSlot != -1) || (!copiedInserter.incoming && copiedInserter.startSlot != posePair.startSlot && copiedInserter.startSlot != -1) ) { continue; } float startDistance = Vector3.Distance(posePair.startPose.position, absoluteInserterPos); float endDistance = Vector3.Distance(posePair.endPose.position, absoluteInserterPos2); float poseDistance = startDistance + endDistance; if (poseDistance < minDistance) { minDistance = poseDistance; bestFit = posePair; hasNearbyPose = true; } } if (hasNearbyPose) { // if we were able to calculate a close enough sensible pose // use that instead of the (visually) imprecise default absoluteInserterPos = bestFit.startPose.position; absoluteInserterPos2 = bestFit.endPose.position; absoluteInserterRot = bestFit.startPose.rotation; absoluteInserterRot2 = bestFit.endPose.rotation * Quaternion.Euler(0.0f, 180f, 0.0f); pickOffset = (short)bestFit.startOffset; insertOffset = (short)bestFit.endOffset; startSlot = bestFit.startSlot; endSlot = bestFit.endSlot; posDelta = bestFit.startPose.position.ToSpherical() - absoluteBuildingPosSpr; pos2Delta = bestFit.endPose.position.ToSpherical() - absoluteBuildingPosSpr; } } } InserterPosition position = new InserterPosition() { copiedInserter = copiedInserter, absoluteBuildingPos = absoluteBuildingPos, absoluteBuildingRot = absoluteBuildingRot, posDelta = posDelta, pos2Delta = pos2Delta, absoluteInserterPos = absoluteInserterPos, absoluteInserterPos2 = absoluteInserterPos2, absoluteInserterRot = absoluteInserterRot, absoluteInserterRot2 = absoluteInserterRot2, pickOffset = pickOffset, insertOffset = insertOffset, startSlot = startSlot, endSlot = endSlot, condition = EBuildCondition.Ok }; if (otherEntityId != 0) { Vector3 forward = absoluteInserterPos2 - absoluteInserterPos; Pose pose; pose.position = Vector3.Lerp(absoluteInserterPos, absoluteInserterPos2, 0.5f); pose.rotation = Quaternion.LookRotation(forward, absoluteInserterPos.normalized); var colliderData = copiedInserter.itemProto.prefabDesc.buildColliders[0]; colliderData.ext = new Vector3(colliderData.ext.x, colliderData.ext.y, Vector3.Distance(absoluteInserterPos2, absoluteInserterPos) * 0.5f + colliderData.ext.z - 0.5f); if (copiedInserter.otherIsBelt) { if (copiedInserter.incoming) { colliderData.pos.z -= 0.4f; colliderData.ext.z += 0.4f; } else { colliderData.pos.z += 0.4f; colliderData.ext.z += 0.4f; } } if (colliderData.ext.z < 0.1f) { colliderData.ext.z = 0.1f; } colliderData.pos = pose.position + pose.rotation * colliderData.pos; colliderData.q = pose.rotation * colliderData.q; int mask = 165888; Collider[] _tmp_cols = new Collider[16]; int collisionsFound = Physics.OverlapBoxNonAlloc(colliderData.pos, colliderData.ext, _tmp_cols, colliderData.q, mask, QueryTriggerInteraction.Collide); PlanetPhysics physics2 = player.planetData.physics; for (int j = 0; j < collisionsFound; j++) { physics2.GetColliderData(_tmp_cols[j], out ColliderData colliderData2); if (colliderData2.objId != 0 && colliderData2.objId != otherEntityId && colliderData2.usage == EColliderUsage.Build) { position.condition = EBuildCondition.Collide; otherPastedId = 0; otherEntityId = 0; break; } } } position.inputEntityId = copiedInserter.incoming ? otherEntityId : 0; position.inputPastedId = copiedInserter.incoming ? otherPastedId : pastedReferenceEntityId; position.outputEntityId = copiedInserter.incoming ? 0 : otherEntityId; position.outputPastedId = copiedInserter.incoming ? pastedReferenceEntityId : otherPastedId; return(position); }
public static PastedEntity ConcurrentPasteInserter(int threadIndex, InserterCopy inserter, float yaw, int pasteIndex, bool connectToPasted = false) { var actionBuild = _abs[threadIndex]; int pasteId = PASTE_INDEX_MULTIPLIER * pasteIndex + inserter.originalId; if (!BlueprintManager.pastedEntities.TryGetValue(pasteId, out PastedEntity pastedEntity)) { BuildPreview bp = BuildPreview.CreateSingle(inserter.itemProto, inserter.itemProto.prefabDesc, true); pastedEntity = new PastedEntity() { pasteIndex = pasteIndex, pasteId = pasteId, status = EPastedStatus.NEW, type = EPastedType.INSERTER, sourceInserter = inserter, buildPreview = bp, }; bp.filterId = inserter.filterId; bp.inputToSlot = 1; bp.outputFromSlot = 0; BlueprintManager.pastedEntities.TryAdd(pasteId, pastedEntity); lock (actionBuild.buildPreviews) { actionBuild.buildPreviews.Add(bp); } } else { pastedEntity.status = EPastedStatus.UPDATE; } InserterPosition positionData = InserterPoses.GetPositions(actionBuild, inserter, yaw * Mathf.Deg2Rad, pasteIndex, connectToPasted); pastedEntity.buildPreview.lpos = positionData.absoluteInserterPos; pastedEntity.buildPreview.lpos2 = positionData.absoluteInserterPos2; pastedEntity.buildPreview.lrot = positionData.absoluteInserterRot; pastedEntity.buildPreview.lrot2 = positionData.absoluteInserterRot2; pastedEntity.buildPreview.inputOffset = positionData.pickOffset; pastedEntity.buildPreview.outputOffset = positionData.insertOffset; pastedEntity.buildPreview.outputToSlot = positionData.endSlot; pastedEntity.buildPreview.inputFromSlot = positionData.startSlot; pastedEntity.buildPreview.condition = positionData.condition; pastedEntity.buildPreview.input = null; pastedEntity.buildPreview.inputObjId = 0; pastedEntity.buildPreview.output = null; pastedEntity.buildPreview.outputObjId = 0; if (BlueprintManager.pastedEntities.TryGetValue(positionData.inputPastedId, out PastedEntity inputPastedEntity)) { pastedEntity.buildPreview.input = inputPastedEntity.buildPreview; } else { pastedEntity.buildPreview.inputObjId = positionData.inputEntityId; } if (BlueprintManager.pastedEntities.TryGetValue(positionData.outputPastedId, out PastedEntity outputPastedEntity)) { pastedEntity.buildPreview.output = outputPastedEntity.buildPreview; } else { pastedEntity.buildPreview.outputObjId = positionData.outputEntityId; } return(pastedEntity); }
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); }
public static void PlayerAction_Build_ClearBuildPreviews_Prefix() { pastedEntities.Clear(); InserterPoses.ResetOverrides(); }