public static void PlayerAction_BuildDetermineBuildPreviewsPostfix(PlayerAction_Build __instance) { // Do we have cached inserters? var ci = PatchCopyInserters.cachedInserters; if (CopyInserters.copyEnabled && ci.Count > 0) { var bpCount = __instance.buildPreviews.Count; for (int i = 0; i < bpCount; i++) { BuildPreview buildingPreview = __instance.buildPreviews[i]; if (!buildingPreview.item.prefabDesc.isInserter) { foreach (var inserter in ci) { var bp = BuildPreview.CreateSingle(LDB.items.Select(inserter.protoId), LDB.items.Select(inserter.protoId).prefabDesc, true); bp.ResetInfos(); bp.lpos = buildingPreview.lpos + buildingPreview.lrot * inserter.posDelta; bp.lrot = buildingPreview.lrot * inserter.rot; bp.lpos2 = buildingPreview.lpos + buildingPreview.lrot * inserter.pos2Delta; bp.lrot2 = buildingPreview.lrot * inserter.rot2; bp.ignoreCollider = true; __instance.AddBuildPreview(bp); } } } } }
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); } }
public static void DetermineBuildPreviews_Postfix(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, NearColliderLogic ___nearcdLogic, Player ___player) { // Do we have cached inserters? var ci = cachedInserters; if (CopyInserters.copyEnabled && ci.Count > 0 && !__instance.multiLevelCovering) { var bpCount = __instance.buildPreviews.Count; for (int i = 0; i < bpCount; i++) { BuildPreview buildPreview = __instance.buildPreviews[i]; if (!buildPreview.item.prefabDesc.isInserter) { foreach (var cachedInserter in ci) { var positionData = GetPositions(__instance, ___factory, ___planetAux, ___nearcdLogic, buildPreview, cachedInserter); var bp = BuildPreview.CreateSingle(LDB.items.Select(cachedInserter.protoId), LDB.items.Select(cachedInserter.protoId).prefabDesc, true); bp.ResetInfos(); bp.lrot = buildPreview.lrot * cachedInserter.rot; bp.lrot2 = buildPreview.lrot * cachedInserter.rot2; if (buildPreview.lpos == Vector3.zero) { bp.lpos = buildPreview.lpos + buildPreview.lrot * positionData.posDelta; bp.lpos2 = buildPreview.lpos + buildPreview.lrot * positionData.pos2Delta; } else { bp.lpos = positionData.absoluteInserterPos; bp.lpos2 = positionData.absoluteInserterPos2; } if (positionData.condition == null) { positionData.condition = EBuildCondition.Ok; Vector3 lpos = positionData.absoluteInserterPos; Vector3 lpos2 = positionData.absoluteInserterPos2; Vector3 forward = lpos2 - lpos; Pose pose; pose.position = Vector3.Lerp(lpos, lpos2, 0.5f); pose.rotation = Quaternion.LookRotation(forward, lpos.normalized); var colliderData = bp.desc.buildColliders[0]; colliderData.ext = new Vector3(colliderData.ext.x, colliderData.ext.y, Vector3.Distance(lpos2, lpos) * 0.5f + colliderData.ext.z - 0.5f); if (cachedInserter.otherIsBelt) { if (cachedInserter.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;// the following is equivalent but explicitly states layers affected int mask = Convert.ToInt32(LayerMaskConstants.layer12 | LayerMaskConstants.layer16 | LayerMaskConstants.layer18); int collisionsFound = Physics.OverlapBoxNonAlloc(colliderData.pos, colliderData.ext, _tmp_cols, colliderData.q, mask, QueryTriggerInteraction.Collide); int collisionLimit = cachedInserter.otherIsBelt ? 0 : 1; if (collisionsFound > collisionLimit) { PlanetPhysics physics2 = ___player.planetData.physics; for (int j = 0; j < collisionsFound; j++) { physics2.GetColliderData(_tmp_cols[j], out ColliderData colliderData2); if (colliderData2.objId != 0) { if (colliderData2.usage == EColliderUsage.Build) { positionData.condition = EBuildCondition.Collide; } } } } } bp.condition = (EBuildCondition)positionData.condition; if (bp.condition == EBuildCondition.Ok) { if (cachedInserter.incoming) { bp.inputObjId = positionData.otherId; } else { bp.outputObjId = positionData.otherId; } } __instance.AddBuildPreview(bp); } } } SwapPositionCache(); } }
public static bool DetermineDestructPreviewsPatch(PlayerAction_Build __instance, ref NearColliderLogic ___nearcdLogic, ref PlanetFactory ___factory) { if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftControl)) { if (!VFInput.onGUI) { UICursor.SetCursor(ECursor.Delete); } } else { return(true); } if (!Utils.CheckIfInBuildDistance(__instance.cursorTarget)) { // Out of reach UnityEngine.Debug.Log("out of reach"); return(true); } List <EntityData> deleteEntitiesList = new List <EntityData>(); ItemProto itemProto = Traverse.Create(__instance).Method( "GetItemProto", __instance.castObjId).GetValue <ItemProto>(); __instance.ClearBuildPreviews(); if (VFInput.reformMinusKey.onDown) { if (__instance.reformSize >= 0) { __instance.reformSize--; } } if (VFInput.reformPlusKey.onDown) { if (__instance.reformSize < _configDisassemblingRadiusMax.Value) { __instance.reformSize++; } } // Management of the sphere delete if (Input.GetKey(KeyCode.LeftControl)) { int[] buildingIdsToDelete = new int[_maxArrayOfBuildingSize.Value]; if (itemProto != null) { ___nearcdLogic.GetBuildingsInAreaNonAlloc(__instance.castObjPos, __instance.reformSize, buildingIdsToDelete); } else { ___nearcdLogic.GetBuildingsInAreaNonAlloc(__instance.cursorTarget, __instance.reformSize, buildingIdsToDelete); } List <int> listBuildingIdsToDelete = new List <int>(); foreach (var id in buildingIdsToDelete) { if (id != 0) { listBuildingIdsToDelete.Add(id); } } foreach (var item in listBuildingIdsToDelete) { deleteEntitiesList.Add(___factory.entityPool[item]); } // Management of both if (Input.GetKey(KeyCode.LeftShift)) { if (itemProto != null) { deleteEntitiesList = Utils.GetEntitySortedByTypeAndRadius(itemProto, deleteEntitiesList, __instance.castObjPos, __instance.reformSize); } } } // Management of the Mass Item delete if (Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.LeftControl)) { __instance.previewPose.position = Vector3.zero; __instance.previewPose.rotation = Quaternion.identity; if ((uint)__instance.castObjId > 0U) { if (itemProto != null) { if ((uint)___factory.entityPool[__instance.castObjId].beltId > 0U) { CargoPath pathByBeltId = Utils.GetPathWithBeltId(___factory, ___factory.entityPool[__instance.castObjId].beltId); deleteEntitiesList = Utils.GetBeltsEntitiesByCargoPathBuildRange(___factory, pathByBeltId); } else { // deleteEntitiesList = Utils.GetEntitiesByProtoBuildRange(___factory, itemProto); return(true); } } } } foreach (var entityData in deleteEntitiesList) { __instance.AddBuildPreview(new BuildPreview()); } // Common Code for (int index = 0; index < __instance.buildPreviews.Count; ++index) { BuildPreview buildPreview = __instance.buildPreviews[index]; ItemProto itemProto2 = Traverse.Create(__instance).Method( "GetItemProto", deleteEntitiesList[index].id).GetValue <ItemProto>(); buildPreview.item = itemProto2; buildPreview.desc = itemProto2.prefabDesc; buildPreview.lpos = deleteEntitiesList[index].pos; buildPreview.lrot = deleteEntitiesList[index].rot; buildPreview.objId = deleteEntitiesList[index].id; int num = buildPreview.desc.lodCount <= 0 ? 0 : ((Object)buildPreview.desc.lodMeshes[0] != (Object)null ? 1 : 0); buildPreview.needModel = num != 0; buildPreview.isConnNode = true; if (buildPreview.desc.isInserter) { Pose pose = Traverse.Create(__instance).Method("GetObjectPose2", buildPreview.objId) .GetValue <Pose>(); buildPreview.lpos2 = pose.position; buildPreview.lrot2 = pose.rotation; } if ((buildPreview.lpos - __instance.player.position).sqrMagnitude > __instance.player.mecha.buildArea * __instance.player.mecha.buildArea) { buildPreview.condition = EBuildCondition.OutOfReach; __instance.cursorText = "目标超出范围".Translate(); __instance.cursorWarning = true; } else { buildPreview.condition = EBuildCondition.Ok; __instance.cursorText = "拆除".Translate() + buildPreview.item.name; } if (buildPreview.desc.multiLevel) { ___factory.ReadObjectConn(buildPreview.objId, 15, out bool _, out int otherObjId, out int _); if ((uint)otherObjId > 0U) { buildPreview.condition = EBuildCondition.Covered; __instance.cursorText = buildPreview.conditionText; } } } return(false); }
public static bool DestructMainLogic_Prefix(ref PlayerAction_Build __instance) { if (__instance.player.planetData.type == EPlanetType.Gas) { multiDestructPossible = false; } else { multiDestructPossible = true; } if (IsMultiDestructAvailable() && multiDestructEnabled) { if (circleGizmo == null) { circleGizmo = CircleGizmo.Create(1, __instance.groundTestPos, area); circleGizmo.fadeOutScale = circleGizmo.fadeInScale = 1.8f; circleGizmo.fadeOutTime = circleGizmo.fadeInTime = 0.15f; circleGizmo.color = DESTRUCT_GIZMO_COLOR; circleGizmo.autoRefresh = true; circleGizmo.Open(); } circleGizmo.position = __instance.groundTestPos; circleGizmo.radius = 1.2f * area; if (!VFInput.onGUI) { UICursor.SetCursor(ECursor.Delete); } __instance.ClearBuildPreviews(); int found = __instance.nearcdLogic.GetBuildingsInAreaNonAlloc(__instance.groundTestPos, area, _nearObjectIds); var ids = new HashSet <int>(); for (int x = 0; x < found; x++) { var objId = _nearObjectIds[x]; if (ids.Contains(objId)) { continue; } ids.Add(objId); ItemProto itemProto = __instance.GetItemProto(objId); PrefabDesc desc = itemProto.prefabDesc; if ( (itemProto.prefabDesc.isBelt && filter == EDestructFilter.Buildings) || (!itemProto.prefabDesc.isBelt && filter == EDestructFilter.Belts)) { continue; } Pose objectPose = __instance.GetObjectPose(objId); BuildPreview buildPreview = new BuildPreview { item = itemProto, desc = itemProto.prefabDesc, lpos = objectPose.position, lrot = objectPose.rotation, objId = objId, needModel = desc.lodCount > 0 && desc.lodMeshes[0] != null, isConnNode = true }; bool isInserter = buildPreview.desc.isInserter; if (isInserter) { Pose objectPose2 = __instance.GetObjectPose2(buildPreview.objId); buildPreview.lpos2 = objectPose2.position; buildPreview.lrot2 = objectPose2.rotation; } if (buildPreview.desc.multiLevel) { bool flag; int num; int num2; __instance.factory.ReadObjectConn(buildPreview.objId, 15, out flag, out num, out num2); if (num != 0) { _nearObjectIds[found++] = num; } } __instance.AddBuildPreview(buildPreview); } // reverse list so the building on 'top' are deleted first __instance.buildPreviews.Reverse(); __instance.DetermineMoreDestructionTargets(); __instance.UpdatePreviews(); __instance.UpdateGizmos(); if ((VFInput._buildConfirm.onDown || VFInput._buildConfirm.pressing) && __instance.buildPreviews.Count > 0) { Destruct(__instance); } return(false); } else { if (circleGizmo != null) { circleGizmo.Close(); circleGizmo = null; } return(true); } }
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 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; } }
/// <summary> /// Orignal PlayerAction_Build::DetermineDestructPreviews /// </summary> public static void CreateEntityUpgradePreview( PlayerAction_Build __instance, List <int> idList, List <EObjectType> typeList, DeterminePreviews.PreviewsFilter filter ) { if (!VFInput.onGUI) { if (__instance.upgradeLevel == 1) { UICursor.SetCursor(ECursor.Upgrade); } else if (__instance.upgradeLevel == -1) { UICursor.SetCursor(ECursor.Downgrade); } } __instance.previewPose.position = Vector3.zero; __instance.previewPose.rotation = Quaternion.identity; __instance.ClearBuildPreviews(); foreach (int entityId in idList) { ItemProto itemProto = (ItemProto)Traverse.Create(__instance).Method("GetItemProto", entityId).GetValue(); Pose objectPose = (Pose)Traverse.Create(__instance).Method("GetObjectPose", entityId).GetValue(); bool flag = false; if (itemProto != null && itemProto.Grade > 0 && itemProto.Upgrades.Length > 0) { flag = true; } if (flag && filter(itemProto) == false) { __instance.AddBuildPreview(new BuildPreview()); BuildPreview buildPreview = __instance.buildPreviews[__instance.buildPreviews.Count - 1]; buildPreview.item = itemProto; buildPreview.desc = itemProto.prefabDesc; buildPreview.lpos = objectPose.position; buildPreview.lrot = objectPose.rotation; buildPreview.objId = entityId; if (buildPreview.desc.lodCount > 0 && buildPreview.desc.lodMeshes[0] != null) { buildPreview.needModel = true; } else { buildPreview.needModel = false; } buildPreview.isConnNode = true; if (buildPreview.desc.isInserter) { Pose objectPose2 = (Pose)Traverse.Create(__instance).Method("GetObjectPose2", buildPreview.objId).GetValue(); //Oringal pose objectPose2 = __instance.GetObjectPose2(buildPreview.objId); buildPreview.lpos2 = objectPose2.position; buildPreview.lrot2 = objectPose2.rotation; } if ((double)(buildPreview.lpos - __instance.player.position).sqrMagnitude > (double)__instance.player.mecha.buildArea * (double)__instance.player.mecha.buildArea) { buildPreview.condition = EBuildCondition.OutOfReach; __instance.cursorText = "目标超出范围".Translate(); __instance.cursorWarning = true; } else { buildPreview.condition = EBuildCondition.Ok; __instance.cursorText = "升级".Translate() + buildPreview.item.name + "\r\n" + "连锁升级提示".Translate(); } } } }
/// <summary> /// Orignal PlayerAction_Build::DetermineDestructPreviews /// </summary> public static void CreateEntityDestructPreview( PlayerAction_Build __instance, List <int> idList, List <EObjectType> typeList, DeterminePreviews.PreviewsFilter filter ) { if (!VFInput.onGUI) { UICursor.SetCursor(ECursor.Delete); } __instance.previewPose.position = Vector3.zero; __instance.previewPose.rotation = Quaternion.identity; __instance.ClearBuildPreviews(); foreach (int entityId in idList) { //int entityId = typeList[index] != EObjectType.Entity ? -entityIdList[index] : entityIdList[index]; ItemProto itemProto = (ItemProto)Traverse.Create(__instance).Method("GetItemProto", entityId).GetValue(); Pose objectPose = (Pose)Traverse.Create(__instance).Method("GetObjectPose", entityId).GetValue(); if (itemProto != null && filter(itemProto) == false) { //Add Build Preview __instance.AddBuildPreview(new BuildPreview()); BuildPreview buildPreview = __instance.buildPreviews[__instance.buildPreviews.Count - 1]; buildPreview.item = itemProto; buildPreview.desc = itemProto.prefabDesc; buildPreview.lpos = objectPose.position; buildPreview.lrot = objectPose.rotation; buildPreview.objId = entityId; int num = buildPreview.desc.lodCount <= 0 ? 0 : ((Object)buildPreview.desc.lodMeshes[0] != (Object)null ? 1 : 0); buildPreview.needModel = num != 0; buildPreview.isConnNode = true; if (buildPreview.desc.isInserter) { Pose objectPose2 = (Pose)Traverse.Create(__instance).Method("GetObjectPose2", buildPreview.objId).GetValue(); buildPreview.lpos2 = objectPose2.position; buildPreview.lrot2 = objectPose2.rotation; } PlanetData planetData = __instance.player.planetData; Vector3 vector3_1 = __instance.player.position; if (planetData.type == EPlanetType.Gas) { vector3_1 = vector3_1.normalized; Vector3 vector3_2 = vector3_1 * planetData.realRadius; } else { buildPreview.condition = EBuildCondition.Ok; __instance.cursorText = "拆除".Translate() + buildPreview.item.name + "\r\n" + "连锁拆除提示".Translate(); } if (buildPreview.desc.multiLevel) { int otherObjId; PlanetFactory factory = Traverse.Create((object)__instance).Field("factory").GetValue <PlanetFactory>(); factory.ReadObjectConn(buildPreview.objId, 15, out bool _, out otherObjId, out int _); if ((uint)otherObjId > 0U) { buildPreview.condition = EBuildCondition.Covered; __instance.cursorText = buildPreview.conditionText; } } } } }
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); }