public override void SetData(PlanetFactory factory, int eId) { int sId = factory.entityPool[eId].stationId; var sc = factory.transport.stationPool[sId]; int minLen = Math.Min(sc.storage.Length, storage.Length); for (int i = 0; i < minLen; i++) { sc.storage[i] = storage[i]; } //获取接口的最小长度,防止越界 minLen = Math.Min(sc.slots.Length, slots.Length); for (int i = 0; i < minLen; i++) { sc.slots[i].storageIdx = slots[i].storageIdx; sc.slots[i].counter = slots[i].counter; sc.slots[i].dir = slots[i].dir; } newEId = eId; }
/// <summary> /// 获取当前星球的物品数量 /// </summary> /// <param name="ItemId">需要寻找的物品id</param> /// <param name="factory">当前星球的工厂</param> /// <param name="player">玩家实例</param> /// <returns></returns> public static int FindItem(int ItemId, PlanetFactory factory, Player player) { if (player.package.GetItemCount(ItemId) > 0) { return(0); } for (int i = 1; i < factory.factoryStorage.storageCursor; i++) { var storage = factory.factoryStorage.storagePool[i]; if (storage != null) { if (storage.GetItemCount(ItemId) > 0) { return(i); } } } return(-1); }
public override void ProcessPacket(LaboratoryUpdateEventPacket packet, NebulaConnection conn) { PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory; LabComponent[] pool = factory?.factorySystem?.labPool; if (pool != null && packet.LabIndex != -1 && packet.LabIndex < pool.Length && pool[packet.LabIndex].id != -1) { using (Multiplayer.Session.Factories.IsIncomingRequest.On()) { Multiplayer.Session.Factories.PacketAuthor = NebulaModAPI.AUTHOR_NONE; if (packet.ProductId == -4) { pool[packet.LabIndex].forceAccMode = !pool[packet.LabIndex].forceAccMode; } else if (packet.ProductId == -3) { //Widthdraw produced cubes pool[packet.LabIndex].produced[0] = 0; } else if (packet.ProductId == -2) { //Research recipe reseted pool[packet.LabIndex].SetFunction(false, 0, 0, factory.entitySignPool); } else if (packet.ProductId == -1) { //Center chenged to research-mode pool[packet.LabIndex].SetFunction(true, 0, GameMain.data.history.currentTech, factory.entitySignPool); } else { //Cube Recipe changed int[] matrixIds = LabComponent.matrixIds; RecipeProto recipeProto = LDB.items.Select(matrixIds[packet.ProductId]).maincraft; pool[packet.LabIndex].SetFunction(false, (recipeProto == null) ? 0 : recipeProto.ID, 0, factory.entitySignPool); } factory.factorySystem?.SyncLabFunctions(GameMain.mainPlayer, packet.LabIndex); factory.factorySystem?.SyncLabForceAccMode(GameMain.mainPlayer, packet.LabIndex); } } }
public static bool ApplyInsertTargetPatch(PlanetFactory __instance, int entityId, int insertTarget, int slotId, int offset) { var _this = __instance; if (entityId == 0) { return(true); } if (insertTarget < 0) { Assert.CannotBeReached(); insertTarget = 0; } int assemblerId = _this.entityPool[entityId].assemblerId; if (assemblerId > 0 && _this.entityPool[insertTarget].assemblerId > 0) { assemblerComponentEx.SetAssemblerInsertTarget(__instance, assemblerId, insertTarget); } return(true); }
public override bool ConnPreBelt(PlanetFactory factory, Dictionary <int, MyPreBuildData> preIdMap) { Common.ReadObjectConn(conn0, out bool isOut1, out int Belt1, out int slot); Common.ReadObjectConn(conn1, out bool isOut2, out int Belt2, out int slot2); if (Belt1 == 0 || preIdMap.ContainsKey(Belt1)) { if (Belt2 == 0 || preIdMap.ContainsKey(Belt2)) { if (Belt1 > 0) { factory.WriteObjectConn(preId, 0, isOut1, preIdMap[Belt1].preId, isOut1 ? 1 : 0); } if (Belt2 > 0) { factory.WriteObjectConn(preId, 1, isOut2, preIdMap[Belt2].preId, isOut2 ? 1 : 0); } return(true); } } return(false); }
public override bool Redo(PlanetFactory factory, PlayerAction_Build actionBuild) { bool success = true; using (UndoManager.IgnoreAllEvents.On()) { foreach (UpgradeData data in targets) { if (!actionBuild.DoUpgradeObject(data.objId, data.newGrade, 0, out int error)) { success = false; if (error == 1) { BlueprintTweaksPlugin.logger.LogDebug($"Can't upgrade {data.objId} to {data.newGrade}, not enough items"); } } } } return(success); }
public static void UpdateAnimation(int PlanetId, int NetId, int NodeId, int PowerAmount) { float idkValue = 0.016666668f; PlanetFactory factory = GameMain.galaxy.PlanetById(PlanetId)?.factory; if (factory != null && factory.entityAnimPool != null && factory.powerSystem != null) { PowerNodeComponent pComp = factory.powerSystem.nodePool[NodeId]; AnimData[] animPool = factory.entityAnimPool; int entityId = pComp.entityId; if (pComp.coverRadius < 15f) { animPool[entityId].StepPoweredClamped(factory.powerSystem.networkServes[NetId], idkValue, (PowerAmount > 0) ? 2U : 1U); } else { animPool[entityId].StepPoweredClamped2(factory.powerSystem.networkServes[NetId], idkValue, (PowerAmount > 0) ? 2U : 1U); } } }
public static bool DismantleFinally_Prefix(PlanetFactory __instance, Player player, int objId, ref int protoId) { if (!SimulatedWorld.Initialized) { return(true); } // TODO: handle if 2 clients or if host and client trigger a destruct of the same object at the same time // If the object is a prebuild, remove it from the prebuild request list if (LocalPlayer.IsMasterClient && objId < 0) { if (!FactoryManager.ContainsPrebuildRequest(__instance.planetId, -objId)) { Log.Warn($"DestructFinally was called without having a corresponding PrebuildRequest for the prebuild {-objId} on the planet {__instance.planetId}"); return(false); } FactoryManager.RemovePrebuildRequest(__instance.planetId, -objId); } return(LocalPlayer.IsMasterClient || FactoryManager.EventFromServer); }
public void stationStatUpdate(StationComponent stationComponent, PlanetFactory factory) { var stationPosition = factory.entityPool[stationComponent.entityId].pos; var items = from item in stationComponent.storage where item.itemId != 0 select new StationItemStat() { item = item, itemProto = LDB.items.Select(item.itemId) }; string text = ((!string.IsNullOrEmpty(stationComponent.name)) ? stationComponent.name : ((!stationComponent.isStellar) ? ("本地站点号".Translate() + stationComponent.id) : ("星际站点号".Translate() + stationComponent.gid))); logisticsStationStats.Add(new StationStat() { planetData = factory.planet, stationComponent = stationComponent, name = text, products = items.ToList(), stationPosition = stationPosition, }); }
public static Pose[] GetLocalSlots(PlanetFactory factory, int objId) { if (objId == 0) { return(emptyPoseArr); } PrefabDesc prefabDesc; if (objId > 0) { ModelProto modelProto = LDB.models.Select(factory.entityPool[objId].modelIndex); if (modelProto == null) { return(emptyPoseArr); } prefabDesc = modelProto.prefabDesc; } else { ModelProto modelProto2 = LDB.models.Select(factory.prebuildPool[-objId].modelIndex); if (modelProto2 == null) { return(emptyPoseArr); } prefabDesc = modelProto2.prefabDesc; } if (!prefabDesc.multiLevel || prefabDesc.multiLevelAllowPortsOrSlots) { return(prefabDesc.slotPoses); } factory.ReadObjectConn(objId, 14, out var _, out var otherObjId, out var _); if (otherObjId != 0) { return(emptyPoseArr); } return(prefabDesc.slotPoses); }
public static int ComputeFlattenTerrainReform(PlanetFactory factory, List <Vector3> points, Vector3 center, float fade0 = 3f) { PlanetRawData data = factory.planet.data; tmpLevelChanges.Clear(); float realRadius = factory.planet.realRadius; ushort[] heightData = data.heightData; float heightDiff = (heightData[data.QueryIndex(center)] - factory.planet.realRadius * 100f + 20f) * 0.01f * 2f; heightDiff = Mathf.Min(9f, Mathf.Abs(heightDiff)); fade0 += heightDiff; float steps = realRadius * 3.1415927f / (factory.planet.precision * 2f); int extent = Mathf.CeilToInt(fade0 * 1.414f / steps * 1.5f + 0.5f); int cost = 0; foreach (Vector3 vpos in points) { float longitude = BlueprintUtils.GetLongitudeRad(vpos.normalized); float longCount = 2 * longitude / Mathf.PI; float angleDistance = Mathf.Abs(longCount - Mathf.Round(longCount)); if (angleDistance <= 0.04) { cost += ScanTerrainDetailed(data, realRadius, vpos, extent, fade0); } else { cost += ScanTerrain(data, realRadius, vpos, extent, fade0); } } return(cost); }
public static void RemExtraDemand(int PlanetId, int NetId, int NodeId) { if (Energy.TryGetValue(PlanetId, out var mapping)) { for (int i = 0; i < mapping.Count; i++) { if (mapping[i].NetId == NetId) { PlanetFactory factory = GameMain.galaxy.PlanetById(PlanetId).factory; PowerSystem pSystem = factory?.powerSystem; for (int j = 0; j < mapping[i].NodeId.Count; j++) { if (mapping[i].NodeId[j] == NodeId) { if (factory != null && pSystem != null) { mapping[i].ExtraPower -= pSystem.nodePool[NodeId].workEnergyPerTick; } else { mapping[i].ExtraPower -= mapping[i].ExtraPower / mapping[i].NodeId.Count; } mapping[i].Activated[j] = false; } } if (mapping[i].ExtraPower < 0) { mapping[i].ExtraPower = 0; } } } } }
public static void SetCopyInfo_Postfix(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, int objectId, int protoId) { cachedInserters.Clear(); // Remove previous copy info if (objectId < 0) // Copied item is a ghost, no inserters to cache { return; } var sourceEntityProto = LDB.items.Select(protoId); var sourceEntityId = objectId; var sourceEntity = ___factory.entityPool[sourceEntityId]; var sourcePos = sourceEntity.pos; var sourceRot = sourceEntity.rot; // Set the current build rotation to the copied building rotation Quaternion zeroRot = Maths.SphericalRotation(sourcePos, 0f); float yaw = Vector3.SignedAngle(zeroRot.Forward(), sourceRot.Forward(), zeroRot.Up()); if (sourceEntityProto.prefabDesc.minerType != EMinerType.Vein) { yaw = Mathf.Round(yaw / 90f) * 90f; } __instance.yaw = yaw; // Ignore building without inserter slots if (sourceEntityProto.prefabDesc.insertPoses.Length == 0) { return; } // Find connected inserters var inserterPool = ___factory.factorySystem.inserterPool; var entityPool = ___factory.entityPool; for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++) { if (inserterPool[i].id == i) { var inserter = inserterPool[i]; var inserterEntity = entityPool[inserter.entityId]; var pickTarget = inserter.pickTarget; var insertTarget = inserter.insertTarget; if (pickTarget == sourceEntityId || insertTarget == sourceEntityId) { ItemProto itemProto = LDB.items.Select(inserterEntity.protoId); bool incoming = insertTarget == sourceEntityId; var otherId = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to Vector3 otherPos; ItemProto otherProto; if (otherId > 0) { otherPos = entityPool[otherId].pos; otherProto = LDB.items.Select((int)___factory.entityPool[otherId].protoId); } else { otherPos = ___factory.prebuildPool[-otherId].pos; otherProto = LDB.items.Select((int)___factory.prebuildPool[-otherId].protoId); } // Store the Grid-Snapped moves from assembler to belt/other int path = 0; Vector3[] snaps = new Vector3[6]; var snappedPointCount = ___planetAux.SnapLineNonAlloc(sourcePos, otherPos, ref path, snaps); Vector3 lastSnap = sourcePos; Vector3[] snapMoves = new Vector3[snappedPointCount]; for (int s = 0; s < snappedPointCount; s++) { // note: reverse rotation of the delta so that rotation works Vector3 snapMove = Quaternion.Inverse(sourceRot) * (snaps[s] - lastSnap); snapMoves[s] = snapMove; lastSnap = snaps[s]; } bool otherIsBelt = otherProto != null && otherProto.prefabDesc.isBelt; // Cache info for this inserter CachedInserter ci = new CachedInserter { incoming = incoming, protoId = inserterEntity.protoId, // rotations + deltas relative to the source building's rotation rot = Quaternion.Inverse(sourceRot) * inserterEntity.rot, rot2 = Quaternion.Inverse(sourceRot) * inserter.rot2, posDelta = Quaternion.Inverse(sourceRot) * (inserterEntity.pos - sourcePos), // Delta from copied building to inserter pos pos2Delta = Quaternion.Inverse(sourceRot) * (inserter.pos2 - sourcePos), // Delta from copied building to inserter pos2 // store to restore inserter speed refCount = Mathf.RoundToInt((float)(inserter.stt - 0.499f) / itemProto.prefabDesc.inserterSTT), // not important? pickOffset = inserter.pickOffset, insertOffset = inserter.insertOffset, // needed for pose? t1 = inserter.t1, t2 = inserter.t2, filterId = inserter.filter, snapMoves = snapMoves, snapCount = snappedPointCount, startSlot = -1, endSlot = -1, otherIsBelt = otherIsBelt }; // compute the start and end slot that the cached inserter uses CalculatePose(__instance, pickTarget, insertTarget); if (__instance.posePairs.Count > 0) { float minDistance = 1000f; for (int j = 0; j < __instance.posePairs.Count; ++j) { var posePair = __instance.posePairs[j]; float startDistance = Vector3.Distance(posePair.startPose.position, inserterEntity.pos); float endDistance = Vector3.Distance(posePair.endPose.position, inserter.pos2); float poseDistance = startDistance + endDistance; if (poseDistance < minDistance) { minDistance = poseDistance; ci.startSlot = posePair.startSlot; ci.endSlot = posePair.endSlot; } } } cachedInserters.Add(ci); } } } }
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 void PlayerAction_BuildAfterPrebuildPostfix(PlayerAction_Build __instance, ref PlanetFactory ___factory, PlanetAuxData ___planetAux) { // Do we have cached inserters? var ci = PatchCopyInserters.cachedInserters; if (ci.Count > 0) { var targetPos = __instance.buildTargetPositionWanted; var entityPool = ___factory.entityPool; foreach (var inserter in ci) { // 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 currentPos = targetPos; for (int u = 0; u < inserter.snapCount; u++) { currentPos = ___planetAux.Snap(currentPos + inserter.snapMoves[u], true, false); } var testPos = currentPos; // Find the other entity at the target location int otherId = 0; for (int x = 1; x < ___factory.entityCursor; x++) { if (entityPool[x].id == x) { var distance = Vector3.Distance(entityPool[x].pos, testPos); if (distance < 0.2) { otherId = entityPool[x].id; break; } } } if (otherId != 0) { // Order an inserter var pi = new PatchCopyInserters.PendingInserter(); pi.otherId = otherId; pi.ci = inserter; pi.AssemblerPos = targetPos; PatchCopyInserters.pendingInserters.Add(pi); } } } }
public static void PlayerAction_BuildSetCopyInfoPostfix(ref PlanetFactory ___factory, int objectId, PlanetAuxData ___planetAux) { cachedInserters.Clear(); // Remove previous copy info var sourceEntity = objectId; var sourcePos = ___factory.entityPool[objectId].pos; var sourceRot = ___factory.entityPool[objectId].rot; // Find connected inserters int matches = 0; var inserterPool = ___factory.factorySystem.inserterPool; var entityPool = ___factory.entityPool; for (int i = 1; i < ___factory.factorySystem.inserterCursor; i++) { if (inserterPool[i].id == i) { var inserter = inserterPool[i]; var pickTarget = inserter.pickTarget; var insertTarget = inserter.insertTarget; if (pickTarget == sourceEntity || insertTarget == sourceEntity) { matches++; var inserterType = ___factory.entityPool[inserter.entityId].protoId; bool incoming = insertTarget == sourceEntity; var otherId = incoming ? pickTarget : insertTarget; // The belt or other building this inserter is attached to var otherPos = ___factory.entityPool[otherId].pos; // Store the Grid-Snapped moves from assembler to belt/other Vector3 begin = sourcePos; Vector3 end = otherPos; int path = 0; Vector3[] snaps = new Vector3[6]; var snappedPointCount = ___planetAux.SnapLineNonAlloc(begin, end, ref path, snaps); Vector3 lastSnap = begin; Vector3[] snapMoves = new Vector3[snappedPointCount]; for (int s = 0; s < snappedPointCount; s++) { Vector3 snapMove = snaps[s] - lastSnap; snapMoves[s] = snapMove; lastSnap = snaps[s]; } // Cache info for this inserter var ci = new CachedInserter(); ci.incoming = incoming; ci.protoId = inserterType; ci.rot = ___factory.entityPool[inserter.entityId].rot; ci.rot2 = inserter.rot2; ci.pos2delta = inserter.pos2; // YukkuriC: record abs pos first ci.posDelta = entityPool[inserter.entityId].pos; // YukkuriC: dump relative transforms Helper.RelTransform(sourcePos, entityPool[inserter.entityId].pos, ___factory.entityPool[inserter.entityId].rot, out ci.posDelta, out ci.rot); Helper.RelTransform(sourcePos, inserter.pos2, inserter.rot2, out ci.pos2delta, out ci.rot2); // not important? ci.pickOffset = inserter.pickOffset; ci.insertOffset = inserter.insertOffset; // needed for pose? ci.t1 = inserter.t1; ci.t2 = inserter.t2; ci.filterId = inserter.filter; ci.snapMoves = snapMoves; ci.snapCount = snappedPointCount; cachedInserters.Add(ci); } } } }
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 abstract bool Redo(PlanetFactory factory, PlayerAction_Build actionBuild);
public static InserterCopy CopyInserter(EntityData sourceEntity, EntityData referenceEntity) { PlanetFactory factory = GameMain.data.localPlanet.factory; PlayerAction_Build actionBuild = GameMain.data.mainPlayer.controller.actionBuild; if (sourceEntity.inserterId == 0) { return(null); } InserterComponent inserter = factory.factorySystem.inserterPool[sourceEntity.inserterId]; if (data.copiedInserters.FindIndex(x => x.originalId == inserter.entityId) != -1) { return(null); } int pickTarget = inserter.pickTarget; int insertTarget = inserter.insertTarget; ItemProto itemProto = LDB.items.Select(sourceEntity.protoId); bool incoming = insertTarget == referenceEntity.id; int otherId = incoming ? pickTarget : insertTarget; Vector2 referenceSprPos = referenceEntity.pos.ToSpherical(); Vector2 sourceSprPos = sourceEntity.pos.ToSpherical(); Vector2 sourceSprPos2 = inserter.pos2.ToSpherical(); // The belt or other building this inserter is attached to Vector2 otherSprPos; ItemProto otherProto; if (otherId > 0) { otherProto = LDB.items.Select(factory.entityPool[otherId].protoId); otherSprPos = factory.entityPool[otherId].pos.ToSpherical(); } else if (otherId < 0) { otherProto = LDB.items.Select(factory.prebuildPool[-otherId].protoId); otherSprPos = factory.prebuildPool[-otherId].pos.ToSpherical(); } else { otherSprPos = sourceSprPos2; otherProto = null; } bool otherIsBelt = otherProto == null || otherProto.prefabDesc.isBelt; // Cache info for this inserter InserterCopy copiedInserter = new InserterCopy { itemProto = itemProto, protoId = itemProto.ID, originalId = inserter.entityId, pickTarget = pickTarget, insertTarget = insertTarget, referenceBuildingId = referenceEntity.id, incoming = incoming, // rotations + deltas relative to the source building's rotation rot = Quaternion.Inverse(referenceEntity.rot) * sourceEntity.rot, rot2 = Quaternion.Inverse(referenceEntity.rot) * inserter.rot2, posDelta = sourceSprPos - referenceSprPos, // Delta from copied building to inserter pos pos2Delta = sourceSprPos2 - referenceSprPos, // Delta from copied building to inserter pos2 posDeltaCount = sourceSprPos.GetSegmentsCount(), pos2DeltaCount = sourceSprPos2.GetSegmentsCount(), otherPosDelta = otherSprPos - referenceSprPos, otherPosDeltaCount = otherSprPos.GetSegmentsCount(), // not important? pickOffset = inserter.pickOffset, insertOffset = inserter.insertOffset, filterId = inserter.filter, startSlot = -1, endSlot = -1, otherIsBelt = otherIsBelt }; InserterPoses.CalculatePose(actionBuild, pickTarget, insertTarget); if (actionBuild.posePairs.Count > 0) { float minDistance = 1000f; for (int j = 0; j < actionBuild.posePairs.Count; ++j) { var posePair = actionBuild.posePairs[j]; float startDistance = Vector3.Distance(posePair.startPose.position, sourceEntity.pos); float endDistance = Vector3.Distance(posePair.endPose.position, inserter.pos2); float poseDistance = startDistance + endDistance; if (poseDistance < minDistance) { minDistance = poseDistance; copiedInserter.startSlot = posePair.startSlot; copiedInserter.endSlot = posePair.endSlot; copiedInserter.pickOffset = (short)posePair.startOffset; copiedInserter.insertOffset = (short)posePair.endOffset; } } } /* factory.ReadObjectConn(sourceEntity.id, 1, out bool isOutput, out int connectedId, out int connectedSlot); * * if (connectedId != 0) * { * copiedInserter.startSlot = connectedSlot; * } * * * factory.ReadObjectConn(sourceEntity.id, 0, out _, out connectedId, out connectedSlot); * if (connectedId != 0) * { * copiedInserter.endSlot = connectedSlot; * } */ data.copiedInserters.Add(copiedInserter); return(copiedInserter); }
public static BeltCopy CopyBelt(EntityData sourceEntity, EntityData referenceEntity) { PlanetFactory factory = GameMain.data.localPlanet.factory; ItemProto sourceEntityProto = LDB.items.Select(sourceEntity.protoId); if (!sourceEntityProto.prefabDesc.isBelt) { return(null); } BeltComponent belt = factory.cargoTraffic.beltPool[sourceEntity.beltId]; Vector2 sourceSprPos = sourceEntity.pos.ToSpherical(); BeltCopy copiedBelt = new BeltCopy() { originalId = sourceEntity.id, protoId = sourceEntityProto.ID, itemProto = sourceEntityProto, altitude = Mathf.RoundToInt(2 * (sourceEntity.pos.magnitude - GameMain.localPlanet.realRadius - 0.2f) / 1.3333333f), backInputId = factory.cargoTraffic.beltPool[belt.backInputId].entityId, leftInputId = factory.cargoTraffic.beltPool[belt.leftInputId].entityId, rightInputId = factory.cargoTraffic.beltPool[belt.rightInputId].entityId, outputId = factory.cargoTraffic.beltPool[belt.outputId].entityId, }; factory.ReadObjectConn(sourceEntity.id, 0, out bool isOutput, out int otherId, out int otherSlot); if (otherId > 0 && factory.entityPool[otherId].beltId == 0) { copiedBelt.connectedBuildingId = otherId; copiedBelt.connectedBuildingIsOutput = isOutput; copiedBelt.connectedBuildingSlot = otherSlot; } factory.ReadObjectConn(sourceEntity.id, 1, out isOutput, out otherId, out otherSlot); if (otherId > 0 && factory.entityPool[otherId].beltId == 0) { copiedBelt.connectedBuildingId = otherId; copiedBelt.connectedBuildingIsOutput = isOutput; copiedBelt.connectedBuildingSlot = otherSlot; } if (sourceEntity.id == referenceEntity.id) { data.referencePos = sourceSprPos; } else { copiedBelt.originalSegmentCount = sourceSprPos.GetSegmentsCount(); copiedBelt.cursorRelativePos = (sourceSprPos - data.referencePos).Clamp(); } data.copiedBelts.Add(copiedBelt); factory.ReadObjectConn(sourceEntity.id, 4, out _, out otherId, out _); if (otherId != 0) { // only copy belt to belt inserter if both belts are part fo the blueprint factory.ReadObjectConn(otherId, 0, out _, out int endId, out _); factory.ReadObjectConn(otherId, 1, out _, out int startId, out _); int idToFind = sourceEntity.id == endId ? startId : endId; if (data.copiedBelts.FindIndex(x => x.originalId == idToFind) != -1) { EntityData inserterEntity = factory.entityPool[otherId]; CopyInserter(inserterEntity, sourceEntity); } } hasData = true; return(copiedBelt); }
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 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 } } } } } } }
public override void SetData(PlanetFactory factory, int eId) { var labId = factory.entityPool[eId].labId; factory.factorySystem.labPool[labId].SetFunction(isResearchMode, LabRecpId, LabTech, factory.entitySignPool); }
public static void AddPlanetFactoryData(PlanetFactory planetFactory) { var factorySystem = planetFactory.factorySystem; var transport = planetFactory.transport; var veinPool = planetFactory.planet.factory.veinPool; var miningSpeedScale = (double)GameMain.history.miningSpeedScale; for (int i = 1; i < factorySystem.minerCursor; i++) { var miner = factorySystem.minerPool[i]; if (i != miner.id) { continue; } var productId = miner.productId; var veinId = (miner.veinCount != 0) ? miner.veins[miner.currentVeinIndex] : 0; if (miner.type == EMinerType.Water) { productId = planetFactory.planet.waterItemId; } else if (productId == 0) { productId = veinPool[veinId].productId; } if (productId == 0) { continue; } EnsureId(ref counter, productId); float frequency = 60f / (float)((double)miner.period / 600000.0); float speed = (float)(0.0001 * (double)miner.speed * miningSpeedScale); float production = 0f; if (factorySystem.minerPool[i].type == EMinerType.Water) { production = frequency * speed; } if (factorySystem.minerPool[i].type == EMinerType.Oil) { production = frequency * speed * (float)((double)veinPool[veinId].amount * (double)VeinData.oilSpeedMultiplier);; } if (factorySystem.minerPool[i].type == EMinerType.Vein) { production = frequency * speed * miner.veinCount; } production = Math.Min(BELT_MAX_ITEMS_PER_MINUTE, production); counter[productId].production += production; counter[productId].producers++; } for (int i = 1; i < factorySystem.assemblerCursor; i++) { var assembler = factorySystem.assemblerPool[i]; if (assembler.id != i || assembler.recipeId == 0) { continue; } var frequency = 60f / (float)((double)assembler.timeSpend / 600000.0); var speed = (float)(0.0001 * (double)assembler.speed); for (int j = 0; j < assembler.requires.Length; j++) { var productId = assembler.requires[j]; EnsureId(ref counter, productId); counter[productId].consumption += frequency * speed * assembler.requireCounts[j]; counter[productId].consumers++; } for (int j = 0; j < assembler.products.Length; j++) { var productId = assembler.products[j]; EnsureId(ref counter, productId); counter[productId].production += frequency * speed * assembler.productCounts[j]; counter[productId].producers++; } } for (int i = 1; i < factorySystem.fractionateCursor; i++) { var fractionator = factorySystem.fractionatePool[i]; if (fractionator.id != i) { continue; } if (fractionator.need != 0) { var productId = fractionator.need; EnsureId(ref counter, productId); counter[productId].consumption += 60f * 30f * fractionator.produceProb; counter[productId].consumers++; } if (fractionator.product != 0) { var productId = fractionator.product; EnsureId(ref counter, productId); counter[productId].production += 60f * 30f * fractionator.produceProb; counter[productId].producers++; } } for (int i = 1; i < factorySystem.ejectorCursor; i++) { var ejector = factorySystem.ejectorPool[i]; if (ejector.id != i) { continue; } EnsureId(ref counter, ejector.bulletId); counter[ejector.bulletId].consumption += 60f / (float)(ejector.chargeSpend + ejector.coldSpend) * 600000f; counter[ejector.bulletId].consumers++; } for (int i = 1; i < factorySystem.siloCursor; i++) { var silo = factorySystem.siloPool[i]; if (silo.id != i) { continue; } EnsureId(ref counter, silo.bulletId); counter[silo.bulletId].consumption += 60f / (float)(silo.chargeSpend + silo.coldSpend) * 600000f; counter[silo.bulletId].consumers++; } for (int i = 1; i < factorySystem.labCursor; i++) { var lab = factorySystem.labPool[i]; if (lab.id != i || !lab.matrixMode) { continue; } float frequency = 60f / (float)((double)lab.timeSpend / 600000.0); for (int j = 0; j < lab.requires.Length; j++) { var productId = lab.requires[j]; EnsureId(ref counter, productId); counter[productId].consumption += frequency * lab.requireCounts[j]; counter[productId].consumers++; } for (int j = 0; j < lab.products.Length; j++) { var productId = lab.products[j]; EnsureId(ref counter, productId); counter[productId].production += frequency * lab.productCounts[j]; counter[productId].producers++; } } for (int i = 1; i < transport.stationCursor; i++) { var station = transport.stationPool[i]; if (station == null || station.id != i || !station.isCollector) { continue; } double collectorsWorkCost = transport.collectorsWorkCost; double gasTotalHeat = planetFactory.planet.gasTotalHeat; float collectSpeedRate = (gasTotalHeat - collectorsWorkCost > 0.0) ? ((float)((miningSpeedScale * gasTotalHeat - collectorsWorkCost) / (gasTotalHeat - collectorsWorkCost))) : 1f; for (int j = 0; j < station.collectionIds.Length; j++) { var productId = station.collectionIds[j]; EnsureId(ref counter, productId); counter[productId].production += 60f * TICKS_PER_SEC * station.collectionPerTick[j] * collectSpeedRate; counter[productId].producers++; } } for (int i = 1; i < planetFactory.powerSystem.genCursor; i++) { var generator = planetFactory.powerSystem.genPool[i]; if (generator.id != i) { continue; } if (generator.productId == 0 || generator.productHeat == 0) { continue; } var productId = generator.productId; EnsureId(ref counter, productId); counter[productId].production += 60.0f * TICKS_PER_SEC * generator.capacityCurrentTick / generator.productHeat; counter[productId].producers++; } }
void Start() { planetFactory = GameObject.FindObjectOfType<PlanetFactory>(); gm = GameObject.FindObjectOfType<GameManager>(); dm = GameObject.FindObjectOfType<DataManager>(); player = GameObject.FindObjectOfType<Player>(); for (int i = 0; i < sectorTiles.Length; i++) { sectorTiles[i] = new SectorTile(); sectorTiles[i].index = i; //sectorTiles[i].x = -8f + 3.2f * i; sectorTiles[i].onSector = null; } sectorTiles[0].firstSeat = new Vector2(-1000, -800)/100f; sectorTiles[0].secondSeat = new Vector2(-1000, -800) / 100f; sectorTiles[0].thirdSeat = new Vector2(-1000, -800) / 100f; sectorTiles[0].fourthSeat = new Vector2(-1000, -800) / 100f; sectorTiles[0].fifthSeat = new Vector2(-1000, -800) / 100f; sectorTiles[1].firstSeat = new Vector2(-800, -500) / 100f; sectorTiles[1].secondSeat = new Vector2(-800, -500) / 100f; sectorTiles[1].thirdSeat = new Vector2(-512, -198) / 100f; sectorTiles[1].fourthSeat = new Vector2(-800, -500) / 100f; sectorTiles[1].fifthSeat = new Vector2(-800, -500) / 100f; sectorTiles[2].firstSeat = new Vector2(-512, 114) / 100f; sectorTiles[2].secondSeat = new Vector2(-386, 96) / 100f; sectorTiles[2].thirdSeat = new Vector2(-255, 10) / 100f; sectorTiles[2].fourthSeat = new Vector2(-188, -117) / 100f; sectorTiles[2].fifthSeat = new Vector2(-175, -207) / 100f; sectorTiles[3].firstSeat = new Vector2(-23, 255) / 100f; sectorTiles[3].secondSeat = new Vector2(47, 139) / 100f; sectorTiles[3].thirdSeat = new Vector2(90, 64) / 100f; sectorTiles[3].fourthSeat = new Vector2(119, -30) / 100f; sectorTiles[3].fifthSeat = new Vector2(134, -117) / 100f; sectorTiles[4].firstSeat = new Vector2(368, 258) / 100f; sectorTiles[4].secondSeat = new Vector2(430, 150) / 100f; sectorTiles[4].thirdSeat = new Vector2(452, 80) / 100f; sectorTiles[4].fourthSeat = new Vector2(470, -10) / 100f; sectorTiles[4].fifthSeat = new Vector2(486, -95) / 100f; sectorTiles[5].firstSeat = new Vector2(800, 500) / 100f; sectorTiles[5].secondSeat = new Vector2(800, 500) / 100f; sectorTiles[5].thirdSeat = new Vector2(800, 500) / 100f; sectorTiles[5].fourthSeat = new Vector2(800, 500) / 100f; sectorTiles[5].fifthSeat = new Vector2(800, 500) / 100f; for (int i = 0; i < sectors.Length; i++) { sectors[i] = Instantiate(sector); sectors[i].gameObject.SetActive(false); } for (int i = 0; i < 6; i++) { if (i == 1) continue; Sector s = CreateSector(); s.SetSectorTile(sectorTiles[i]); for (int j = 0; j < s.transform.childCount; j++) s.transform.GetChild(j).position = s.transform.GetChild(j).GetComponent<PlanetBase>().targetPos; } startSector.SetSectorTile(sectorTiles[1]); for (int i = 0; i < startSector.transform.childCount; i++) startSector.transform.GetChild(i).position = startSector.transform.GetChild(i).GetComponent<PlanetBase>().targetPos; ProbabilityRevision(); sectorData = dm.GetCurrentSectorData(currentSector); }
public static BuildingCopy CopyBuilding(EntityData sourceEntity, EntityData referenceEntity) { PlanetFactory factory = GameMain.data.localPlanet.factory; ItemProto sourceEntityProto = LDB.items.Select(sourceEntity.protoId); Vector3 sourcePos = sourceEntity.pos; Quaternion sourceRot = sourceEntity.rot; Quaternion zeroRot = Maths.SphericalRotation(sourcePos, 0f); float yaw = Vector3.SignedAngle(zeroRot.Forward(), sourceRot.Forward(), zeroRot.Up()); BuildingCopy copiedBuilding = new BuildingCopy() { originalId = sourceEntity.id, protoId = sourceEntityProto.ID, itemProto = sourceEntityProto, modelIndex = sourceEntity.modelIndex }; if (sourceEntity.assemblerId > 0) { copiedBuilding.recipeId = factory.factorySystem.assemblerPool[sourceEntity.assemblerId].recipeId; } else if (sourceEntity.labId > 0) { LabComponent labComponent = factory.factorySystem.labPool[sourceEntity.labId]; copiedBuilding.recipeId = ((!labComponent.researchMode) ? labComponent.recipeId : -1); } else if (sourceEntity.powerGenId > 0) { PowerGeneratorComponent powerGeneratorComponent = factory.powerSystem.genPool[sourceEntity.powerGenId]; if (powerGeneratorComponent.gamma) { copiedBuilding.recipeId = ((powerGeneratorComponent.productId <= 0) ? 0 : 1); } } else if (sourceEntity.powerExcId > 0) { copiedBuilding.recipeId = Mathf.RoundToInt(factory.powerSystem.excPool[sourceEntity.powerExcId].targetState); } else if (sourceEntity.ejectorId > 0) { copiedBuilding.recipeId = factory.factorySystem.ejectorPool[sourceEntity.ejectorId].orbitId; } else if (sourceEntity.stationId > 0) { StationComponent stationComponent = factory.transport.stationPool[sourceEntity.stationId]; for (int i = 0; i < stationComponent.slots.Length; i++) { if (stationComponent.slots[i].storageIdx != 0) { copiedBuilding.slotFilters.Add(new SlotFilter() { slotIndex = i, storageIdx = stationComponent.slots[i].storageIdx }); } } for (int i = 0; i < stationComponent.storage.Length; i++) { if (stationComponent.storage[i].itemId != 0) { copiedBuilding.stationSettings.Add(new StationSetting() { index = i, itemId = stationComponent.storage[i].itemId, max = stationComponent.storage[i].max, localLogic = stationComponent.storage[i].localLogic, remoteLogic = stationComponent.storage[i].remoteLogic }); } } } else if (sourceEntity.splitterId > 0) { // TODO: find a way to restore splitter settings // SplitterComponent splitterComponent = factory.cargoTraffic.splitterPool[sourceEntity.splitterId]; } Vector2 sourceSprPos = sourcePos.ToSpherical(); if (sourceEntity.id == referenceEntity.id) { data.referencePos = sourceSprPos; copiedBuilding.cursorRelativeYaw = yaw; } else { copiedBuilding.originalSegmentCount = sourceSprPos.GetSegmentsCount(); copiedBuilding.cursorRelativePos = (sourceSprPos - data.referencePos).Clamp(); copiedBuilding.cursorRelativeYaw = yaw; } data.copiedBuildings.Add(copiedBuilding); for (int i = 0; i < sourceEntityProto.prefabDesc.insertPoses.Length; i++) { factory.ReadObjectConn(sourceEntity.id, i, out bool _, out int otherObjId, out int _); if (otherObjId > 0) { EntityData inserterEntity = factory.entityPool[otherObjId]; CopyInserter(inserterEntity, sourceEntity); } } hasData = true; return(copiedBuilding); }
public static void Postfix(int id, ItemProto newProto, PlanetFactory __instance) { if (id == 0 || __instance.entityPool[id].id == 0) { return; } if (__instance.entityPool[id].minerId <= 0) { return; } MinerComponent component = __instance.factorySystem.minerPool[__instance.entityPool[id].minerId]; if (component.type != EMinerType.Vein) { return; } PrefabDesc desc = newProto.prefabDesc; Pose pose; pose.position = __instance.entityPool[id].pos; pose.rotation = __instance.entityPool[id].rot; int[] tmp_ids = new int[256]; Vector3 vector3 = pose.position + pose.forward * -1.2f; Vector3 rhs = -pose.forward; Vector3 up = pose.up; int veinsInAreaNonAlloc = __instance.planet.physics.nearColliderLogic.GetVeinsInAreaNonAlloc(vector3, DSPAdvancedMiner.getMinerRadius(desc) + 4, tmp_ids); int[] refArray = new int[veinsInAreaNonAlloc]; VeinData[] veinPool = __instance.planet.factory.veinPool; int refCount = 0; for (int j = 0; j < veinsInAreaNonAlloc; j++) { if (tmp_ids[j] != 0 && veinPool[tmp_ids[j]].id == tmp_ids[j]) { if (veinPool[tmp_ids[j]].type != EVeinType.Oil) { Vector3 pos = veinPool[tmp_ids[j]].pos; Vector3 vector4 = pos - vector3; float num8 = Vector3.Dot(up, vector4); vector4 -= up * num8; float sqrMagnitude = vector4.sqrMagnitude; float num9 = Vector3.Dot(vector4.normalized, rhs); float radius = DSPAdvancedMiner.getMinerRadius(desc); if (sqrMagnitude <= radius * radius && num9 >= 0.73f && Mathf.Abs(num8) <= 2f) { refArray[refCount++] = tmp_ids[j]; } } } } component.InitVeinArray(refCount); if (refCount > 0) { Array.Copy(refArray, component.veins, refCount); } for (int i = 0; i < component.veinCount; i++) { __instance.RefreshVeinMiningDisplay(component.veins[i], component.entityId, 0); } component.ArrageVeinArray(); __instance.factorySystem.minerPool[__instance.entityPool[id].minerId] = component; }
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 Postfix(int entityId, ItemProto newProto, PlanetFactory __instance) { if (entityId == 0 || __instance.entityPool[entityId].id == 0) { return; } if (__instance.entityPool[entityId].minerId <= 0) { return; } MinerComponent component = __instance.factorySystem.minerPool[__instance.entityPool[entityId].minerId]; if (component.type != EMinerType.Vein) { return; } PrefabDesc desc = newProto.prefabDesc; float radius = DSPAdvancedMiner.getMinerRadius(desc); radius *= radius; Pose pose; pose.position = __instance.entityPool[entityId].pos; pose.rotation = __instance.entityPool[entityId].rot; int[] tmp_ids = new int[256]; Vector3 vector2 = pose.position + pose.forward * -1.2f; Vector3 rhs = -pose.forward; Vector3 vector3 = pose.up; int veinsInAreaNonAlloc = __instance.planet.physics.nearColliderLogic.GetVeinsInAreaNonAlloc(vector2, DSPAdvancedMiner.getMinerRadius(desc) + 4, tmp_ids); PrebuildData prebuildData = default(PrebuildData); prebuildData.InitParametersArray(veinsInAreaNonAlloc); VeinData[] veinPool = __instance.planet.factory.veinPool; int paramCount = 0; for (int j = 0; j < veinsInAreaNonAlloc; j++) { if (tmp_ids[j] != 0 && veinPool[tmp_ids[j]].id == tmp_ids[j]) { if (veinPool[tmp_ids[j]].type != EVeinType.Oil) { Vector3 vector4 = veinPool[tmp_ids[j]].pos - vector2; float num2 = Vector3.Dot(vector3, vector4); vector4 -= vector3 * num2; float sqrMagnitude = vector4.sqrMagnitude; float num3 = Vector3.Dot(vector4.normalized, rhs); if (sqrMagnitude <= radius && num3 >= 0.73f && Mathf.Abs(num2) <= 2f) { prebuildData.parameters[paramCount++] = tmp_ids[j]; } } } else { Assert.CannotBeReached(); } } component.InitVeinArray(paramCount); if (paramCount > 0) { Array.Copy(prebuildData.parameters, component.veins, paramCount); } for (int i = 0; i < component.veinCount; i++) { __instance.RefreshVeinMiningDisplay(component.veins[i], component.entityId, 0); } component.ArrangeVeinArray(); __instance.factorySystem.minerPool[__instance.entityPool[entityId].minerId] = component; }
static void Geothermal(PlanetFactory __instance) { var factory = __instance; if (frame % 3 != 0) { return; } if (factory.planet.type != EPlanetType.Vocano || factory.planet.waterItemId != -1) { return; } GameStatData statistics = GameMain.statistics; FactoryProductionStat factoryProductionStat = statistics.production.factoryStatPool[factory.factorySystem.factory.index]; int[] productRegister = factoryProductionStat.productRegister; int[] consumeRegister = factoryProductionStat.consumeRegister; for (int i = 0; i < factory.transport.stationCursor; i++) { var sc = factory.transport.stationPool[i]; if (sc != null && sc.storage != null) { int item1 = -1; int item2 = -1; int item3 = -1; int item4 = -1; int item5 = -1; for (int j = 0; j < sc.storage.Length; j++) { var st = sc.storage[j]; if (st.itemId > 0) { if (st.itemId == ice) { item1 = j; } else if (st.itemId == waterId) { item2 = j; } else if (st.itemId == cmx) { item3 = j; } else if (st.itemId == emtryB) { item4 = j; } else if (st.itemId == fullB) { item5 = j; } } } if (item1 > -1) { if (item3 > -1 && sc.storage[item1].count > 0) { if (sc.storage[item3].count < sc.storage[item3].max) { if (sc.energy < sc.energyMax - 100000) { sc.energy += 100000; } sc.storage[item1].count--; consumeRegister[item1]++; sc.storage[item3].count++; productRegister[item1]++; if (item4 > -1 && item5 > -1 && sc.storage[item4].count > 0 && sc.storage[item5].max > sc.storage[item5].count) { if (frame % 20 == 0) { sc.storage[item4].count--; consumeRegister[item4]++; productRegister[item5]++; sc.storage[item5].count++; } } } } } if (item2 > -1) { if (sc.storage[item2].count > 0 && item4 > -1 && item5 > -1 && sc.storage[item4].count > 0 && sc.storage[item5].max > sc.storage[item5].count) { if (sc.energy < sc.energyMax - 100000) { sc.energy += 100000; } sc.storage[item2].count--; consumeRegister[item2]++; if (frame % 20 == 0) { sc.storage[item4].count--; consumeRegister[item4]++; productRegister[item5]++; sc.storage[item5].count++; } } } } } }
// This function is based on PlayerAction_Mine.GameTick public void DroneGameTick() { double powerFactor = 0.01666666753590107; PlanetFactory factory = this.player.factory; if (factory == null) { // This has only been seen briefly when the Render Distance mod is transitioning to or from a planet view. return; } double miningEnergyCost = this.player.mecha.miningPower * powerFactor; double energyAvailable; float fractionOfEnergyAvailable; this.player.mecha.QueryEnergy(miningEnergyCost, out energyAvailable, out fractionOfEnergyAvailable); int miningTime = (int)(this.player.mecha.miningSpeed * configSpeedScaleFactor * fractionOfEnergyAvailable * 10000f + 0.49f); VegeData vegeData = factory.GetVegeData(this.miningId); this.miningProtoId = (int)vegeData.protoId; VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId); if (vegeProto != null) { this.miningTick += miningTime; this.player.mecha.coreEnergy -= energyAvailable; this.player.mecha.MarkEnergyChange(5, -miningEnergyCost); this.percent = Mathf.Clamp01((float)((double)this.miningTick / (double)(vegeProto.MiningTime * 10000))); if (this.miningTick >= vegeProto.MiningTime * 10000) { System.Random random = new System.Random(vegeData.id + ((this.player.planetData.seed & 16383) << 14)); bool inventoryOverflowFlag = false; int popupQueueIndex = 0; for (int itemIdx = 0; itemIdx < vegeProto.MiningItem.Length; itemIdx++) { float randomMiningChance = (float)random.NextDouble(); if (randomMiningChance < vegeProto.MiningChance[itemIdx]) { int minedItem = vegeProto.MiningItem[itemIdx]; int minedItemCount = (int)((float)vegeProto.MiningCount[itemIdx] * (vegeData.scl.y * vegeData.scl.y) + 0.5f); if (minedItemCount > 0 && LDB.items.Select(minedItem) != null) { int inventoryOverflowCount = this.player.package.AddItemStacked(minedItem, minedItemCount); if (inventoryOverflowCount != 0) { UIItemup.Up(minedItem, inventoryOverflowCount); UIRealtimeTip.PopupItemGet(minedItem, inventoryOverflowCount, vegeData.pos + vegeData.pos.normalized, popupQueueIndex++); } else // Unable to fit all items { inventoryOverflowFlag = true; } } } } VFEffectEmitter.Emit(vegeProto.MiningEffect, vegeData.pos, vegeData.rot); VFAudio.Create(vegeProto.MiningAudio, null, vegeData.pos, true); factory.RemoveVegeWithComponents(vegeData.id); GameMain.gameScenario.NotifyOnVegetableMined((int)vegeData.protoId); this.miningType = EObjectType.Entity; // This change will cause the mission to be completed. this.miningId = 0; if (inventoryOverflowFlag) { //Logger.LogInfo("Inventory overflow detected."); } this.miningTick = 0; } } else { //Logger.LogInfo("null vegeProto. Icarus likely removed clearing target."); this.miningType = EObjectType.Entity; // This change will cause the mission to be completed. this.miningId = 0; this.miningTick = 0; this.percent = 0f; factory.RemoveVegeWithComponents(vegeData.id); } }