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;
    }
Exemple #2
0
    /// <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);
                }
            }
        }
Exemple #4
0
        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);
 }
Exemple #6
0
        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);
                }
            }
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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,
            });
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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();
            }
        }
Exemple #15
0
            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);
                        }
                    }
                }
            }
Exemple #16
0
            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);
                        }
                    }
                }
            }
Exemple #17
0
            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);
            }
Exemple #18
0
 public abstract bool Redo(PlanetFactory factory, PlayerAction_Build actionBuild);
Exemple #19
0
        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);
        }
Exemple #20
0
        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);
    }
Exemple #24
0
        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);
    }
Exemple #26
0
        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);
        }
Exemple #27
0
        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;
        }
Exemple #28
0
        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;
            }
        }
Exemple #29
0
        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;
        }
Exemple #30
0
        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);
                }
            }