public static void PasteBuilding(int index, BuildingCopy building, Vector2 targetSpr, float yaw) { Vector2 newRelative = building.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, building.originalSegmentCount); Vector2 sprPos = newRelative + targetSpr; float rawLatitudeIndex = (sprPos.x - Mathf.PI / 2) / 6.2831855f * 200; int latitudeIndex = Mathf.FloorToInt(Mathf.Max(0f, Mathf.Abs(rawLatitudeIndex) - 0.1f)); int newSegmentCount = PlanetGrid.DetermineLongitudeSegmentCount(latitudeIndex, 200); float sizeDeviation = building.originalSegmentCount / (float)newSegmentCount; sprPos = new Vector2(newRelative.x, newRelative.y * sizeDeviation) + targetSpr; Vector3 absoluteBuildingPos = sprPos.SnapToGrid(); Quaternion absoluteBuildingRot = Maths.SphericalRotation(absoluteBuildingPos, yaw + building.cursorRelativeYaw); PrefabDesc desc = GetPrefabDesc(building); BuildPreview bp = BuildPreview.CreateSingle(building.itemProto, desc, true); bp.ResetInfos(); bp.desc = desc; bp.item = building.itemProto; bp.recipeId = building.recipeId; bp.lpos = absoluteBuildingPos; bp.lrot = absoluteBuildingRot; Pose pose = new Pose(absoluteBuildingPos, absoluteBuildingRot); int objId = InserterPoses.AddOverride(pose, building.itemProto); pastedEntities.Add(building.originalId, new PastedEntity() { type = EPastedType.BUILDING, index = index, sourceBuilding = building, pose = pose, objId = objId, buildPreview = bp }); ActivateColliders(absoluteBuildingPos); previews.Add(bp); }
public static PastedEntity ConcurrentPasteBuilding(int threadIndex, BuildingCopy building, Vector2 targetSpr, float yaw, int pasteIndex) { var actionBuild = _abs[threadIndex]; int pasteId = PASTE_INDEX_MULTIPLIER * pasteIndex + building.originalId; if (!BlueprintManager.pastedEntities.TryGetValue(pasteId, out PastedEntity pastedEntity)) { PrefabDesc desc = BlueprintManager.GetPrefabDesc(building); BuildPreview bp = BuildPreview.CreateSingle(building.itemProto, desc, true); bp.ResetInfos(); bp.desc = desc; bp.item = building.itemProto; bp.recipeId = building.recipeId; pastedEntity = new PastedEntity() { pasteIndex = pasteIndex, pasteId = pasteId, status = EPastedStatus.NEW, type = EPastedType.BUILDING, sourceBuilding = building, buildPreview = bp, }; BlueprintManager.pastedEntities.TryAdd(pasteId, pastedEntity); lock (actionBuild.buildPreviews) { actionBuild.buildPreviews.Add(bp); } } else { pastedEntity.status = EPastedStatus.UPDATE; } Vector2 newRelative = building.cursorRelativePos.Rotate(yaw * Mathf.Deg2Rad, building.originalSegmentCount); Vector2 sprPos = newRelative + targetSpr; int newSegmentCount = Util.GetSegmentsCount(sprPos); float sizeDeviation = building.originalSegmentCount / (float)newSegmentCount; sprPos = new Vector2(newRelative.x, newRelative.y * sizeDeviation) + targetSpr; Vector3 absoluteBuildingPos = sprPos.SnapToGrid(); Quaternion absoluteBuildingRot = Maths.SphericalRotation(absoluteBuildingPos, yaw + building.cursorRelativeYaw); absoluteBuildingPos += absoluteBuildingRot * (building.altitude * pastedEntity.buildPreview.desc.lapJoint); Pose pose = new Pose(absoluteBuildingPos, absoluteBuildingRot); pastedEntity.objId = InserterPoses.AddOverride(pose, building.itemProto); pastedEntity.pose = pose; pastedEntity.buildPreview.lpos = absoluteBuildingPos; pastedEntity.buildPreview.lrot = absoluteBuildingRot; pastedEntity.buildPreview.condition = EBuildCondition.Ok; pastedEntity.connectedEntities.Clear(); return(pastedEntity); }
public static void DetermineBuildPreviews(PlayerAction_Build _this) { if (AdvancedBuildDestruct.buildKeyUp) { AdvancedBuildDestruct.buildKeyUp = false; beginPos = _this.groundSnappedPos; begin = !begin; } _this.waitConfirm = _this.cursorValid; int path = 0; int count = 0; if (begin) { count = _this.planetAux.SnapLineNonAlloc(beginPos, _this.groundSnappedPos, ref path, snaps); } if (VFInput._tabKey.onDown) { _this.modelOffset++; } if (VFInput._rotate.onDown) { _this.yaw += 90f; _this.yaw = Mathf.Repeat(_this.yaw, 360f); _this.yaw = Mathf.Round(_this.yaw / 90f) * 90f; } if (VFInput._counterRotate.onDown) { _this.yaw -= 90f; _this.yaw = Mathf.Repeat(_this.yaw, 360f); _this.yaw = Mathf.Round(_this.yaw / 90f) * 90f; } if (_this.handPrefabDesc.minerType != EMinerType.Vein) { _this.yaw = Mathf.Round(_this.yaw / 90f) * 90f; } _this.multiLevelCovering = false; _this.previewPose.position = _this.groundSnappedPos; _this.previewPose.rotation = Maths.SphericalRotation(_this.previewPose.position, _this.yaw); _this.ClearBuildPreviews(); if (begin) { List <Vector3> posList = new List <Vector3>(); List <ColliderData> cList = new List <ColliderData>(); for (int i = 0; i < count; i++) { var desc = _this.handPrefabDesc; if (i > 0) { // 电力设备 // Debug.Log("判断电力设备"); float x = posList[posList.Count - 1].x - snaps[i].x; float y = posList[posList.Count - 1].y - snaps[i].y; float z = posList[posList.Count - 1].z - snaps[i].z; float dis = x * x + y * y + z * z; if (dis < 12.25f) { continue; } if (desc.isPowerNode && !desc.isAccumulator) { if (desc.windForcedPower && dis < 110.25f) { continue; // 风力发电机 } if (_this.handItem.ModelIndex == 73 && dis < 110.25f) { continue; // 射线接收站 } } // 物流站 // Debug.Log("判断物流站"); if (desc.isStation) { float dis2 = (desc.isStellarStation) ? 841f : 225f; if ((posList[posList.Count - 1] - snaps[i]).sqrMagnitude < dis2) { continue; } } // 发射器 // Debug.Log("判断发射器"); if (desc.isEjector) { if (dis < 110.25f) { continue; } } // 建造碰撞器 // Debug.Log("判断碰撞器"); if (desc.hasBuildCollider) { ColliderData c = desc.buildCollider; c.pos = snaps[i] + Maths.SphericalRotation(snaps[i], _this.yaw) * c.pos; c.q = Maths.SphericalRotation(snaps[i], _this.yaw) * c.q; if (_this.handItem.BuildMode == 1) { float mul = 1f; if (_this.handItem.ModelIndex == 64) { mul = 1.05f; } if (_this.handItem.ModelIndex == 54 || _this.handItem.ModelIndex == 118) { if (!CheckBox(cList[cList.Count - 1], c)) { continue; } else { if (dis < 16) { i++; } } } else if (!CheckBox(cList[cList.Count - 1], c, mul)) { // Debug.Log("因碰撞器跳过"); continue; } } } } i += AdvancedBuildDestruct.BuildExtraSpacing.Value; _this.AddBuildPreview(BuildPreview.CreateSingle(_this.handItem, _this.handPrefabDesc, true)); posList.Add(snaps[i]); if (desc.hasBuildCollider) { ColliderData c = desc.buildCollider; c.pos = snaps[i] + Maths.SphericalRotation(snaps[i], _this.yaw) * c.pos; c.q = Maths.SphericalRotation(snaps[i], _this.yaw) * c.q; cList.Add(c); } } for (int i = 0; i < _this.buildPreviews.Count; i++) { BuildPreview buildPreview = _this.buildPreviews[i]; buildPreview.ResetInfos(); buildPreview.item = _this.handItem; buildPreview.desc = _this.handPrefabDesc; buildPreview.recipeId = _this.copyRecipeId; buildPreview.filterId = _this.copyFilterId; buildPreview.lpos = posList[i]; buildPreview.lrot = Maths.SphericalRotation(posList[i], _this.yaw); } } else { _this.AddBuildPreview(BuildPreview.CreateSingle(_this.handItem, _this.handPrefabDesc, true)); BuildPreview buildPreview = _this.buildPreviews[0]; buildPreview.ResetInfos(); buildPreview.item = _this.handItem; buildPreview.desc = _this.handPrefabDesc; buildPreview.recipeId = _this.copyRecipeId; buildPreview.filterId = _this.copyFilterId; } }
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); }