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 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); }