示例#1
0
        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);
        }
示例#2
0
        public static void PreparePaste()
        {
            InserterPoses.ResetOverrides();

            BlueprintManager_Paste.PrepareThreads();

            foreach (var pastedEntity in pastedEntities.Values)
            {
                pastedEntity.status = EPastedStatus.REMOVE;
            }
        }
示例#3
0
        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,
                });
            }
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        public static List <BuildPreview> Paste(Vector3 targetPos, float yaw, bool pasteInserters = true)
        {
            PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild;

            pastedEntities.Clear();
            parallelPastedEntities.Clear();
            previews.Clear();
            InserterPoses.ResetOverrides();

            Vector2 targetSpr = targetPos.ToSpherical();
            float   yawRad    = yaw * Mathf.Deg2Rad;


            for (int i = 0; i < data.copiedBuildings.Count; i++)
            {
                PasteBuilding(i, data.copiedBuildings[i], targetSpr, yaw);
            }

            for (int i = 0; i < data.copiedBelts.Count; i++)
            {
                PasteBelt(i, data.copiedBelts[i], targetSpr, yaw);
            }

            if (pasteInserters && data.copiedInserters.Count > 16)
            {
                var maxThreads        = Environment.ProcessorCount - 1;
                var runningThreads    = 0;
                var next              = -1;
                ManualResetEvent done = new ManualResetEvent(false);

                for (int i = 0; i < maxThreads; i++)
                {
                    ThreadPool.QueueUserWorkItem(_ =>
                    {
                        int item;
                        Interlocked.Increment(ref runningThreads);

                        try
                        {
                            PlayerAction_Build ab = BuildLogic.ClonePlayerAction_Build(actionBuild);
                            while ((item = Interlocked.Increment(ref next)) < data.copiedInserters.Count)
                            {
                                PasteInserter(ab, item, data.copiedInserters[item], yaw);
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.ToString());
                        }
                        finally
                        {
                            if (Interlocked.Decrement(ref runningThreads) == 0)
                            {
                                done.Set();
                            }
                        }
                    });
                }

                done.WaitOne();
            }
            else if (pasteInserters)
            {
                for (var i = 0; i < data.copiedInserters.Count; i++)
                {
                    PasteInserter(actionBuild, i, data.copiedInserters[i], yaw);
                }
            }
            // merge the inserter pastedEntities in the main dictionaries
            foreach (var item in parallelPastedEntities)
            {
                previews.Add(item.Value.buildPreview);
                pastedEntities.Add(item.Key, item.Value);
            }

            // after creating the belt previews this restore the correct connection to other belts and buildings
            foreach (BeltCopy belt in data.copiedBelts)
            {
                BuildPreview preview = pastedEntities[belt.originalId].buildPreview;

                if (belt.outputId != 0 &&
                    pastedEntities.TryGetValue(belt.outputId, out PastedEntity otherEntity) &&
                    Vector3.Distance(preview.lpos, otherEntity.buildPreview.lpos) < 10) // if the belts are too far apart ignore connection
                {
                    preview.output = otherEntity.buildPreview;
                    var otherBelt = data.copiedBelts[otherEntity.index];

                    if (otherBelt.backInputId == belt.originalId)
                    {
                        preview.outputToSlot = 1;
                    }
                    if (otherBelt.leftInputId == belt.originalId)
                    {
                        preview.outputToSlot = 2;
                    }
                    if (otherBelt.rightInputId == belt.originalId)
                    {
                        preview.outputToSlot = 3;
                    }
                }

                if (belt.connectedBuildingId != 0 && pastedEntities.TryGetValue(belt.connectedBuildingId, out PastedEntity otherBuilding))
                {
                    if (belt.connectedBuildingIsOutput)
                    {
                        preview.output       = otherBuilding.buildPreview;
                        preview.outputToSlot = belt.connectedBuildingSlot;
                    }
                    else
                    {
                        preview.input         = otherBuilding.buildPreview;
                        preview.inputFromSlot = belt.connectedBuildingSlot;
                    }
                }

                bool beltHasInput  = pastedEntities.ContainsKey(belt.backInputId) || pastedEntities.ContainsKey(belt.leftInputId) || pastedEntities.ContainsKey(belt.rightInputId);
                bool beltHasOutput = pastedEntities.ContainsKey(belt.outputId);

                if (!beltHasInput || !beltHasOutput)
                {
                    int found = actionBuild.nearcdLogic.GetBuildingsInAreaNonAlloc(preview.lpos, 0.34f, _nearObjectIds, false);
                    for (int x = 0; x < found; x++)
                    {
                        int overlappingEntityId = _nearObjectIds[x];

                        if (overlappingEntityId <= 0)
                        {
                            continue;
                        }

                        EntityData overlappingEntityData = actionBuild.factory.entityPool[overlappingEntityId];

                        if (overlappingEntityData.beltId <= 0)
                        {
                            continue;
                        }

                        BeltComponent overlappingBelt = actionBuild.factory.cargoTraffic.beltPool[overlappingEntityData.beltId];

                        bool overlappingBeltHasInput  = (overlappingBelt.backInputId + overlappingBelt.leftInputId + overlappingBelt.rightInputId) != 0;
                        bool overlappingBeltHasOutput = overlappingBelt.outputId != 0;

                        if ((beltHasOutput && !overlappingBeltHasOutput) || (beltHasInput && !overlappingBeltHasInput))
                        {
                            // found overlapping belt that can be 'replaced' to connect to existing belts
                            preview.coverObjId     = overlappingEntityId;
                            preview.ignoreCollider = true;
                            preview.willCover      = true;
                        }
                    }
                }
            }


            return(previews);
        }
示例#7
0
        public static 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);
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
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);
        }
示例#11
0
 public static void PlayerAction_Build_ClearBuildPreviews_Prefix()
 {
     pastedEntities.Clear();
     InserterPoses.ResetOverrides();
 }