public static void SetCopyInfo_Postfix(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, int objectId, int protoId)
        {
            cachedInserters.Clear(); // Remove previous copy info
            if (objectId < 0)        // Copied item is a ghost, no inserters to cache
            {
                return;
            }
            var sourceEntityProto = LDB.items.Select(protoId);
            var sourceEntityId    = objectId;
            var sourceEntity      = ___factory.entityPool[sourceEntityId];
            var sourcePos         = sourceEntity.pos;
            var sourceRot         = sourceEntity.rot;

            // Set the current build rotation to the copied building rotation
            Quaternion zeroRot = Maths.SphericalRotation(sourcePos, 0f);
            float      yaw     = Vector3.SignedAngle(zeroRot.Forward(), sourceRot.Forward(), zeroRot.Up());

            if (sourceEntityProto.prefabDesc.minerType != EMinerType.Vein)
            {
                yaw = Mathf.Round(yaw / 90f) * 90f;
            }
            __instance.yaw = yaw;

            // Ignore building without inserter slots
            if (sourceEntityProto.prefabDesc.insertPoses.Length == 0)
            {
                return;
            }

            // Find connected inserters
            var inserterPool = ___factory.factorySystem.inserterPool;
            var entityPool   = ___factory.entityPool;

            for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++)
            {
                if (inserterPool[i].id == i)
                {
                    var inserter       = inserterPool[i];
                    var inserterEntity = entityPool[inserter.entityId];

                    var pickTarget   = inserter.pickTarget;
                    var insertTarget = inserter.insertTarget;

                    if (pickTarget == sourceEntityId || insertTarget == sourceEntityId)
                    {
                        ItemProto itemProto = LDB.items.Select(inserterEntity.protoId);

                        bool      incoming = insertTarget == sourceEntityId;
                        var       otherId  = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to
                        Vector3   otherPos;
                        ItemProto otherProto;

                        if (otherId > 0)
                        {
                            otherPos   = entityPool[otherId].pos;
                            otherProto = LDB.items.Select((int)___factory.entityPool[otherId].protoId);
                        }
                        else
                        {
                            otherPos   = ___factory.prebuildPool[-otherId].pos;
                            otherProto = LDB.items.Select((int)___factory.prebuildPool[-otherId].protoId);
                        }

                        // Store the Grid-Snapped moves from assembler to belt/other
                        int       path              = 0;
                        Vector3[] snaps             = new Vector3[6];
                        var       snappedPointCount = ___planetAux.SnapLineNonAlloc(sourcePos, otherPos, ref path, snaps);
                        Vector3   lastSnap          = sourcePos;
                        Vector3[] snapMoves         = new Vector3[snappedPointCount];
                        for (int s = 0; s < snappedPointCount; s++)
                        {
                            // note: reverse rotation of the delta so that rotation works
                            Vector3 snapMove = Quaternion.Inverse(sourceRot) * (snaps[s] - lastSnap);
                            snapMoves[s] = snapMove;
                            lastSnap     = snaps[s];
                        }

                        bool otherIsBelt = otherProto != null && otherProto.prefabDesc.isBelt;

                        // Cache info for this inserter
                        CachedInserter ci = new CachedInserter
                        {
                            incoming = incoming,
                            protoId  = inserterEntity.protoId,

                            // rotations + deltas relative to the source building's rotation
                            rot       = Quaternion.Inverse(sourceRot) * inserterEntity.rot,
                            rot2      = Quaternion.Inverse(sourceRot) * inserter.rot2,
                            posDelta  = Quaternion.Inverse(sourceRot) * (inserterEntity.pos - sourcePos), // Delta from copied building to inserter pos
                            pos2Delta = Quaternion.Inverse(sourceRot) * (inserter.pos2 - sourcePos),      // Delta from copied building to inserter pos2

                            // store to restore inserter speed
                            refCount = Mathf.RoundToInt((float)(inserter.stt - 0.499f) / itemProto.prefabDesc.inserterSTT),

                            // not important?
                            pickOffset   = inserter.pickOffset,
                            insertOffset = inserter.insertOffset,

                            // needed for pose?
                            t1 = inserter.t1,
                            t2 = inserter.t2,

                            filterId  = inserter.filter,
                            snapMoves = snapMoves,
                            snapCount = snappedPointCount,

                            startSlot = -1,
                            endSlot   = -1,

                            otherIsBelt = otherIsBelt
                        };


                        // compute the start and end slot that the cached inserter uses
                        CalculatePose(__instance, pickTarget, insertTarget);

                        if (__instance.posePairs.Count > 0)
                        {
                            float minDistance = 1000f;
                            for (int j = 0; j < __instance.posePairs.Count; ++j)
                            {
                                var   posePair      = __instance.posePairs[j];
                                float startDistance = Vector3.Distance(posePair.startPose.position, inserterEntity.pos);
                                float endDistance   = Vector3.Distance(posePair.endPose.position, inserter.pos2);
                                float poseDistance  = startDistance + endDistance;

                                if (poseDistance < minDistance)
                                {
                                    minDistance  = poseDistance;
                                    ci.startSlot = posePair.startSlot;
                                    ci.endSlot   = posePair.endSlot;
                                }
                            }
                        }

                        cachedInserters.Add(ci);
                    }
                }
            }
        }
Exemple #2
0
            public static void PlayerAction_BuildSetCopyInfoPostfix(PlayerAction_Build __instance, ref PlanetFactory ___factory, PlanetAuxData ___planetAux, int objectId, int protoId)
            {
                cachedInserters.Clear(); // Remove previous copy info
                if (objectId < 0)        // Copied item is a ghost, no inserters to cache
                {
                    return;
                }
                var sourceEntityProto = LDB.items.Select(protoId);

                // Ignore building without inserter slots
                if (sourceEntityProto.prefabDesc.insertPoses.Length == 0)
                {
                    return;
                }

                var sourceEntityId = objectId;
                var sourceEntity   = ___factory.entityPool[sourceEntityId];
                var sourcePos      = sourceEntity.pos;
                var sourceRot      = sourceEntity.rot;

                // Find connected inserters
                var inserterPool = ___factory.factorySystem.inserterPool;
                var entityPool   = ___factory.entityPool;

                for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++)
                {
                    if (inserterPool[i].id == i)
                    {
                        var inserter       = inserterPool[i];
                        var inserterEntity = entityPool[inserter.entityId];

                        var pickTarget   = inserter.pickTarget;
                        var insertTarget = inserter.insertTarget;

                        if (pickTarget == sourceEntityId || insertTarget == sourceEntityId)
                        {
                            bool incoming = insertTarget == sourceEntityId;
                            var  otherId  = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to
                            var  otherPos = entityPool[otherId].pos;

                            // Store the Grid-Snapped moves from assembler to belt/other
                            int       path              = 0;
                            Vector3[] snaps             = new Vector3[6];
                            var       snappedPointCount = ___planetAux.SnapLineNonAlloc(sourcePos, otherPos, ref path, snaps);
                            Vector3   lastSnap          = sourcePos;
                            Vector3[] snapMoves         = new Vector3[snappedPointCount];
                            for (int s = 0; s < snappedPointCount; s++)
                            {
                                // note: reverse rotation of the delta so that rotation works
                                Vector3 snapMove = Quaternion.Inverse(sourceRot) * (snaps[s] - lastSnap);
                                snapMoves[s] = snapMove;
                                lastSnap     = snaps[s];
                            }

                            // Cache info for this inserter
                            var ci = new CachedInserter();
                            ci.incoming = incoming;
                            ci.protoId  = inserterEntity.protoId;

                            // rotations + deltas relative to the source building's rotation
                            ci.rot       = Quaternion.Inverse(sourceRot) * inserterEntity.rot;
                            ci.rot2      = Quaternion.Inverse(sourceRot) * inserter.rot2;
                            ci.posDelta  = Quaternion.Inverse(sourceRot) * (inserterEntity.pos - sourcePos); // Delta from copied building to inserter pos
                            ci.pos2Delta = Quaternion.Inverse(sourceRot) * (inserter.pos2 - sourcePos);      // Delta from copied building to inserter pos2

                            ItemProto itemProto = LDB.items.Select(ci.protoId);
                            ci.refCount = Mathf.RoundToInt((float)(inserter.stt - 0.499f) / itemProto.prefabDesc.inserterSTT);
                            // compute the start and end slot that the cached inserter uses
                            if (!incoming)
                            {
                                CalculatePose(__instance, sourceEntityId, otherId);
                            }
                            else
                            {
                                CalculatePose(__instance, otherId, sourceEntityId);
                            }

                            if (__instance.posePairs.Count > 0)
                            {
                                float minDistance = 1000f;
                                PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair();
                                bool hasNearbyPose = false;
                                for (int j = 0; j < __instance.posePairs.Count; ++j)
                                {
                                    float startDistance = Vector3.Distance(__instance.posePairs[j].startPose.position, inserterEntity.pos);
                                    float endDistance   = Vector3.Distance(__instance.posePairs[j].endPose.position, inserter.pos2);
                                    float poseDistance  = startDistance + endDistance;

                                    if (poseDistance < minDistance)
                                    {
                                        minDistance   = poseDistance;
                                        bestFit       = __instance.posePairs[j];
                                        hasNearbyPose = true;
                                    }
                                }
                                if (hasNearbyPose)
                                {
                                    ci.startSlot = bestFit.startSlot;
                                    ci.endSlot   = bestFit.endSlot;
                                }
                            }

                            // not important?
                            ci.pickOffset   = inserter.pickOffset;
                            ci.insertOffset = inserter.insertOffset;
                            // needed for pose?
                            ci.t1 = inserter.t1;
                            ci.t2 = inserter.t2;

                            ci.filterId  = inserter.filter;
                            ci.snapMoves = snapMoves;
                            ci.snapCount = snappedPointCount;

                            cachedInserters.Add(ci);
                        }
                    }
                }
            }
Exemple #3
0
            public static void PlayerAction_BuildSetCopyInfoPostfix(ref PlanetFactory ___factory, int objectId, PlanetAuxData ___planetAux)
            {
                cachedInserters.Clear(); // Remove previous copy info

                var sourceEntity = objectId;
                var sourcePos    = ___factory.entityPool[objectId].pos;
                var sourceRot    = ___factory.entityPool[objectId].rot;
                // Find connected inserters
                int matches      = 0;
                var inserterPool = ___factory.factorySystem.inserterPool;
                var entityPool   = ___factory.entityPool;

                for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++)
                {
                    if (inserterPool[i].id == i)
                    {
                        var inserter     = inserterPool[i];
                        var pickTarget   = inserter.pickTarget;
                        var insertTarget = inserter.insertTarget;
                        if (pickTarget == sourceEntity || insertTarget == sourceEntity)
                        {
                            matches++;
                            var  inserterType = ___factory.entityPool[inserter.entityId].protoId;
                            bool incoming     = insertTarget == sourceEntity;
                            var  otherId      = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to
                            var  otherPos     = ___factory.entityPool[otherId].pos;

                            // Store the Grid-Snapped moves from assembler to belt/other
                            Vector3   begin             = sourcePos;
                            Vector3   end               = otherPos;
                            int       path              = 0;
                            Vector3[] snaps             = new Vector3[6];
                            var       snappedPointCount = ___planetAux.SnapLineNonAlloc(begin, end, ref path, snaps);
                            Vector3   lastSnap          = begin;
                            Vector3[] snapMoves         = new Vector3[snappedPointCount];
                            for (int s = 0; s < snappedPointCount; s++)
                            {
                                Vector3 snapMove = snaps[s] - lastSnap;
                                snapMoves[s] = snapMove;
                                lastSnap     = snaps[s];
                            }

                            // Cache info for this inserter
                            var ci = new CachedInserter();
                            ci.incoming  = incoming;
                            ci.protoId   = inserterType;
                            ci.rot       = ___factory.entityPool[inserter.entityId].rot;
                            ci.rot2      = inserter.rot2;
                            ci.pos2delta = inserter.pos2; // YukkuriC: record abs pos first
                            ci.posDelta  = entityPool[inserter.entityId].pos;

                            // YukkuriC: dump relative transforms
                            Helper.RelTransform(sourcePos,
                                                entityPool[inserter.entityId].pos, ___factory.entityPool[inserter.entityId].rot,
                                                out ci.posDelta, out ci.rot);
                            Helper.RelTransform(sourcePos,
                                                inserter.pos2, inserter.rot2,
                                                out ci.pos2delta, out ci.rot2);

                            // not important?
                            ci.pickOffset   = inserter.pickOffset;
                            ci.insertOffset = inserter.insertOffset;
                            // needed for pose?
                            ci.t1 = inserter.t1;
                            ci.t2 = inserter.t2;


                            ci.filterId  = inserter.filter;
                            ci.snapMoves = snapMoves;
                            ci.snapCount = snappedPointCount;

                            cachedInserters.Add(ci);
                        }
                    }
                }
            }
            public static void PlayerAction_BuildSetCopyInfoPostfix(PlayerAction_Build __instance, ref PlanetFactory ___factory, int objectId, PlanetAuxData ___planetAux)
            {
                cachedInserters.Clear(); // Remove previous copy info
                if (objectId < 0)        // Copied item is a ghost, no inserters to cache
                {
                    return;
                }

                var sourceEntity = objectId;
                var sourcePos    = ___factory.entityPool[objectId].pos;
                // Find connected inserters
                int matches      = 0;
                var inserterPool = ___factory.factorySystem.inserterPool;
                var entityPool   = ___factory.entityPool;

                for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++)
                {
                    if (inserterPool[i].id == i)
                    {
                        var inserter     = inserterPool[i];
                        var pickTarget   = inserter.pickTarget;
                        var insertTarget = inserter.insertTarget;
                        if (pickTarget == sourceEntity || insertTarget == sourceEntity)
                        {
                            matches++;
                            var  inserterType = ___factory.entityPool[inserter.entityId].protoId;
                            bool incoming     = insertTarget == sourceEntity;
                            var  otherId      = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to
                            var  otherPos     = ___factory.entityPool[otherId].pos;

                            // Store the Grid-Snapped moves from assembler to belt/other
                            Vector3   begin             = sourcePos;
                            Vector3   end               = otherPos;
                            int       path              = 0;
                            Vector3[] snaps             = new Vector3[6];
                            var       snappedPointCount = ___planetAux.SnapLineNonAlloc(begin, end, ref path, snaps);
                            Vector3   lastSnap          = begin;
                            Vector3[] snapMoves         = new Vector3[snappedPointCount];
                            for (int s = 0; s < snappedPointCount; s++)
                            {
                                Vector3 snapMove = snaps[s] - lastSnap;
                                snapMoves[s] = snapMove;
                                lastSnap     = snaps[s];
                            }

                            // Cache info for this inserter
                            var ci = new CachedInserter();
                            ci.otherDelta = (otherPos - sourcePos); // Delta from copied building to other belt/building
                            ci.incoming   = incoming;
                            ci.protoId    = inserterType;
                            ci.rot        = ___factory.entityPool[inserter.entityId].rot;
                            ci.rot2       = inserter.rot2;
                            ci.pos2delta  = (inserter.pos2 - entityPool[inserter.entityId].pos); // Delta from inserter pos2 to copied building
                            var posDelta = entityPool[inserter.entityId].pos - sourcePos;        // Delta from copied building to inserter pos
                            if (!incoming)
                            {
                                posDelta = sourcePos - entityPool[inserter.entityId].pos;            // Reverse for outgoing inserters
                            }
                            ci.posDelta = posDelta;


                            // compute the start and end slot that the cached inserter uses
                            if (!incoming)
                            {
                                CalculatePose(__instance, sourceEntity, otherId);
                            }
                            else
                            {
                                CalculatePose(__instance, otherId, sourceEntity);
                            }

                            if (__instance.posePairs.Count > 0)
                            {
                                float minDistance = 1000f;
                                PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair();
                                bool hasNearbyPose = false;
                                for (int j = 0; j < __instance.posePairs.Count; ++j)
                                {
                                    float startDistance = Vector3.Distance(__instance.posePairs[j].startPose.position, entityPool[inserter.entityId].pos);
                                    float endDistance   = Vector3.Distance(__instance.posePairs[j].endPose.position, inserter.pos2);
                                    float poseDistance  = startDistance + endDistance;

                                    if (poseDistance < minDistance)
                                    {
                                        minDistance   = poseDistance;
                                        bestFit       = __instance.posePairs[j];
                                        hasNearbyPose = true;
                                    }
                                }
                                if (hasNearbyPose)
                                {
                                    ci.startSlot = bestFit.startSlot;
                                    ci.endSlot   = bestFit.endSlot;
                                }
                            }

                            // not important?
                            ci.pickOffset   = inserter.pickOffset;
                            ci.insertOffset = inserter.insertOffset;
                            // needed for pose?
                            ci.t1 = inserter.t1;
                            ci.t2 = inserter.t2;


                            ci.filterId  = inserter.filter;
                            ci.snapMoves = snapMoves;
                            ci.snapCount = snappedPointCount;

                            cachedInserters.Add(ci);
                        }
                    }
                }
            }