Exemplo n.º 1
0
        public ColliderManager(VisibleVegetationCellSelector visibleVegetationCellSelector,
                               VegetationSystemPro vegetationSystemPro, VegetationItemInfoPro vegetationItemInfoPro,
                               Transform colliderParent, bool showColliders)
        {
            _showColliders         = showColliders;
            _vegetationSystemPro   = vegetationSystemPro;
            _vegetationItemInfoPro = vegetationItemInfoPro;

            float cullingDistance = vegetationSystemPro.VegetationSettings.GetVegetationDistance() *
                                    vegetationItemInfoPro.ColliderDistanceFactor;


            VegetationItemSelector = new VegetationItemSelector(visibleVegetationCellSelector, vegetationSystemPro,
                                                                vegetationItemInfoPro, false, 1, 0)
            {
                CullingDistance = cullingDistance
            };

            VegetationItemSelector.OnVegetationItemVisibleDelegate   += OnVegetationItemVisible;
            VegetationItemSelector.OnVegetationItemInvisibleDelegate += OnVegetationItemInvisible;
            VegetationItemSelector.OnVegetationCellInvisibleDelegate += OnVegetationCellInvisible;

            VegetationItemModelInfo vegetationItemModelInfo =
                vegetationSystemPro.GetVegetationItemModelInfo(vegetationItemInfoPro.VegetationItemID);

            ColliderPool         = new ColliderPool(vegetationItemInfoPro, vegetationItemModelInfo, vegetationSystemPro, colliderParent, _showColliders);
            RuntimePrefabStorage = new RuntimePrefabStorage(ColliderPool);
        }
 private void Awake()
 {
     Instance     = this;
     spritePool   = GetComponent <SpritePool>();
     colliderPool = GetComponent <ColliderPool>();
     generator    = new FloorGenerator(this);
     generator.Generate(RoomCount);
 }
    public Room(int pX, int pY, SpritePool spritePool, ColliderPool colliderPool)
    {
        tiles = new Tile[Width * Height];

        Pos      = new Vec2i(pX, pY);
        WorldPos = new Vector2(pX * Width, pY * Height);

        this.spritePool = spritePool;
        collision       = new RoomCollision(this, colliderPool);
    }
Exemplo n.º 4
0
 protected override void OnUpdate()
 {
     Entities.ForEach((Entity entity, ref Health health, ref Translation pos, ref Damage damage) =>
     {
         if (health.beHitValue > 0)
         {
             ColliderPool.PlayBulletImpact(pos.Value, health.beHitValue, entity.Index);
             health.beHitValue = 0f;
         }
     });
 }
Exemplo n.º 5
0
    private void Awake()
    {
        Instance = this;

        spritePool   = GetComponent <SpritePool>();
        colliderPool = GetComponent <ColliderPool>();

        generators[0] = new LinearGenerator(this, enemyPrefabs);

        Pathfinder = new FloorPathfinder(this);
    }
Exemplo n.º 6
0
    void Start()
    {
        manager = World.Active.GetOrCreateManager <EntityManager>();

        PerlinNoiseGenerator perlin = new PerlinNoiseGenerator();

        heightmap = perlin.GenerateHeightMap();

        //创建一个碰撞池
        colPool = new ColliderPool(boxCollider, transform);

        ChunckGenerator(chunckBase);
    }
Exemplo n.º 7
0
    public Room(int pX, int pY, SpritePool spritePool, ColliderPool colliderPool, Floor floor)
    {
        this.floor = floor;
        tiles      = new Tile[Width * Height];

        Pos      = new Vec2i(pX, pY);
        tileRect = new RectInt(pX * Width, pY * Height, Width, Height);
        WorldPos = new Vector2(tileRect.xMin, tileRect.yMin);

        this.spritePool = spritePool;

        collision = new RoomCollision(this, colliderPool);
    }
Exemplo n.º 8
0
    void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(gameObject);
            return;
        }
        else
        {
            instance = this;
        }

        damagePool = new ShootTextProController[damagePoolSize];
        for (int i = 0; i < damagePoolSize; i++)
        {
            damagePool[i] = Instantiate(shootTextProController, instance.transform);
        }
    }
Exemplo n.º 9
0
        public static void DetermineBuildPreviews_Postfix(ref PlayerAction_Build __instance)
        {
            if (IsMultiBuildRunning())
            {
                __instance.ClearBuildPreviews();

                if (__instance.previewPose.position == Vector3.zero)
                {
                    return;
                }

                __instance.previewPose.position = Vector3.zero;
                __instance.previewPose.rotation = Quaternion.identity;

                int       snapPath = path;
                Vector3[] snaps    = new Vector3[1024];

                var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                var        desc        = __instance.handPrefabDesc;
                Collider[] colliders   = new Collider[desc.buildColliders.Length];
                Vector3    previousPos = Vector3.zero;

                var usedSnaps = new List <Vector3>(10);

                var maxSnaps = Math.Max(1, snappedPointCount - spacing);

                for (int s = 0; s < maxSnaps; s++)
                {
                    var pos = snaps[s];
                    var rot = Maths.SphericalRotation(snaps[s], __instance.yaw);

                    if (s > 0)
                    {
                        var sqrDistance = (previousPos - pos).sqrMagnitude;

                        // power towers
                        if (desc.isPowerNode && sqrDistance < 12.25f)
                        {
                            continue;
                        }

                        // wind turbines
                        if (desc.windForcedPower && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // ray receivers
                        if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // logistic stations
                        if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                        {
                            continue;
                        }

                        // ejector
                        if (desc.isEjector && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        if (desc.hasBuildCollider)
                        {
                            var foundCollision = false;
                            for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                            {
                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                            }

                            if (foundCollision)
                            {
                                continue;
                            }
                        }
                    }

                    if (s > 0 && spacing > 0)
                    {
                        s  += spacing;
                        pos = snaps[s];
                        rot = Maths.SphericalRotation(snaps[s], __instance.yaw);
                    }

                    previousPos = pos;
                    usedSnaps.Add(pos);

                    var bp = BuildPreview.CreateSingle(__instance.handItem, __instance.handPrefabDesc, true);
                    bp.ResetInfos();
                    bp.desc     = desc;
                    bp.lpos     = pos;
                    bp.lrot     = rot;
                    bp.item     = __instance.handItem;
                    bp.recipeId = __instance.copyRecipeId;
                    bp.filterId = __instance.copyFilterId;

                    if (desc.hasBuildCollider)
                    {
                        for (var j = 0; j < desc.buildColliders.Length; j++)
                        {
                            // create temporary collider entities for the latest 'positioned' building
                            if (colliders[j] != null)
                            {
                                ColliderPool.PutCollider(colliders[j]);
                            }

                            var colliderData = desc.buildColliders[j];
                            colliderData.pos = pos + rot * colliderData.pos;
                            colliderData.q   = rot * colliderData.q;
                            colliders[j]     = ColliderPool.TakeCollider(colliderData);
                            colliders[j].gameObject.layer = 27;
                        }
                    }

                    __instance.AddBuildPreview(bp);
                }

                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        ColliderPool.PutCollider(collider);
                    }
                }


                ActivateColliders(ref __instance.nearcdLogic, usedSnaps);
            }
        }
Exemplo n.º 10
0
        public static bool PlayerAction_Build_DetermineBuildPreviews_Prefix(ref PlayerAction_Build __instance)
        {
            if (__instance.controller.cmd.mode != 1 ||
                __instance.player.planetData.type == EPlanetType.Gas ||
                !__instance.cursorValid ||
                __instance.groundSnappedPos == Vector3.zero ||
                (__instance.handPrefabDesc != null && __instance.handPrefabDesc.minerType != EMinerType.None)
                )
            {
                lastRunOriginal = true;
                return(true);
            }

            __instance.waitConfirm        = __instance.cursorValid;
            __instance.multiLevelCovering = false;
            if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.multiLevel)
            {
                int objectProtoId = __instance.GetObjectProtoId(__instance.castObjId);
                if (objectProtoId == __instance.handItem.ID)
                {
                    __instance.multiLevelCovering = true;
                }
            }

            if (!MultiBuild.IsMultiBuildRunning() && (__instance.multiLevelCovering || !BlueprintManager.hasData))
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            // full hijacking of DetermineBuildPreviews
            lastRunOriginal = false;
            if (VFInput._switchSplitter.onDown)
            {
                __instance.modelOffset++;
                forceRecalculation = true;
            }

            if (VFInput._rotate.onDown)
            {
                __instance.yaw    += 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }
            if (VFInput._counterRotate.onDown)
            {
                __instance.yaw    -= 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }

            __instance.yaw = Mathf.Round(__instance.yaw / 90f) * 90f;
            __instance.previewPose.position = Vector3.zero;
            __instance.previewPose.rotation = Quaternion.identity;

            if (lastPosition == __instance.groundSnappedPos && !forceRecalculation)
            {
                // no update necessary
                runUpdate = false;
                return(false);
            }
            lastPosition       = __instance.groundSnappedPos;
            forceRecalculation = false;

            List <BuildPreview> previews = new List <BuildPreview>();

            if (MultiBuild.IsMultiBuildRunning())
            {
                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.Add(new BuildingCopy()
                    {
                        itemProto  = __instance.handItem,
                        recipeId   = __instance.copyRecipeId,
                        modelIndex = __instance.handPrefabDesc.modelIndex
                    });
                }
                var building = BlueprintManager.data.copiedBuildings[0];// BlueprintManager.data.copiedBuildings.First();

                int snapPath = path;


                var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(MultiBuild.startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                var        desc        = BlueprintManager.GetPrefabDesc(building);
                Collider[] colliders   = new Collider[desc.buildColliders.Length];
                Vector3    previousPos = Vector3.zero;

                var copiesCounter = 0;
                for (int s = 0; s < snappedPointCount; s++)
                {
                    var pos = snaps[s];
                    var rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);

                    if (s > 0)
                    {
                        var sqrDistance = (previousPos - pos).sqrMagnitude;

                        // power towers
                        if (desc.isPowerNode && !desc.isAccumulator && sqrDistance < 12.25f)
                        {
                            continue;
                        }

                        // wind turbines
                        if (desc.windForcedPower && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // ray receivers
                        if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // logistic stations
                        if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                        {
                            continue;
                        }

                        // ejector
                        if (desc.isEjector && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        if (desc.hasBuildCollider)
                        {
                            var foundCollision = false;
                            for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                            {
                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                            }

                            if (foundCollision)
                            {
                                continue;
                            }
                        }
                    }

                    if (s > 0 && MultiBuild.spacingStore[MultiBuild.spacingIndex] > 0 && copiesCounter % MultiBuild.spacingPeriod == 0)
                    {
                        s += MultiBuild.spacingStore[MultiBuild.spacingIndex];

                        if (s >= snappedPointCount)
                        {
                            break;
                        }
                        pos = snaps[s];
                        rot = Maths.SphericalRotation(snaps[s], __instance.yaw);
                    }

                    copiesCounter++;
                    previousPos = pos;

                    if (desc.hasBuildCollider)
                    {
                        for (var j = 0; j < desc.buildColliders.Length; j++)
                        {
                            // create temporary collider entities for the latest 'positioned' building
                            if (colliders[j] != null)
                            {
                                ColliderPool.PutCollider(colliders[j]);
                            }

                            var colliderData = desc.buildColliders[j];
                            colliderData.pos = pos + rot * colliderData.pos;
                            colliderData.q   = rot * colliderData.q;
                            colliders[j]     = ColliderPool.TakeCollider(colliderData);
                            colliders[j].gameObject.layer = 27;
                        }
                    }

                    previews = previews.Concat(BlueprintManager.Paste(pos, __instance.yaw, MultiBuild.multiBuildInserters)).ToList();
                }

                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.RemoveAt(0);
                }
                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        ColliderPool.PutCollider(collider);
                    }
                }
            }
            else
            {
                var pasteInserters = MultiBuild.multiBuildInserters || (BlueprintManager.data.copiedBuildings.Count + BlueprintManager.data.copiedBelts.Count > 1);
                previews = BlueprintManager.Paste(__instance.groundSnappedPos, __instance.yaw, pasteInserters);
            }

            // synch previews
            var availableModelPreviews = new Dictionary <int, Queue <int> >();

            foreach (var bp in __instance.buildPreviews)
            {
                if (bp.previewIndex >= 0)
                {
                    int modelId = bp.desc.modelIndex;
                    if (!availableModelPreviews.TryGetValue(modelId, out Queue <int> availableIndexes))
                    {
                        availableIndexes = new Queue <int>();
                        availableModelPreviews.Add(modelId, availableIndexes);
                    }
                    availableIndexes.Enqueue(bp.previewIndex);
                }

                bp.Free();
            }

            __instance.buildPreviews.Clear();

            var restored = 0;

            foreach (var bp in previews)
            {
                int modelId = bp.desc.modelIndex;
                if (availableModelPreviews.TryGetValue(modelId, out Queue <int> availableIndexes) && availableIndexes.Count > 0)
                {
                    restored++;
                    bp.previewIndex = availableIndexes.Dequeue();
                }
                __instance.AddBuildPreview(bp);
            }

            var removed = 0;

            foreach (var availableIndexes in availableModelPreviews.Values)
            {
                foreach (var previewIndex in availableIndexes)
                {
                    if (__instance.previewRenderers[previewIndex] != null)
                    {
                        removed++;
                        UnityEngine.Object.Destroy(__instance.previewRenderers[previewIndex].sharedMaterial);
                        __instance.previewRenderers[previewIndex].gameObject.SetActive(false);
                    }
                }
            }

            return(false);
        }
 public RoomCollision(Room room, ColliderPool pool)
 {
     this.room = room;
     this.pool = pool;
 }
Exemplo n.º 12
0
        public static bool PlayerAction_Build_DetermineBuildPreviews_Prefix(ref PlayerAction_Build __instance)
        {
            if (__instance.controller.cmd.mode != 1 ||
                __instance.player.planetData.type == EPlanetType.Gas ||
                !__instance.cursorValid ||
                __instance.groundSnappedPos == Vector3.zero ||
                (__instance.handPrefabDesc != null && __instance.handPrefabDesc.minerType != EMinerType.None)
                )
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            __instance.waitConfirm        = __instance.cursorValid;
            __instance.multiLevelCovering = false;
            if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.multiLevel)
            {
                int objectProtoId = __instance.GetObjectProtoId(__instance.castObjId);
                if (objectProtoId == __instance.handItem.ID)
                {
                    __instance.multiLevelCovering = true;
                }
            }

            if (!IsMultiBuildRunning() && (__instance.multiLevelCovering || !BlueprintManager.hasData))
            {
                if (!lastRunOriginal)
                {
                    __instance.ClearBuildPreviews();
                }
                lastRunOriginal = true;
                return(true);
            }

            // full hijacking of DetermineBuildPreviews

            if (VFInput._switchSplitter.onDown)
            {
                __instance.modelOffset++;
                forceRecalculation = true;
            }

            if (VFInput._rotate.onDown)
            {
                __instance.yaw    += 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }
            if (VFInput._counterRotate.onDown)
            {
                __instance.yaw    -= 90f;
                __instance.yaw     = Mathf.Repeat(__instance.yaw, 360f);
                __instance.yaw     = Mathf.Round(__instance.yaw / 90f) * 90f;
                forceRecalculation = true;
            }

            __instance.yaw = Mathf.Round(__instance.yaw / 90f) * 90f;
            __instance.previewPose.position = Vector3.zero;
            __instance.previewPose.rotation = Quaternion.identity;

            if (lastPosition == __instance.groundSnappedPos && !forceRecalculation)
            {
                // no update necessary
                runUpdate       = false;
                lastRunOriginal = false;
                return(false);
            }
            lastPosition       = __instance.groundSnappedPos;
            forceRecalculation = false;

            if (lastRunOriginal)
            {
                __instance.ClearBuildPreviews();
            }
            BlueprintManager.PreparePaste();
            if (IsMultiBuildRunning())
            {
                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.Add(new BuildingCopy()
                    {
                        originalId = 0,
                        itemProto  = __instance.handItem,
                        recipeId   = __instance.copyRecipeId,
                        modelIndex = __instance.handPrefabDesc.modelIndex
                    });
                }
                var building = BlueprintManager.data.copiedBuildings[0];// BlueprintManager.data.copiedBuildings.First();

                int snapPath = path;

                var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                var        desc            = BlueprintManager.GetPrefabDesc(building);
                var        pastedPositions = new List <Vector3>();
                Collider[] colliders       = new Collider[desc.buildColliders.Length];

                var copiesCounter = 0;
                for (int s = 0; s < snappedPointCount; s++)
                {
                    var pos = snaps[s];
                    var rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);

                    if (s > 0)
                    {
                        var sqrDistance = (pastedPositions.Last() - pos).sqrMagnitude;

                        // power towers
                        if (desc.isPowerNode && !desc.isAccumulator && sqrDistance < 12.25f)
                        {
                            continue;
                        }

                        // wind turbines
                        if (desc.windForcedPower && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // ray receivers
                        if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        // logistic stations
                        if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                        {
                            continue;
                        }

                        // ejector
                        if (desc.isEjector && sqrDistance < 110.25f)
                        {
                            continue;
                        }

                        if (desc.hasBuildCollider)
                        {
                            var foundCollision = false;
                            for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                            {
                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                            }

                            if (foundCollision)
                            {
                                continue;
                            }
                        }
                    }


                    if (s > 0 && spacingStore[spacingIndex] > 0 && copiesCounter % spacingPeriod == 0)
                    {
                        s += spacingStore[spacingIndex];
                        if (s >= snappedPointCount)
                        {
                            break;
                        }
                        pos = snaps[s];
                        rot = Maths.SphericalRotation(snaps[s], __instance.yaw + building.cursorRelativeYaw);
                    }

                    BlueprintManager.Paste(pos, __instance.yaw, false, pastedPositions.Count);
                    pastedPositions.Add(pos);

                    if (desc.hasBuildCollider)
                    {
                        for (var j = 0; j < desc.buildColliders.Length; j++)
                        {
                            // create temporary collider entities for the latest 'positioned' building
                            if (colliders[j] != null)
                            {
                                ColliderPool.PutCollider(colliders[j]);
                            }

                            var colliderData = desc.buildColliders[j];
                            colliderData.pos = pos + rot * colliderData.pos;
                            colliderData.q   = rot * colliderData.q;
                            colliders[j]     = ColliderPool.TakeCollider(colliderData);
                            colliders[j].gameObject.layer = 27;
                        }
                    }
                }
                if (multiBuildInserters)
                {
                    for (var i = 0; i < pastedPositions.Count; i++)
                    {
                        BlueprintManager.PasteInsertersOnly(pastedPositions[i], __instance.yaw, i, true);
                    }
                }

                if (!BlueprintManager.hasData)
                {
                    BlueprintManager.data.copiedBuildings.RemoveAt(0);
                }
                foreach (var collider in colliders)
                {
                    if (collider != null)
                    {
                        ColliderPool.PutCollider(collider);
                    }
                }
            }
            else
            {
                var pasteInserters = multiBuildInserters || (BlueprintManager.data.copiedBuildings.Count + BlueprintManager.data.copiedBelts.Count > 1);
                BlueprintManager.Paste(__instance.groundSnappedPos, __instance.yaw, pasteInserters);
            }
            BlueprintManager.AfterPaste();

            lastRunOriginal = false;
            return(false);
        }
Exemplo n.º 13
0
        public static bool DetermineBuildPreviews_Prefix(ref PlayerAction_Build __instance)
        {
            var runOriginal = true;

            if (__instance.controller.cmd.mode == 1 && __instance.player.planetData.type != EPlanetType.Gas && __instance.cursorValid)
            {
                if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.minerType != EMinerType.None)
                {
                    return(true);
                }
                __instance.waitConfirm        = __instance.cursorValid;
                __instance.multiLevelCovering = false;
                if (__instance.handPrefabDesc != null && __instance.handPrefabDesc.multiLevel)
                {
                    int objectProtoId = __instance.GetObjectProtoId(__instance.castObjId);
                    if (objectProtoId == __instance.handItem.ID)
                    {
                        __instance.multiLevelCovering = true;
                    }
                }
                if (__instance.multiLevelCovering && !MultiBuild.IsMultiBuildRunning())
                {
                    return(true);
                }

                // full hijacking of DetermineBuildPreviews
                runOriginal = false;

                if (VFInput._switchSplitter.onDown)
                {
                    __instance.modelOffset++;
                }

                if (VFInput._rotate.onDown)
                {
                    __instance.yaw += 90f;
                    __instance.yaw  = Mathf.Repeat(__instance.yaw, 360f);
                    __instance.yaw  = Mathf.Round(__instance.yaw / 90f) * 90f;
                }
                if (VFInput._counterRotate.onDown)
                {
                    __instance.yaw -= 90f;
                    __instance.yaw  = Mathf.Repeat(__instance.yaw, 360f);
                    __instance.yaw  = Mathf.Round(__instance.yaw / 90f) * 90f;
                }
                __instance.yaw = Mathf.Round(__instance.yaw / 90f) * 90f;

                /*__instance.previewPose.position = Vector3.zero;
                 * __instance.previewPose.rotation = Quaternion.identity;*/

                __instance.previewPose.position = __instance.cursorTarget;
                __instance.previewPose.rotation = Maths.SphericalRotation(__instance.previewPose.position, __instance.yaw);

                var inversePreviewRot = Quaternion.Inverse(__instance.previewPose.rotation);
                if (copiedAssemblers.Count == 0)
                {
                    copiedAssemblers.Add(0, new AssemblerCopy()
                    {
                        itemProto = __instance.handItem,

                        recipeId = __instance.copyRecipeId
                    });
                }

                var previews = new List <BuildPreview>();

                if (lastPosition == __instance.groundSnappedPos)
                {
                    return(false);
                }
                lastPosition = __instance.groundSnappedPos;
                if (copiedAssemblers.Count == 1 && MultiBuild.IsMultiBuildRunning())
                {
                    int       snapPath = path;
                    Vector3[] snaps    = new Vector3[1024];

                    var snappedPointCount = __instance.planetAux.SnapLineNonAlloc(MultiBuild.startPos, __instance.groundSnappedPos, ref snapPath, snaps);

                    var        desc        = copiedAssemblers[0].itemProto.prefabDesc;
                    Collider[] colliders   = new Collider[desc.buildColliders.Length];
                    Vector3    previousPos = Vector3.zero;

                    var usedSnaps = new List <Vector3>(10);

                    var maxSnaps = Math.Max(1, snappedPointCount - MultiBuild.spacingStore[MultiBuild.spacingIndex]);

                    for (int s = 0; s < maxSnaps; s++)
                    {
                        var pos = snaps[s];
                        var rot = Maths.SphericalRotation(snaps[s], __instance.yaw);

                        if (s > 0)
                        {
                            var sqrDistance = (previousPos - pos).sqrMagnitude;

                            // power towers
                            if (desc.isPowerNode && !desc.isAccumulator && sqrDistance < 12.25f)
                            {
                                continue;
                            }

                            // wind turbines
                            if (desc.windForcedPower && sqrDistance < 110.25f)
                            {
                                continue;
                            }

                            // ray receivers
                            if (desc.gammaRayReceiver && sqrDistance < 110.25f)
                            {
                                continue;
                            }

                            // logistic stations
                            if (desc.isStation && sqrDistance < (desc.isStellarStation ? 841f : 225f))
                            {
                                continue;
                            }

                            // ejector
                            if (desc.isEjector && sqrDistance < 110.25f)
                            {
                                continue;
                            }

                            if (desc.hasBuildCollider)
                            {
                                var foundCollision = false;
                                for (var j = 0; j < desc.buildColliders.Length && !foundCollision; j++)
                                {
                                    var colliderData = desc.buildColliders[j];
                                    colliderData.pos = pos + rot * colliderData.pos;
                                    colliderData.q   = rot * colliderData.q;
                                    // check only collision with layer 27 (the layer used by the our own building colliders for the previously 'placed' building)
                                    foundCollision = Physics.CheckBox(colliderData.pos, colliderData.ext, colliderData.q, 134217728, QueryTriggerInteraction.Collide);
                                }

                                if (foundCollision)
                                {
                                    continue;
                                }
                            }
                        }

                        if (s > 0 && MultiBuild.spacingStore[MultiBuild.spacingIndex] > 0)
                        {
                            s  += MultiBuild.spacingStore[MultiBuild.spacingIndex];
                            pos = snaps[s];
                            rot = Maths.SphericalRotation(snaps[s], __instance.yaw);
                        }

                        previousPos = pos;
                        usedSnaps.Add(pos);

                        var bp = BuildPreview.CreateSingle(copiedAssemblers[0].itemProto, copiedAssemblers[0].itemProto.prefabDesc, true);
                        bp.ResetInfos();
                        bp.desc     = copiedAssemblers[0].itemProto.prefabDesc;
                        bp.item     = copiedAssemblers[0].itemProto;
                        bp.lpos     = inversePreviewRot * (pos - __instance.previewPose.position);
                        bp.lrot     = inversePreviewRot * rot;
                        bp.recipeId = copiedAssemblers[0].recipeId;

                        //pose.position - this.previewPose.position =  this.previewPose.rotation * buildPreview.lpos;
                        //pose.rotation = this.previewPose.rotation * buildPreview.lrot;
                        if (desc.hasBuildCollider)
                        {
                            for (var j = 0; j < desc.buildColliders.Length; j++)
                            {
                                // create temporary collider entities for the latest 'positioned' building
                                if (colliders[j] != null)
                                {
                                    ColliderPool.PutCollider(colliders[j]);
                                }

                                var colliderData = desc.buildColliders[j];
                                colliderData.pos = pos + rot * colliderData.pos;
                                colliderData.q   = rot * colliderData.q;
                                colliders[j]     = ColliderPool.TakeCollider(colliderData);
                                colliders[j].gameObject.layer = 27;
                            }
                        }

                        previews.Add(bp);
                    }

                    foreach (var collider in colliders)
                    {
                        if (collider != null)
                        {
                            ColliderPool.PutCollider(collider);
                        }
                    }

                    ActivateColliders(ref __instance.nearcdLogic, usedSnaps);
                }
                else
                {
                    foreach (var copiedAssembler in copiedAssemblers.Values)
                    {
                        var absoluteBuildingRot = Maths.SphericalRotation(__instance.groundSnappedPos, __instance.yaw);
                        var absolutePosition    = __instance.planetAux.Snap(__instance.groundSnappedPos + absoluteBuildingRot * copiedAssembler.cursorRelativePos, true, true);

                        if (copiedAssembler.snapCount > 0)
                        {
                            absolutePosition = __instance.groundSnappedPos;
                            // Note: rotates each move relative to the rotation of the new building
                            for (int u = 0; u < copiedAssembler.snapCount; u++)
                            {
                                absolutePosition = __instance.planetAux.Snap(absolutePosition + absoluteBuildingRot * copiedAssembler.snapMoves[u], true, false);
                            }
                        }

                        BuildPreview bp = BuildPreview.CreateSingle(copiedAssembler.itemProto, copiedAssembler.itemProto.prefabDesc, true);
                        bp.ResetInfos();
                        bp.desc     = copiedAssembler.itemProto.prefabDesc;
                        bp.item     = copiedAssembler.itemProto;
                        bp.recipeId = copiedAssembler.recipeId;
                        bp.lpos     = inversePreviewRot * (absolutePosition - __instance.previewPose.position);
                        bp.lrot     = inversePreviewRot * Maths.SphericalRotation(absolutePosition, __instance.yaw + copiedAssembler.cursorRelativeYaw);

                        previews.Add(bp);
                    }
                }

                for (var i = 0; i < previews.Count; i++)
                {
                    if (i >= __instance.buildPreviews.Count)
                    {
                        __instance.AddBuildPreview(previews[i]);
                    }
                    else
                    {
                        var original = __instance.buildPreviews[i];
                        var updated  = previews[i];
                        if (original.desc != updated.desc || original.item != updated.item)
                        {
                            original.ResetInfos();
                            original.desc = updated.desc;
                            original.item = updated.item;
                        }
                        original.recipeId  = updated.recipeId;
                        original.filterId  = updated.filterId;
                        original.condition = EBuildCondition.Ok;

                        original.lpos = updated.lpos;
                        original.lrot = updated.lrot;

                        original.lpos2 = updated.lpos2;
                        original.lrot2 = updated.lrot2;
                    }
                }

                if (__instance.buildPreviews.Count > previews.Count)
                {
                    var toRemove = __instance.buildPreviews.Count - previews.Count;

                    for (var i = 0; i < toRemove; i++)
                    {
                        __instance.RemoveBuildPreview(previews.Count);
                    }
                }
            }



            return(runOriginal);
        }