public static PlayerAction_Build ClonePlayerAction_Build(PlayerAction_Build original) { var nearcdClone = new NearColliderLogic() { planet = original.nearcdLogic.planet, colChunks = original.nearcdLogic.colChunks, activeColHashes = new int[600], activeColHashCount = 0, colliderObjs = original.nearcdLogic.colliderObjs }; var clone = new PlayerAction_Build() { factory = original.factory, player = original.player, nearcdLogic = nearcdClone, tmpPackage = original.tmpPackage, planetAux = original.planetAux, cursorTarget = original.cursorTarget, buildPreviews = original.buildPreviews, planetPhysics = original.planetPhysics, previewPose = new Pose(Vector3.zero, Quaternion.identity), posePairs = new List <PlayerAction_Build.PosePair>(64), startSlots = new List <PlayerAction_Build.SlotPoint>(64), endSlots = new List <PlayerAction_Build.SlotPoint>(64) }; return(clone); }
public static void ActivateColliders(Vector3 center) { NearColliderLogic nearCdLogic = GameMain.data.mainPlayer.controller.actionBuild.nearcdLogic; nearCdLogic.activeColHashCount = 0; nearCdLogic.MarkActivePos(center); const float sqrAreaRadius = 4f * 4f; for (int i = 0; i < nearCdLogic.activeColHashCount; i++) { int hash = nearCdLogic.activeColHashes[i]; ColliderData[] colliderPool = nearCdLogic.colChunks[hash].colliderPool; for (int j = 1; j < nearCdLogic.colChunks[hash].cursor; j++) { var collider = colliderPool[j]; if (collider.idType != 0 && (collider.pos - center).sqrMagnitude <= sqrAreaRadius + collider.ext.sqrMagnitude && (collider.usage != EColliderUsage.Physics || collider.objType != EObjectType.Entity)) { int colliderObjId = hash << 20 | j; if (nearCdLogic.colliderObjs.ContainsKey(colliderObjId)) { nearCdLogic.colliderObjs[colliderObjId].live = true; } else { nearCdLogic.colliderObjs[colliderObjId] = new ColliderObject(colliderObjId, collider); } } } } }
public static void ActivateColliders(ref NearColliderLogic nearCdLogic, List <Vector3> snaps) { for (int s = 0; s < snaps.Count; s++) { nearCdLogic.activeColHashCount = 0; var center = snaps[s]; Vector3 vector = Vector3.Cross(center, center - GameMain.mainPlayer.position).normalized *(5f); Vector3 vector2 = Vector3.Cross(vector, center).normalized *(5f); nearCdLogic.MarkActivePos(center); nearCdLogic.MarkActivePos(center + vector); nearCdLogic.MarkActivePos(center - vector); nearCdLogic.MarkActivePos(center + vector2); nearCdLogic.MarkActivePos(center - vector2); nearCdLogic.MarkActivePos(center + vector + vector2); nearCdLogic.MarkActivePos(center - vector + vector2); nearCdLogic.MarkActivePos(center + vector - vector2); nearCdLogic.MarkActivePos(center - vector - vector2); if (nearCdLogic.activeColHashCount > 0) { for (int i = 0; i < nearCdLogic.activeColHashCount; i++) { int num2 = nearCdLogic.activeColHashes[i]; ColliderData[] colliderPool = nearCdLogic.colChunks[num2].colliderPool; for (int j = 1; j < nearCdLogic.colChunks[num2].cursor; j++) { if (colliderPool[j].idType != 0) { if ((colliderPool[j].pos - center).sqrMagnitude <= 25f * 4f + colliderPool[j].ext.sqrMagnitude) { if (colliderPool[j].usage != EColliderUsage.Physics || colliderPool[j].objType != EObjectType.Entity) { int num3 = num2 << 20 | j; if (nearCdLogic.colliderObjs.ContainsKey(num3)) { nearCdLogic.colliderObjs[num3].live = true; } else { nearCdLogic.colliderObjs[num3] = new ColliderObject(num3, colliderPool[j]); } } } } } } } } }
public void ProcessPacket(CreatePrebuildsRequest packet, NebulaConnection conn) { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); if (planet.factory == null) { Log.Warn($"planet.factory was null create new one"); planet.factory = GameMain.data.GetOrCreateFactory(planet); } PlayerAction_Build pab = GameMain.mainPlayer.controller?.actionBuild; if (pab != null) { //Make backup of values that are overwritten List <BuildPreview> tmpList = pab.buildPreviews; bool tmpConfirm = pab.waitConfirm; UnityEngine.Vector3 tmpPos = pab.previewPose.position; UnityEngine.Quaternion tmpRot = pab.previewPose.rotation; PlanetFactory tmpFactory = null; NearColliderLogic tmpNearcdLogic = null; PlanetPhysics tmpPlanetPhysics = null; float tmpBuildArea = GameMain.mainPlayer.mecha.buildArea; PlanetData tmpData = null; bool loadExternalPlanetData = GameMain.localPlanet != planet; //Load temporary planet data, since host is not there if (loadExternalPlanetData) { tmpFactory = (PlanetFactory)AccessTools.Field(typeof(PlayerAction_Build), "factory").GetValue(GameMain.mainPlayer.controller.actionBuild); tmpNearcdLogic = (NearColliderLogic)AccessTools.Field(typeof(PlayerAction_Build), "nearcdLogic").GetValue(GameMain.mainPlayer.controller.actionBuild); tmpPlanetPhysics = (PlanetPhysics)AccessTools.Field(typeof(PlayerAction_Build), "planetPhysics").GetValue(pab); tmpData = GameMain.mainPlayer.planetData; } //Create Prebuilds from incomming packet and prepare new position pab.buildPreviews = packet.GetBuildPreviews(); pab.waitConfirm = true; using (FactoryManager.EventFromServer.On()) { FactoryManager.EventFactory = planet.factory; pab.previewPose.position = new UnityEngine.Vector3(packet.PosePosition.x, packet.PosePosition.y, packet.PosePosition.z); pab.previewPose.rotation = new UnityEngine.Quaternion(packet.PoseRotation.x, packet.PoseRotation.y, packet.PoseRotation.z, packet.PoseRotation.w); //Check if some mandatory variables are missing if (planet.physics == null || planet.physics.colChunks == null) { planet.physics = new PlanetPhysics(planet); planet.physics.Init(); } if (BeltManager.GetCargoTraffic(planet.factory.cargoTraffic) == null) { planet.factory.cargoTraffic.CreateRenderingBatches(); } if (planet.aux == null) { planet.aux = new PlanetAuxData(planet); } //Set temporary Local Planet / Factory data that are needed for original methods CheckBuildConditions() and CreatePrebuilds() AccessTools.Field(typeof(PlayerAction_Build), "factory").SetValue(GameMain.mainPlayer.controller.actionBuild, planet.factory); AccessTools.Field(typeof(PlayerAction_Build), "planetPhysics").SetValue(GameMain.mainPlayer.controller.actionBuild, planet.physics); AccessTools.Field(typeof(PlayerAction_Build), "nearcdLogic").SetValue(GameMain.mainPlayer.controller.actionBuild, planet.physics.nearColliderLogic); AccessTools.Property(typeof(global::Player), "planetData").SetValue(GameMain.mainPlayer, planet, null); //Check if prebuilds can be build (collision check, height check, etc) GameMain.mainPlayer.mecha.buildArea = float.MaxValue; bool canBuild; using (FactoryManager.IgnoreBasicBuildConditionChecks.On()) { canBuild = pab.CheckBuildConditions(); canBuild &= CheckBuildingConnections(pab.buildPreviews, planet.factory.entityPool, planet.factory.prebuildPool); } if (canBuild) { FactoryManager.PacketAuthor = packet.AuthorId; pab.CreatePrebuilds(); FactoryManager.PacketAuthor = -1; } //Revert changes back to the original planet if (loadExternalPlanetData) { planet.physics.Free(); planet.physics = null; AccessTools.Property(typeof(global::Player), "planetData").SetValue(GameMain.mainPlayer, tmpData, null); AccessTools.Field(typeof(PlayerAction_Build), "planetPhysics").SetValue(GameMain.mainPlayer.controller.actionBuild, tmpPlanetPhysics); AccessTools.Field(typeof(PlayerAction_Build), "factory").SetValue(GameMain.mainPlayer.controller.actionBuild, tmpFactory); AccessTools.Field(typeof(PlayerAction_Build), "nearcdLogic").SetValue(GameMain.mainPlayer.controller.actionBuild, tmpNearcdLogic); } GameMain.mainPlayer.mecha.buildArea = tmpBuildArea; FactoryManager.EventFactory = null; } pab.buildPreviews = tmpList; pab.waitConfirm = tmpConfirm; pab.previewPose.position = tmpPos; pab.previewPose.rotation = tmpRot; } }
public static void AfterPrebuild_Postfix(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, NearColliderLogic ___nearcdLogic) { // Do we have cached inserters? var ci = cachedInserters; if (CopyInserters.copyEnabled && ci.Count > 0 && !__instance.multiLevelCovering) { foreach (var cachedInserter in ci) { var protoId = cachedInserter.protoId; var modelIndex = (short)LDB.items.Select(cachedInserter.protoId).ModelIndex; foreach (BuildPreview buildPreview in __instance.buildPreviews) { var positionData = GetPositions(__instance, ___factory, ___planetAux, ___nearcdLogic, buildPreview, cachedInserter); if (positionData.otherId != 0) { // Create inserter Prebuild data var pbdata = new PrebuildData { protoId = (short)protoId, modelIndex = modelIndex, insertOffset = positionData.insertOffset, pickOffset = positionData.pickOffset, filterId = cachedInserter.filterId, refCount = cachedInserter.refCount, pos = positionData.absoluteInserterPos, pos2 = positionData.absoluteInserterPos2, rot = positionData.absoluteInserterRot, rot2 = positionData.absoluteInserterRot2 }; // Check the player has the item in inventory, no cheating here var pc = CopyInserters.pc; var itemcount = pc.player.package.GetItemCount(protoId); // If player has none; skip this request, as we dont create prebuild ghosts, must avoid confusion if (itemcount > 0) { var qty = 1; pc.player.package.TakeTailItems(ref protoId, ref qty); int pbCursor = ___factory.AddPrebuildDataWithComponents(pbdata); // Add the inserter request to Prebuild pool if (cachedInserter.incoming) { ___factory.WriteObjectConn(-pbCursor, 0, true, buildPreview.objId, positionData.endSlot); // assembler connection ___factory.WriteObjectConn(-pbCursor, 1, false, positionData.otherId, positionData.startSlot); // other connection } else { ___factory.WriteObjectConn(-pbCursor, 0, false, buildPreview.objId, positionData.startSlot); // assembler connection ___factory.WriteObjectConn(-pbCursor, 1, true, positionData.otherId, positionData.endSlot); // other connection } } } } } } }
private static InserterPosition GetPositions(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, NearColliderLogic ___nearcdLogic, BuildPreview buildPreview, CachedInserter cachedInserter) { Vector3 absoluteBuildingPos; Quaternion absoluteBuildingRot; // When using AdvancedBuildDestruct mod, all buildPreviews are positioned 'absolutely' on the planet surface. // In 'normal' mode the buildPreviews are relative to __instance.previewPose. // This means that in 'normal' mode the (only) buildPreview is always positioned at {0,0,0} if (buildPreview.lpos == Vector3.zero) { absoluteBuildingPos = __instance.previewPose.position; absoluteBuildingRot = __instance.previewPose.rotation; } else { absoluteBuildingPos = buildPreview.lpos; absoluteBuildingRot = buildPreview.lrot; } InserterPosition position = null; if (currentPositionCache.Count > 0) { position = currentPositionCache.Dequeue(); } bool isCacheValid = position != null && position.cachedInserter == cachedInserter && position.absoluteBuildingPos == absoluteBuildingPos && position.absoluteBuildingRot == absoluteBuildingRot; if (isCacheValid) { nextPositionCache.Enqueue(position); return(position); } var posDelta = cachedInserter.posDelta; var pos2Delta = cachedInserter.pos2Delta; Vector3 absoluteInserterPos = absoluteBuildingPos + absoluteBuildingRot * cachedInserter.posDelta; Vector3 absoluteInserterPos2 = absoluteBuildingPos + absoluteBuildingRot * cachedInserter.pos2Delta; Quaternion absoluteInserterRot = absoluteBuildingRot * cachedInserter.rot; Quaternion absoluteInserterRot2 = absoluteBuildingRot * cachedInserter.rot2; int startSlot = cachedInserter.startSlot; int endSlot = cachedInserter.endSlot; short pickOffset = cachedInserter.pickOffset; short insertOffset = cachedInserter.insertOffset; // Find the desired belt/building position // As delta doesn't work over distance, re-trace the Grid Snapped steps from the original // to find the target belt/building for this inserters other connection var testPos = absoluteBuildingPos; // Note: rotates each move relative to the rotation of the new building for (int u = 0; u < cachedInserter.snapCount; u++) { testPos = ___planetAux.Snap(testPos + absoluteBuildingRot * cachedInserter.snapMoves[u], true, false); } // Find the other entity at the target location int otherId = 0; // find building nearby int found = ___nearcdLogic.GetBuildingsInAreaNonAlloc(testPos, 0.2f, _nearObjectIds); // find nearest building float maxDistance = 0.2f; for (int x = 0; x < found; x++) { var id = _nearObjectIds[x]; float distance; ItemProto proto; if (id == 0 || id == buildPreview.objId) { continue; } else if (id > 0) { EntityData entityData = ___factory.entityPool[id]; proto = LDB.items.Select((int)entityData.protoId); distance = Vector3.Distance(entityData.pos, testPos); } else { PrebuildData prebuildData = ___factory.prebuildPool[-id]; proto = LDB.items.Select((int)prebuildData.protoId); if (proto.prefabDesc.isBelt) { // ignore unbuilt belts continue; } distance = Vector3.Distance(prebuildData.pos, testPos); } // ignore entitites that ore not (built) belts or don't have inserterPoses if ((proto.prefabDesc.isBelt == cachedInserter.otherIsBelt || proto.prefabDesc.insertPoses.Length > 0) && distance < maxDistance) { otherId = id; maxDistance = distance; } } if (otherId != 0) { var buildingId = buildPreview.objId; if (buildingId == 0) { // the original calculatePose code doesn't correctly handle calculation where one of the entity is a BuildPreview // as it has objId 0 and is not registered in either the entityPool or prebuildPool // To address that we override the 4 critical methods GetObjectPose/GetObjectProtoId/ObjectIsBelt/GetLocalInserts // only for this specific execution of CalculatePose, by returning the expected value for the current buildPreview overridePoseMethods = true; overriddenProto = buildPreview.item; overriddenPose = new Pose(absoluteBuildingPos, absoluteBuildingRot); } if (cachedInserter.incoming) { CalculatePose(__instance, otherId, buildingId); } else { CalculatePose(__instance, buildingId, otherId); } overridePoseMethods = false; bool hasNearbyPose = false; if (__instance.posePairs.Count > 0) { float minDistance = 1000f; PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair(); for (int j = 0; j < __instance.posePairs.Count; ++j) { var posePair = __instance.posePairs[j]; if ( (cachedInserter.incoming && cachedInserter.endSlot != posePair.endSlot) || (!cachedInserter.incoming && cachedInserter.startSlot != posePair.startSlot) ) { continue; } float startDistance = Vector3.Distance(posePair.startPose.position, absoluteInserterPos); float endDistance = Vector3.Distance(posePair.endPose.position, absoluteInserterPos2); float poseDistance = startDistance + endDistance; if (poseDistance < minDistance) { minDistance = poseDistance; bestFit = posePair; hasNearbyPose = true; } } if (hasNearbyPose) { // if we were able to calculate a close enough sensible pose // use that instead of the (visually) imprecise default absoluteInserterPos = bestFit.startPose.position; absoluteInserterPos2 = bestFit.endPose.position; absoluteInserterRot = bestFit.startPose.rotation; absoluteInserterRot2 = bestFit.endPose.rotation * Quaternion.Euler(0.0f, 180f, 0.0f); pickOffset = (short)bestFit.startOffset; insertOffset = (short)bestFit.endOffset; startSlot = bestFit.startSlot; endSlot = bestFit.endSlot; posDelta = Quaternion.Inverse(absoluteBuildingRot) * (absoluteInserterPos - absoluteBuildingPos); pos2Delta = Quaternion.Inverse(absoluteBuildingRot) * (absoluteInserterPos2 - absoluteBuildingPos); } } } position = new InserterPosition() { cachedInserter = cachedInserter, absoluteBuildingPos = absoluteBuildingPos, absoluteBuildingRot = absoluteBuildingRot, otherId = otherId, posDelta = posDelta, pos2Delta = pos2Delta, absoluteInserterPos = absoluteInserterPos, absoluteInserterPos2 = absoluteInserterPos2, absoluteInserterRot = absoluteInserterRot, absoluteInserterRot2 = absoluteInserterRot2, pickOffset = pickOffset, insertOffset = insertOffset, startSlot = startSlot, endSlot = endSlot, }; nextPositionCache.Enqueue(position); return(position); }
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 void FlattenTerrainReformALT(this PlanetFactory planetFactory, Vector3 center, float radius, int reformSize, bool veinBuried, float localRadius, float realRadius, float fade0 = 3f) { if (planetFactory.tmp_ids == null) { planetFactory.tmp_ids = new int[1024]; } if (planetFactory.tmp_entity_ids == null) { planetFactory.tmp_entity_ids = new int[1024]; } Array.Clear(planetFactory.tmp_ids, 0, planetFactory.tmp_ids.Length); Array.Clear(planetFactory.tmp_entity_ids, 0, planetFactory.tmp_entity_ids.Length); Vector3 zero = Vector3.zero; PlanetRawData data = planetFactory.planet.data; ushort[] heightData = data.heightData; float f = ((float)(int)heightData[data.QueryIndex(center)] - realRadius * 100f + 20f) * 0.01f * 2f; //f = Mathf.Min(9f, Mathf.Abs(f)); f = Mathf.Min(5f, Mathf.Abs(f)); fade0 += f; float areaRadius = radius + fade0; short num = (short)(realRadius * 100f + 20f); bool levelized = planetFactory.planet.levelized; int num2 = Mathf.RoundToInt((center.magnitude - 0.2f - realRadius) / 1.33333325f); int num3 = num2 * 133 + num - 60; float num4 = localRadius * 100f - 20f; foreach (KeyValuePair <int, int> tmp_levelChange in planetFactory.tmp_levelChanges) { /* * if (tmp_levelChange.Value <= 0) * { * continue; * } */ ushort num5 = heightData[tmp_levelChange.Key]; if (levelized) { if (num5 >= num3) { if (data.GetModLevel(tmp_levelChange.Key) < 3) { data.SetModPlane(tmp_levelChange.Key, num2); } planetFactory.planet.AddHeightMapModLevel(tmp_levelChange.Key, tmp_levelChange.Value); } } else { Debug.Log("AddHeightMapModLevel: " + tmp_levelChange.Key + ", " + tmp_levelChange.Value); planetFactory.planet.AddHeightMapModLevelALT(tmp_levelChange.Key, tmp_levelChange.Value); } if ((float)(int)num5 < num4) { planetFactory.planet.landPercentDirty = true; } } if (planetFactory.planet.UpdateDirtyMeshes()) { planetFactory.RenderLocalPlanetHeightmap(); } radius -= (float)reformSize * 0.15f; NearColliderLogic nearColliderLogic = planetFactory.planet.physics.nearColliderLogic; int vegetablesInAreaNonAlloc = nearColliderLogic.GetVegetablesInAreaNonAlloc(center, areaRadius, planetFactory.tmp_ids); float num6 = radius * radius; for (int i = 0; i < vegetablesInAreaNonAlloc; i++) { int num7 = planetFactory.tmp_ids[i]; zero = planetFactory.vegePool[num7].pos; zero -= center; if (zero.x * zero.x + zero.y * zero.y + zero.z * zero.z <= num6 + 2.2f) { planetFactory.RemoveVegeWithComponents(num7); continue; } float num8 = data.QueryModifiedHeight(planetFactory.vegePool[num7].pos) - 0.03f; planetFactory.vegePool[num7].pos = planetFactory.vegePool[num7].pos.normalized * num8; GameMain.gpuiManager.AlterModel(planetFactory.vegePool[num7].modelIndex, planetFactory.vegePool[num7].modelId, num7, planetFactory.vegePool[num7].pos, planetFactory.vegePool[num7].rot, setBuffer: false); } float num9 = 50f; vegetablesInAreaNonAlloc = ((!veinBuried) ? nearColliderLogic.GetVeinsInOceanInAreaNonAlloc(center, areaRadius, planetFactory.tmp_ids) : nearColliderLogic.GetVeinsInAreaNonAlloc(center, areaRadius, planetFactory.tmp_ids)); for (int j = 0; j < vegetablesInAreaNonAlloc; j++) { int num10 = planetFactory.tmp_ids[j]; zero = planetFactory.veinPool[num10].pos; float num11 = realRadius + 0.2f; Vector3 vector = zero.normalized * num11 - center; if (!(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z <= num6 + 2f)) { continue; } PlanetPhysics physics = planetFactory.planet.physics; int colliderId = planetFactory.veinPool[num10].colliderId; ColliderData colliderData = physics.GetColliderData(colliderId); if (veinBuried) { num11 -= num9; } else { Vector3 center2 = zero.normalized * num11; int entitiesInAreaWhenReformNonAlloc = nearColliderLogic.GetEntitiesInAreaWhenReformNonAlloc(center2, colliderData.radius, planetFactory.tmp_entity_ids); if (entitiesInAreaWhenReformNonAlloc > 0) { num11 = zero.magnitude; } } Vector3 pos = colliderData.pos.normalized * num11; int num12 = colliderId >> 20; colliderId &= 0xFFFFF; physics.colChunks[num12].colliderPool[colliderId].pos = pos; planetFactory.veinPool[num10].pos = zero.normalized * num11; physics.RefreshColliders(); GameMain.gpuiManager.AlterModel(planetFactory.veinPool[num10].modelIndex, planetFactory.veinPool[num10].modelId, num10, planetFactory.veinPool[num10].pos, setBuffer: false); } planetFactory.tmp_levelChanges.Clear(); Array.Clear(planetFactory.tmp_ids, 0, planetFactory.tmp_ids.Length); Array.Clear(planetFactory.tmp_ids, 0, planetFactory.tmp_entity_ids.Length); GameMain.gpuiManager.SyncAllGPUBuffer(); }
public static void FlattenTerrainReform(PlanetFactory factory, List <Vector3> points, Vector3 center) { if (factory.tmp_ids == null) { factory.tmp_ids = new int[1024]; } if (factory.tmp_entity_ids == null) { factory.tmp_entity_ids = new int[1024]; } Array.Clear(factory.tmp_ids, 0, factory.tmp_ids.Length); Array.Clear(factory.tmp_entity_ids, 0, factory.tmp_entity_ids.Length); PlanetRawData data = factory.planet.data; ushort[] heightData = data.heightData; short h = (short)(factory.planet.realRadius * 100f + 20f); bool levelized = factory.planet.levelized; int step = Mathf.RoundToInt((center.magnitude - 0.2f - factory.planet.realRadius) / 1.3333333f); int heightT = step * 133 + h - 60; float heightT2 = factory.planet.radius * 100f - 20f; foreach (KeyValuePair <int, int> keyValuePair in tmpLevelChanges) { if (keyValuePair.Value > 0) { ushort height = heightData[keyValuePair.Key]; if (levelized) { if (height >= heightT) { if (data.GetModLevel(keyValuePair.Key) < 3) { data.SetModPlane(keyValuePair.Key, step); } factory.planet.AddHeightMapModLevel(keyValuePair.Key, keyValuePair.Value); } } else { factory.planet.AddHeightMapModLevel(keyValuePair.Key, keyValuePair.Value); } if (height < heightT2) { factory.planet.landPercentDirty = true; } } } if (factory.planet.UpdateDirtyMeshes()) { factory.RenderLocalPlanetHeightmap(); } foreach (Vector3 point in points) { NearColliderLogic nearColliderLogic = factory.planet.physics.nearColliderLogic; int num7 = nearColliderLogic.GetVegetablesInAreaNonAlloc(point, 1, factory.tmp_ids); for (int i = 0; i < num7; i++) { int id = factory.tmp_ids[i]; Vector3 position = factory.vegePool[id].pos; position -= point; if (position.sqrMagnitude <= 9f) { factory.RemoveVegeWithComponents(id); } else { float d = data.QueryModifiedHeight(factory.vegePool[id].pos) - 0.03f; factory.vegePool[id].pos = factory.vegePool[id].pos.normalized * d; GameMain.gpuiManager.AlterModel(factory.vegePool[id].modelIndex, factory.vegePool[id].modelId, id, factory.vegePool[id].pos, factory.vegePool[id].rot, false); } } } tmpLevelChanges.Clear(); Array.Clear(factory.tmp_ids, 0, factory.tmp_ids.Length); Array.Clear(factory.tmp_ids, 0, factory.tmp_entity_ids.Length); GameMain.gpuiManager.SyncAllGPUBuffer(); }
public static void CreatePrebuildsRequest(CreatePrebuildsRequest packet) { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); if (planet.factory == null) { if (FactoryManager.EventFromServer) { // We only execute the code if the client has loaded the factory at least once. // Else it will get it once it goes to the planet for the first time. return; } Log.Warn($"planet.factory was null create new one"); planet.factory = GameMain.data.GetOrCreateFactory(planet); } PlayerAction_Build pab = GameMain.mainPlayer.controller != null ? GameMain.mainPlayer.controller.actionBuild : null; BuildTool[] buildTools = pab.tools; BuildTool buildTool = null; for (int i = 0; i < buildTools.Length; i++) { if (buildTools[i].GetType().ToString() == packet.BuildToolType) { buildTool = buildTools[i]; break; } } if (pab != null && buildTool != null) { FactoryManager.TargetPlanet = packet.PlanetId; FactoryManager.PacketAuthor = packet.AuthorId; PlanetFactory tmpFactory = null; NearColliderLogic tmpNearcdLogic = null; PlanetPhysics tmpPlanetPhysics = null; bool loadExternalPlanetData = GameMain.localPlanet != planet; if (loadExternalPlanetData) { //Make backup of values that are overwritten tmpFactory = buildTool.factory; tmpNearcdLogic = buildTool.actionBuild.nearcdLogic; tmpPlanetPhysics = buildTool.actionBuild.planetPhysics; } //Create Prebuilds from incoming packet and prepare new position List <BuildPreview> tmpList = new List <BuildPreview>(); tmpList.AddRange(buildTool.buildPreviews); buildTool.buildPreviews.Clear(); buildTool.buildPreviews.AddRange(packet.GetBuildPreviews()); FactoryManager.EventFactory = planet.factory; //Check if some mandatory variables are missing if (planet.physics == null || planet.physics.colChunks == null) { planet.physics = new PlanetPhysics(planet); planet.physics.Init(); } if (planet.aux == null) { planet.aux = new PlanetAuxData(planet); } //Set temporary Local Planet / Factory data that are needed for original methods CheckBuildConditions() and CreatePrebuilds() buildTool.factory = planet.factory; pab.factory = planet.factory; pab.noneTool.factory = planet.factory; if (FactoryManager.EventFromClient) { // Only the server needs to set these pab.planetPhysics = planet.physics; pab.nearcdLogic = planet.physics.nearColliderLogic; } //Check if prebuilds can be build (collision check, height check, etc) bool canBuild = false; if (FactoryManager.EventFromClient) { GameMain.mainPlayer.mecha.buildArea = float.MaxValue; canBuild = CheckBuildingConnections(buildTool.buildPreviews, planet.factory.entityPool, planet.factory.prebuildPool); } Debug.Log(buildTool.buildPreviews[0].condition); if (canBuild || FactoryManager.EventFromServer) { if (FactoryManager.EventFromClient) { CheckAndFixConnections(buildTool, planet); } if (packet.BuildToolType == typeof(BuildTool_Click).ToString()) { ((BuildTool_Click)buildTool).CreatePrebuilds(); } else if (packet.BuildToolType == typeof(BuildTool_Path).ToString()) { ((BuildTool_Path)buildTool).CreatePrebuilds(); } else if (packet.BuildToolType == typeof(BuildTool_Inserter).ToString()) { ((BuildTool_Inserter)buildTool).CreatePrebuilds(); } } //Revert changes back to the original planet if (loadExternalPlanetData) { buildTool.factory = tmpFactory; pab.factory = tmpFactory; pab.noneTool.factory = tmpFactory; if (FactoryManager.EventFromClient) { pab.planetPhysics = tmpPlanetPhysics; pab.nearcdLogic = tmpNearcdLogic; planet.physics.Free(); planet.physics = null; } } GameMain.mainPlayer.mecha.buildArea = Configs.freeMode.mechaBuildArea; FactoryManager.EventFactory = null; buildTool.buildPreviews.Clear(); buildTool.buildPreviews.AddRange(tmpList); FactoryManager.TargetPlanet = FactoryManager.PLANET_NONE; FactoryManager.PacketAuthor = -1; } }
public static void CreatePrebuildsRequest(CreatePrebuildsRequest packet) { PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId); if (planet.factory == null) { if (FactoryManager.IsIncomingRequest) { // We only execute the code if the client has loaded the factory at least once. // Else it will get it once it goes to the planet for the first time. return; } Log.Warn($"planet.factory was null create new one"); planet.factory = GameMain.data.GetOrCreateFactory(planet); } PlayerAction_Build pab = GameMain.mainPlayer.controller != null ? GameMain.mainPlayer.controller.actionBuild : null; BuildTool[] buildTools = pab.tools; BuildTool buildTool = null; for (int i = 0; i < buildTools.Length; i++) { if (buildTools[i].GetType().ToString() == packet.BuildToolType) { buildTool = buildTools[i]; break; } } if (pab != null && buildTool != null) { FactoryManager.TargetPlanet = packet.PlanetId; FactoryManager.PacketAuthor = packet.AuthorId; PlanetFactory tmpFactory = null; NearColliderLogic tmpNearcdLogic = null; PlanetPhysics tmpPlanetPhysics = null; bool loadExternalPlanetData = GameMain.localPlanet?.id != planet.id; if (loadExternalPlanetData) { //Make backup of values that are overwritten tmpFactory = buildTool.factory; tmpNearcdLogic = buildTool.actionBuild.nearcdLogic; tmpPlanetPhysics = buildTool.actionBuild.planetPhysics; FactoryManager.AddPlanetTimer(packet.PlanetId); } bool incomingBlueprintEvent = packet.BuildToolType == typeof(BuildTool_BlueprintPaste).ToString(); //Create Prebuilds from incoming packet and prepare new position List <BuildPreview> tmpList = new List <BuildPreview>(); if (!incomingBlueprintEvent) { tmpList.AddRange(buildTool.buildPreviews); buildTool.buildPreviews.Clear(); buildTool.buildPreviews.AddRange(packet.GetBuildPreviews()); } FactoryManager.EventFactory = planet.factory; //Set temporary Local Planet / Factory data that are needed for original methods CheckBuildConditions() and CreatePrebuilds() buildTool.factory = planet.factory; pab.factory = planet.factory; pab.noneTool.factory = planet.factory; if (FactoryManager.IsIncomingRequest) { // Only the server needs to set these pab.planetPhysics = planet.physics; pab.nearcdLogic = planet.physics.nearColliderLogic; } //Check if prebuilds can be build (collision check, height check, etc) bool canBuild = false; if (FactoryManager.IsIncomingRequest) { GameMain.mainPlayer.mecha.buildArea = float.MaxValue; canBuild = CheckBuildingConnections(buildTool.buildPreviews, planet.factory.entityPool, planet.factory.prebuildPool); } if (canBuild || FactoryManager.IsIncomingRequest) { if (FactoryManager.IsIncomingRequest) { CheckAndFixConnections(buildTool, planet); } if (packet.BuildToolType == typeof(BuildTool_Click).ToString()) { ((BuildTool_Click)buildTool).CreatePrebuilds(); } else if (packet.BuildToolType == typeof(BuildTool_Path).ToString()) { ((BuildTool_Path)buildTool).CreatePrebuilds(); } else if (packet.BuildToolType == typeof(BuildTool_Inserter).ToString()) { ((BuildTool_Inserter)buildTool).CreatePrebuilds(); } else if (incomingBlueprintEvent) { BuildTool_BlueprintPaste bpTool = buildTool as BuildTool_BlueprintPaste; // Cache the current data before performing the requested CreatePrebuilds(); int previousCursor = bpTool.bpCursor; BuildPreview[] previousPool = bpTool.bpPool; // Perform the requested CreatePrebuilds(); List <BuildPreview> incomingPreviews = packet.GetBuildPreviews(); bpTool.bpCursor = incomingPreviews.Count; bpTool.bpPool = incomingPreviews.ToArray(); bpTool.CreatePrebuilds(); // Revert to previous data bpTool.bpCursor = previousCursor; bpTool.bpPool = previousPool; } } //Revert changes back to the original planet if (loadExternalPlanetData) { buildTool.factory = tmpFactory; pab.factory = tmpFactory; pab.noneTool.factory = tmpFactory; pab.planetPhysics = tmpPlanetPhysics; pab.nearcdLogic = tmpNearcdLogic; } GameMain.mainPlayer.mecha.buildArea = Configs.freeMode.mechaBuildArea; FactoryManager.EventFactory = null; if (!incomingBlueprintEvent) { buildTool.buildPreviews.Clear(); buildTool.buildPreviews.AddRange(tmpList); } FactoryManager.TargetPlanet = FactoryManager.PLANET_NONE; FactoryManager.PacketAuthor = FactoryManager.AUTHOR_NONE; } }