private Station(PrebuildData prebuild)
 {
     pd         = prebuild;
     isStation  = true;
     isNeedConn = true;
     type       = EDataType.Station;
 }
 public static bool PlanetFactory_BuildFinally_Prefix(Player player, int prebuildId)
 {
     if (player.factory != null && prebuildId != 0)
     {
         PrebuildData prebuild = player.factory.prebuildPool[prebuildId];
         if (isDroneClearingPrebuild(prebuild))
         {   // This will never happen unless DSP Cheats' Instant-Build feature is enabled.  So, let's do what it's telling us to.
             if (configEnableInstantClearing)
             {
                 player.factory.RemovePrebuildData(prebuildId);
                 player.factory.RemoveVegeWithComponents(prebuild.upEntity);
                 for (int activeMissionIdx = 0; activeMissionIdx < activeMissions.Count; ++activeMissionIdx)
                 {
                     DroneClearingMissionData missionData = activeMissions[activeMissionIdx];
                     if (missionData.prebuildId == prebuildId)
                     {
                         if (missionData.mineAction.miningType == EObjectType.Entity)
                         {
                             activeMissions.RemoveAt(activeMissionIdx);
                         }
                     }
                 }
             }
             return(false);
         }
     }
     return(true);
 }
Beispiel #3
0
 public Fractionate(PrebuildData prebuild, int c0, int c1, int c2)
 {
     pd         = prebuild;
     isNeedConn = true;
     type       = EDataType.Fractionate;
     this.c0    = c0;
     this.c1    = c1;
     this.c2    = c2;
 }
Beispiel #4
0
 public Inserter(PrebuildData prebuild, InserterComponent inserter, int Out, int In)
 {
     pd            = prebuild;
     isInserter    = true;
     type          = EDataType.Inserter;
     this.inserter = inserter;
     outConn       = Out;
     inConn        = In;
 }
Beispiel #5
0
        public PrebuildData GetPrebuildData()
        {
            PrebuildData prebuild = new PrebuildData();

            using (BinaryUtils.Reader writer = new BinaryUtils.Reader(PrebuildDataRaw))
            {
                prebuild.Import(writer.BinaryReader);
            }
            return(prebuild);
        }
Beispiel #6
0
        public AddEntityPreviewRequest(int planetId, PrebuildData prebuild)
        {
            PlanetId = planetId;

            using (BinaryUtils.Writer writer = new BinaryUtils.Writer())
            {
                prebuild.Export(writer.BinaryWriter);
                PrebuildDataRaw = writer.CloseAndGetBytes();
            }
        }
 public Gamm(PrebuildData prebuild, int ProduceId, int conn0, int conn1)
 {
     isGamm         = true;
     isNeedConn     = true;
     type           = EDataType.Gamm;
     pd             = prebuild;
     this.conn0     = conn0;
     this.conn1     = conn1;
     this.produceId = ProduceId;
 }
        public static void MechaDrone_Update_Postfix(MechaDrone __instance, ref int __result, PrebuildData[] prebuildPool, Vector3 playerPos, float dt, ref double energy, ref double energyChange, double energyRate)
        {
            if (__result == 1)  // If the Prebuild would normally complete...
            {
                int          prebuildId = -__instance.targetObject;
                PrebuildData prebuild   = prebuildPool[prebuildId];
                if (isDroneClearingPrebuild(prebuild))
                {
                    PlanetFactory factory = GameMain.mainPlayer.factory;

                    DroneClearingMissionData missionData = null;
                    for (int activeMissionIdx = 0; activeMissionIdx < activeMissions.Count; ++activeMissionIdx)
                    {
                        missionData = activeMissions[activeMissionIdx];
                        if (missionData.prebuildId == prebuildId)
                        {
                            if (missionData.mineAction.miningType == EObjectType.Entity)
                            {
                                // Clearing completed
                                activeMissions.RemoveAt(activeMissionIdx);
                                factory.RemovePrebuildData(prebuildId);
                            }
                            else
                            {
                                __result = 0;
                            }
                            return;
                        }
                    }

                    if (configCollectResourcesFlag)
                    {
                        missionData                       = new DroneClearingMissionData();
                        missionData.prebuildId            = prebuildId;
                        missionData.forward               = __instance.forward;
                        missionData.position              = __instance.position;
                        missionData.mineAction            = new DroneAction_Mine();
                        missionData.mineAction.player     = GameMain.mainPlayer;
                        missionData.mineAction.miningType = EObjectType.Vegetable;
                        missionData.mineAction.miningId   = prebuild.upEntity;
                        missionData.mineAction.miningTick = 0;
                        activeMissions.Add(missionData);
                    }
                    else
                    {
                        factory.RemovePrebuildData(prebuildId);
                        factory.RemoveVegeWithComponents(prebuild.upEntity);
                    }

                    __result = 0;
                    return;
                }
            }
        }
 public Splitter(PrebuildData prebuild, int c0, int c1, int c2, int c3)
 {
     pd         = prebuild;
     isSplitter = true;
     isNeedConn = true;
     isAfterSet = true;
     type       = EDataType.Splitter;
     this.c0    = c0;
     this.c1    = c1;
     this.c2    = c2;
     this.c3    = c3;
 }
 public Belt(PrebuildData prebuild, BeltComponent belt, int out1, int in1, int in2, int in3)
 {
     pd = prebuild;
     Init();
     this.belt = belt;
     type      = EDataType.Belt;
     beltOut   = out1;
     beltIn1   = in1;
     beltIn2   = in2;
     beltIn3   = in3;
     isBelt    = true;
 }
 public PowerExchanger(PrebuildData prebuild, int conn0, int conn1, int conn2, int conn3, float state)
 {
     pd         = prebuild;
     isNeedConn = true;
     isAfterSet = true;
     type       = EDataType.PowerExchanger;
     c0         = conn0;
     c1         = conn1;
     c2         = conn2;
     c3         = conn3;
     this.state = state;
 }
 public Lab(PrebuildData prebuild, bool isResMode, int RecpId, int TachId, int next = 0)
 {
     Init();
     pd             = prebuild;
     isLab          = true;
     type           = EDataType.Lab;
     isNeedConn     = true;
     isResearchMode = isResMode;
     LabRecpId      = RecpId;
     LabTech        = TachId;
     nextLab        = next;
 }
    static PrebuildData GetPreDate(BeltComponent bc, EntityData ed)
    {
        PrebuildData prebuild = default(PrebuildData);

        prebuild.protoId    = (short)ed.protoId;
        prebuild.modelIndex = (short)ed.modelIndex;
        prebuild.pos        = ed.pos;
        prebuild.pos2       = VectorLF3.zero;
        prebuild.rot        = ed.rot;
        prebuild.rot2       = Quaternion.identity;
        return(prebuild);
    }
Beispiel #14
0
        public static void AddPrebuildData_Postfix(PlanetFactory __instance, PrebuildData prebuild, ref int __result)
        {
            if (!SimulatedWorld.Initialized)
            {
                return;
            }

            // If the host game called the method, we need to compute the PrebuildId ourself
            if (LocalPlayer.IsMasterClient)
            {
                FactoryManager.SetPrebuildRequest(__instance.planetId, __result, LocalPlayer.PlayerId);
            }
        }
        public static void AddPrebuildData_Postfix(PlanetFactory __instance, PrebuildData prebuild, ref int __result)
        {
            if (!Multiplayer.IsActive)
            {
                return;
            }

            // If the host game called the method, we need to compute the PrebuildId ourself
            if (Multiplayer.Session.LocalPlayer.IsHost)
            {
                Multiplayer.Session.Factories.SetPrebuildRequest(__instance.planetId, __result, Multiplayer.Session.LocalPlayer.Id);
            }
        }
    static PrebuildData GetPreDate(InserterComponent ic, EntityData ed)
    {
        PrebuildData prebuild = default(PrebuildData);

        prebuild.protoId      = (short)ed.protoId;
        prebuild.modelIndex   = (short)ed.modelIndex;
        prebuild.pos          = ed.pos;
        prebuild.pos2         = ic.pos2;
        prebuild.rot          = ed.rot;
        prebuild.rot2         = ic.rot2;
        prebuild.filterId     = ic.filter;
        prebuild.insertOffset = ic.insertOffset;
        prebuild.pickOffset   = ic.pickOffset;
        return(prebuild);
    }
 public static bool PrebuildData_Export_Prefix(PrebuildData __instance, BinaryWriter w)
 {
     if (isDroneClearingPrebuild(__instance))
     {
         // Do not save drone clearing tasks.  This would work unless the mod
         // gets uninstalled in which case it causes the game to issue an error.
         //Logger.LogInfo("Preventing saving of drone clearing prebuild.");
         PrebuildData generic = default;
         generic.Export(w);
         return(false);
     }
     else
     {
         return(true);
     }
 }
Beispiel #18
0
        public void ProcessPacket(AddEntityPreviewRequest packet, NebulaConnection conn)
        {
            PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId);

            // We only execute the code if the client has loaded the factory at least once.
            // Else it will get it once it goes to the planet for the first time.
            if (planet.factory != null)
            {
                FactoryManager.EventFromServer = true;
                PrebuildData prebuild      = packet.GetPrebuildData();
                int          localPlanetId = GameMain.localPlanet?.id ?? -1;
                if (packet.PlanetId == localPlanetId)
                {
                    planet.factory.AddPrebuildDataWithComponents(prebuild);
                }
                else
                {
                    planet.factory.AddPrebuildData(prebuild);
                }
                FactoryManager.EventFromServer = false;
            }
        }
    public Station(PrebuildData prebuild, StationComponent sc)
    {
        pd         = prebuild;
        isStation  = true;
        isNeedConn = true;
        type       = EDataType.Station;
        slots      = new SlotData[sc.slots.Length];
        for (int i = 0; i < slots.Length; i++)
        {
            slots[i] = sc.slots[i];

            slots[i].beltId = GameMain.mainPlayer.planetData.factory.cargoTraffic.beltPool[slots[i].beltId].entityId;
        }
        storage = new StationStore[sc.storage.Length];
        for (int i = 0; i < storage.Length; i++)
        {
            storage[i]             = sc.storage[i];
            storage[i].count       = 0;
            storage[i].localOrder  = 0;
            storage[i].remoteOrder = 0;
        }
    }
Beispiel #20
0
        public void ProcessPacket(AddEntityPreviewRequest packet, NebulaConnection conn)
        {
            Player player = playerManager.GetPlayer(conn);

            if (player == null)
            {
                Log.Warn($"Received AddEntityPreviewRequest packet from unknown player connection");
                return;
            }

            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);
            }

            FactoryManager.EventFromClient = true;
            int nextPrebuildId = FactoryManager.GetNextPrebuildId(packet.PlanetId);

            FactoryManager.SetPrebuildRequest(packet.PlanetId, nextPrebuildId, player.Id);
            PrebuildData prebuild      = packet.GetPrebuildData();
            int          localPlanetId = GameMain.localPlanet?.id ?? -1;

            if (planet.id == localPlanetId)
            {
                planet.factory.AddPrebuildDataWithComponents(prebuild);
            }
            else
            {
                planet.factory.AddPrebuildData(prebuild);

                // AddPrebuildData is not patched so we need to send the packet manually here
                LocalPlayer.SendPacket(packet);
            }
            FactoryManager.EventFromClient = false;
        }
Beispiel #21
0
 public static void CreatePrebuilds(PlayerAction_Build _this)
 {
     if (_this.waitConfirm && VFInput.rtsConfirm.pressing && _this.buildPreviews.Count > 0)
     {
         Traverse.Create(_this).Field("tmp_links").GetValue <List <int> >().Clear();
         var factory = Traverse.Create(_this).Field("factory").GetValue <PlanetFactory>();
         foreach (BuildPreview buildPreview in _this.buildPreviews)
         {
             if (buildPreview.isConnNode)
             {
                 buildPreview.lrot = Maths.SphericalRotation(buildPreview.lpos, 0f);
             }
             PrebuildData prebuild = default(PrebuildData);
             prebuild.protoId      = (short)buildPreview.item.ID;
             prebuild.modelIndex   = (short)buildPreview.desc.modelIndex;
             prebuild.pos          = _this.previewPose.position + _this.previewPose.rotation * buildPreview.lpos;
             prebuild.pos2         = _this.previewPose.position + _this.previewPose.rotation * buildPreview.lpos2;
             prebuild.rot          = _this.previewPose.rotation * buildPreview.lrot;
             prebuild.rot2         = _this.previewPose.rotation * buildPreview.lrot2;
             prebuild.pickOffset   = (short)buildPreview.inputOffset;
             prebuild.insertOffset = (short)buildPreview.outputOffset;
             prebuild.recipeId     = buildPreview.recipeId;
             prebuild.filterId     = buildPreview.filterId;
             prebuild.InitRefArray(buildPreview.refCount);
             for (int i = 0; i < buildPreview.refCount; i++)
             {
                 prebuild.refArr[i] = buildPreview.refArr[i];
             }
             bool flag = true;
             if (buildPreview.coverObjId == 0 || buildPreview.willCover)
             {
                 int id  = buildPreview.item.ID;
                 int num = 1;
                 if (_this.player.inhandItemId == id && _this.player.inhandItemCount > 0)
                 {
                     _this.player.UseHandItems(1);
                 }
                 else
                 {
                     _this.player.package.TakeTailItems(ref id, ref num, false);
                 }
                 flag = (num == 1);
             }
             if (flag)
             {
                 if (buildPreview.coverObjId == 0)
                 {
                     buildPreview.objId = -factory.AddPrebuildDataWithComponents(prebuild);
                 }
                 else if (buildPreview.willCover)
                 {
                     int  coverObjId = buildPreview.coverObjId;
                     bool flag2      = ObjectIsBelt(_this, coverObjId);
                     if (flag2)
                     {
                         for (int j = 0; j < 4; j++)
                         {
                             bool flag3;
                             int  num2;
                             int  num3;
                             factory.ReadObjectConn(coverObjId, j, out flag3, out num2, out num3);
                             int num4 = num2;
                             if (num4 != 0 && ObjectIsBelt(_this, num4))
                             {
                                 bool flag4 = false;
                                 for (int k = 0; k < 2; k++)
                                 {
                                     factory.ReadObjectConn(num4, k, out flag3, out num2, out num3);
                                     if (num2 != 0)
                                     {
                                         bool flag5 = ObjectIsBelt(_this, num2);
                                         bool flag6 = Traverse.Create(_this).Method("ObjectIsInserter", num2).GetValue <bool>();
                                         if (!flag5 && !flag6)
                                         {
                                             flag4 = true;
                                             break;
                                         }
                                     }
                                 }
                                 if (flag4)
                                 {
                                     Traverse.Create(_this).Field("tmp_links").GetValue <List <int> >().Add(num4);
                                 }
                             }
                         }
                     }
                     if (buildPreview.coverObjId > 0)
                     {
                         Array.Copy(factory.entityConnPool, buildPreview.coverObjId * 16, Traverse.Create(_this).Field("tmp_conn").GetValue <int[]>(), 0, 16);
                         for (int l = 0; l < 16; l++)
                         {
                             bool flag7;
                             int  num5;
                             int  otherSlotId;
                             factory.ReadObjectConn(buildPreview.coverObjId, l, out flag7, out num5, out otherSlotId);
                             if (num5 > 0)
                             {
                                 factory.ApplyEntityDisconnection(num5, buildPreview.coverObjId, otherSlotId, l);
                             }
                         }
                         Array.Clear(factory.entityConnPool, buildPreview.coverObjId * 16, 16);
                     }
                     else
                     {
                         Array.Copy(factory.prebuildConnPool, -buildPreview.coverObjId * 16, Traverse.Create(_this).Field("tmp_conn").GetValue <int[]>(), 0, 16);
                         Array.Clear(factory.prebuildConnPool, -buildPreview.coverObjId * 16, 16);
                     }
                     buildPreview.objId = -factory.AddPrebuildDataWithComponents(prebuild);
                     if (buildPreview.objId > 0)
                     {
                         Array.Copy(Traverse.Create(_this).Field("tmp_conn").GetValue <int[]>(), 0, factory.entityConnPool, buildPreview.objId * 16, 16);
                     }
                     else
                     {
                         Array.Copy(Traverse.Create(_this).Field("tmp_conn").GetValue <int[]>(), 0, factory.prebuildConnPool, -buildPreview.objId * 16, 16);
                     }
                     factory.EnsureObjectConn(buildPreview.objId);
                 }
                 else
                 {
                     buildPreview.objId = buildPreview.coverObjId;
                 }
             }
             else
             {
                 Assert.CannotBeReached();
                 UIRealtimeTip.Popup("物品不足".Translate(), true, 1);
             }
         }
         foreach (BuildPreview buildPreview2 in _this.buildPreviews)
         {
             if (buildPreview2.objId != 0)
             {
                 if (buildPreview2.outputObjId != 0)
                 {
                     factory.WriteObjectConn(buildPreview2.objId, buildPreview2.outputFromSlot, true, buildPreview2.outputObjId, buildPreview2.outputToSlot);
                 }
                 else if (buildPreview2.output != null)
                 {
                     factory.WriteObjectConn(buildPreview2.objId, buildPreview2.outputFromSlot, true, buildPreview2.output.objId, buildPreview2.outputToSlot);
                 }
                 if (buildPreview2.inputObjId != 0)
                 {
                     factory.WriteObjectConn(buildPreview2.objId, buildPreview2.inputToSlot, false, buildPreview2.inputObjId, buildPreview2.inputFromSlot);
                 }
                 else if (buildPreview2.input != null)
                 {
                     factory.WriteObjectConn(buildPreview2.objId, buildPreview2.inputToSlot, false, buildPreview2.input.objId, buildPreview2.inputFromSlot);
                 }
             }
         }
         foreach (BuildPreview buildPreview3 in _this.buildPreviews)
         {
             if (buildPreview3.coverObjId != 0 && buildPreview3.willCover && buildPreview3.objId != 0 && ObjectIsBelt(_this, buildPreview3.objId))
             {
                 bool flag8;
                 int  num6;
                 int  num7;
                 factory.ReadObjectConn(buildPreview3.objId, 0, out flag8, out num6, out num7);
                 if (num6 != 0 && flag8 && ObjectIsBelt(_this, buildPreview3.objId))
                 {
                     int num8;
                     factory.ReadObjectConn(num6, 0, out flag8, out num8, out num7);
                     if (num8 == buildPreview3.objId)
                     {
                         factory.ClearObjectConn(num6, 0);
                     }
                 }
             }
         }
         foreach (BuildPreview buildPreview4 in _this.buildPreviews)
         {
             if (buildPreview4.coverObjId != 0 && buildPreview4.willCover)
             {
                 _this.DoDestructObject(buildPreview4.coverObjId);
             }
             foreach (int objId in Traverse.Create(_this).Field("tmp_links").GetValue <List <int> >())
             {
                 _this.DoDestructObject(objId);
             }
         }
         _this.AfterPrebuild();
     }
 }
        public static void AfterPrebuild_Postfix(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, NearColliderLogic ___nearcdLogic)
        {
            // Do we have cached inserters?
            var ci = cachedInserters;

            if (CopyInserters.copyEnabled && ci.Count > 0 && !__instance.multiLevelCovering)
            {
                foreach (var cachedInserter in ci)
                {
                    var protoId    = cachedInserter.protoId;
                    var modelIndex = (short)LDB.items.Select(cachedInserter.protoId).ModelIndex;

                    foreach (BuildPreview buildPreview in __instance.buildPreviews)
                    {
                        var positionData = GetPositions(__instance, ___factory, ___planetAux, ___nearcdLogic, buildPreview, cachedInserter);

                        if (positionData.otherId != 0)
                        {
                            // Create inserter Prebuild data
                            var pbdata = new PrebuildData
                            {
                                protoId    = (short)protoId,
                                modelIndex = modelIndex,

                                insertOffset = positionData.insertOffset,
                                pickOffset   = positionData.pickOffset,
                                filterId     = cachedInserter.filterId,

                                refCount = cachedInserter.refCount,

                                pos  = positionData.absoluteInserterPos,
                                pos2 = positionData.absoluteInserterPos2,

                                rot  = positionData.absoluteInserterRot,
                                rot2 = positionData.absoluteInserterRot2
                            };


                            // Check the player has the item in inventory, no cheating here
                            var pc        = CopyInserters.pc;
                            var itemcount = pc.player.package.GetItemCount(protoId);
                            // If player has none; skip this request, as we dont create prebuild ghosts, must avoid confusion
                            if (itemcount > 0)
                            {
                                var qty = 1;
                                pc.player.package.TakeTailItems(ref protoId, ref qty);
                                int pbCursor = ___factory.AddPrebuildDataWithComponents(pbdata); // Add the inserter request to Prebuild pool

                                if (cachedInserter.incoming)
                                {
                                    ___factory.WriteObjectConn(-pbCursor, 0, true, buildPreview.objId, positionData.endSlot);      // assembler connection
                                    ___factory.WriteObjectConn(-pbCursor, 1, false, positionData.otherId, positionData.startSlot); // other connection
                                }
                                else
                                {
                                    ___factory.WriteObjectConn(-pbCursor, 0, false, buildPreview.objId, positionData.startSlot); // assembler connection
                                    ___factory.WriteObjectConn(-pbCursor, 1, true, positionData.otherId, positionData.endSlot);  // other connection
                                }
                            }
                        }
                    }
                }
            }
        }
        private static InserterPosition GetPositions(PlayerAction_Build __instance, PlanetFactory ___factory, PlanetAuxData ___planetAux, NearColliderLogic ___nearcdLogic, BuildPreview buildPreview, CachedInserter cachedInserter)
        {
            Vector3    absoluteBuildingPos;
            Quaternion absoluteBuildingRot;

            // When using AdvancedBuildDestruct mod, all buildPreviews are positioned 'absolutely' on the planet surface.
            // In 'normal' mode the buildPreviews are relative to __instance.previewPose.
            // This means that in 'normal' mode the (only) buildPreview is always positioned at {0,0,0}

            if (buildPreview.lpos == Vector3.zero)
            {
                absoluteBuildingPos = __instance.previewPose.position;
                absoluteBuildingRot = __instance.previewPose.rotation;
            }
            else
            {
                absoluteBuildingPos = buildPreview.lpos;
                absoluteBuildingRot = buildPreview.lrot;
            }

            InserterPosition position = null;

            if (currentPositionCache.Count > 0)
            {
                position = currentPositionCache.Dequeue();
            }

            bool isCacheValid = position != null &&
                                position.cachedInserter == cachedInserter &&
                                position.absoluteBuildingPos == absoluteBuildingPos &&
                                position.absoluteBuildingRot == absoluteBuildingRot;

            if (isCacheValid)
            {
                nextPositionCache.Enqueue(position);
                return(position);
            }


            var posDelta  = cachedInserter.posDelta;
            var pos2Delta = cachedInserter.pos2Delta;

            Vector3 absoluteInserterPos  = absoluteBuildingPos + absoluteBuildingRot * cachedInserter.posDelta;
            Vector3 absoluteInserterPos2 = absoluteBuildingPos + absoluteBuildingRot * cachedInserter.pos2Delta;

            Quaternion absoluteInserterRot  = absoluteBuildingRot * cachedInserter.rot;
            Quaternion absoluteInserterRot2 = absoluteBuildingRot * cachedInserter.rot2;

            int startSlot = cachedInserter.startSlot;
            int endSlot   = cachedInserter.endSlot;

            short pickOffset   = cachedInserter.pickOffset;
            short insertOffset = cachedInserter.insertOffset;

            // Find the desired belt/building position
            // As delta doesn't work over distance, re-trace the Grid Snapped steps from the original
            // to find the target belt/building for this inserters other connection
            var testPos = absoluteBuildingPos;

            // Note: rotates each move relative to the rotation of the new building
            for (int u = 0; u < cachedInserter.snapCount; u++)
            {
                testPos = ___planetAux.Snap(testPos + absoluteBuildingRot * cachedInserter.snapMoves[u], true, false);
            }

            // Find the other entity at the target location
            int otherId = 0;

            // find building nearby
            int found = ___nearcdLogic.GetBuildingsInAreaNonAlloc(testPos, 0.2f, _nearObjectIds);

            // find nearest building
            float maxDistance = 0.2f;

            for (int x = 0; x < found; x++)
            {
                var       id = _nearObjectIds[x];
                float     distance;
                ItemProto proto;
                if (id == 0 || id == buildPreview.objId)
                {
                    continue;
                }
                else if (id > 0)
                {
                    EntityData entityData = ___factory.entityPool[id];
                    proto    = LDB.items.Select((int)entityData.protoId);
                    distance = Vector3.Distance(entityData.pos, testPos);
                }
                else
                {
                    PrebuildData prebuildData = ___factory.prebuildPool[-id];
                    proto = LDB.items.Select((int)prebuildData.protoId);
                    if (proto.prefabDesc.isBelt)
                    {
                        // ignore unbuilt belts
                        continue;
                    }
                    distance = Vector3.Distance(prebuildData.pos, testPos);
                }

                // ignore entitites that ore not (built) belts or don't have inserterPoses
                if ((proto.prefabDesc.isBelt == cachedInserter.otherIsBelt || proto.prefabDesc.insertPoses.Length > 0) && distance < maxDistance)
                {
                    otherId     = id;
                    maxDistance = distance;
                }
            }

            if (otherId != 0)
            {
                var buildingId = buildPreview.objId;

                if (buildingId == 0)
                {
                    // the original calculatePose code doesn't correctly handle calculation where one of the entity is a BuildPreview
                    // as it has objId 0 and is not registered in either the entityPool or prebuildPool
                    // To address that we override the 4 critical methods GetObjectPose/GetObjectProtoId/ObjectIsBelt/GetLocalInserts
                    // only for this specific execution of CalculatePose, by returning the expected value for the current buildPreview
                    overridePoseMethods = true;
                    overriddenProto     = buildPreview.item;
                    overriddenPose      = new Pose(absoluteBuildingPos, absoluteBuildingRot);
                }

                if (cachedInserter.incoming)
                {
                    CalculatePose(__instance, otherId, buildingId);
                }
                else
                {
                    CalculatePose(__instance, buildingId, otherId);
                }


                overridePoseMethods = false;

                bool hasNearbyPose = false;
                if (__instance.posePairs.Count > 0)
                {
                    float minDistance = 1000f;
                    PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair();

                    for (int j = 0; j < __instance.posePairs.Count; ++j)
                    {
                        var posePair = __instance.posePairs[j];
                        if (
                            (cachedInserter.incoming && cachedInserter.endSlot != posePair.endSlot) ||
                            (!cachedInserter.incoming && cachedInserter.startSlot != posePair.startSlot)
                            )
                        {
                            continue;
                        }
                        float startDistance = Vector3.Distance(posePair.startPose.position, absoluteInserterPos);
                        float endDistance   = Vector3.Distance(posePair.endPose.position, absoluteInserterPos2);
                        float poseDistance  = startDistance + endDistance;

                        if (poseDistance < minDistance)
                        {
                            minDistance   = poseDistance;
                            bestFit       = posePair;
                            hasNearbyPose = true;
                        }
                    }
                    if (hasNearbyPose)
                    {
                        // if we were able to calculate a close enough sensible pose
                        // use that instead of the (visually) imprecise default

                        absoluteInserterPos  = bestFit.startPose.position;
                        absoluteInserterPos2 = bestFit.endPose.position;

                        absoluteInserterRot  = bestFit.startPose.rotation;
                        absoluteInserterRot2 = bestFit.endPose.rotation * Quaternion.Euler(0.0f, 180f, 0.0f);

                        pickOffset   = (short)bestFit.startOffset;
                        insertOffset = (short)bestFit.endOffset;

                        startSlot = bestFit.startSlot;
                        endSlot   = bestFit.endSlot;


                        posDelta  = Quaternion.Inverse(absoluteBuildingRot) * (absoluteInserterPos - absoluteBuildingPos);
                        pos2Delta = Quaternion.Inverse(absoluteBuildingRot) * (absoluteInserterPos2 - absoluteBuildingPos);
                    }
                }
            }

            position = new InserterPosition()
            {
                cachedInserter      = cachedInserter,
                absoluteBuildingPos = absoluteBuildingPos,
                absoluteBuildingRot = absoluteBuildingRot,

                otherId = otherId,

                posDelta             = posDelta,
                pos2Delta            = pos2Delta,
                absoluteInserterPos  = absoluteInserterPos,
                absoluteInserterPos2 = absoluteInserterPos2,

                absoluteInserterRot  = absoluteInserterRot,
                absoluteInserterRot2 = absoluteInserterRot2,

                pickOffset   = pickOffset,
                insertOffset = insertOffset,

                startSlot = startSlot,
                endSlot   = endSlot,
            };


            nextPositionCache.Enqueue(position);
            return(position);
        }
        public static bool AddPrebuildDataWithComponents_Prefix(PlanetFactory __instance, PrebuildData prebuild)
        {
            if (!SimulatedWorld.Initialized)
            {
                return(true);
            }

            // If the host game called the method, we need to compute the PrebuildId ourself
            if (LocalPlayer.IsMasterClient && !FactoryManager.EventFromClient)
            {
                int nextPrebuildId = FactoryManager.GetNextPrebuildId(__instance);
                FactoryManager.SetPrebuildRequest(__instance.planetId, nextPrebuildId, LocalPlayer.PlayerId);
            }

            return(true);
        }
Beispiel #25
0
        public static void UpdateRemotePlayerDrone(NewDroneOrderPacket packet)
        {
            using (GetRemotePlayersModels(out var remotePlayersModels))
            {
                if (remotePlayersModels.TryGetValue(packet.PlayerId, out RemotePlayerModel player))
                {
                    //Setup drone of remote player based on the drone data
                    ref MechaDrone  drone      = ref player.PlayerInstance.mecha.drones[packet.DroneId];
                    MechaDroneLogic droneLogic = player.PlayerInstance.mecha.droneLogic;

                    drone.stage        = packet.Stage;
                    drone.targetObject = packet.Stage < 3 ? packet.EntityId : 0;
                    drone.movement     = droneLogic.player.mecha.droneMovement;
                    if (packet.Stage == 1)
                    {
                        drone.position = player.Movement.GetLastPosition().LocalPlanetPosition.ToVector3();
                    }
                    drone.target                    = (Vector3)MethodInvoker.GetHandler(AccessTools.Method(typeof(MechaDroneLogic), "_obj_hpos", new System.Type[] { typeof(int) })).Invoke(GameMain.mainPlayer.mecha.droneLogic, packet.EntityId);
                    drone.initialVector             = drone.position + drone.position.normalized * 4.5f + ((drone.target - drone.position).normalized + UnityEngine.Random.insideUnitSphere) * 1.5f;
                    drone.forward                   = drone.initialVector;
                    drone.progress                  = 0f;
                    player.MechaInstance.droneCount = GameMain.mainPlayer.mecha.droneCount;
                    player.MechaInstance.droneSpeed = GameMain.mainPlayer.mecha.droneSpeed;
                    Mecha myMecha = GameMain.mainPlayer.mecha;
                    if (packet.Stage == 3)
                    {
                        myMecha.droneLogic.serving.Remove(packet.EntityId);
                    }

                    if (drone.stage == 1 || drone.stage == 2)
                    {
                        //Check if target entity exists as Prebuild
                        if (GameMain.data.localPlanet.factory.prebuildPool.Length <= -packet.EntityId || GameMain.data.localPlanet.factory.prebuildPool[-packet.EntityId].id == 0)
                        {
                            return;
                        }

                        //Check target prebuild if it is same prebuild that I have. Sometimes it is same ID, but different prebuild
                        ref PrebuildData prebuildData = ref GameMain.data.localPlanet.factory.prebuildPool[-packet.EntityId];
                        if (prebuildData.pos.x != packet.EntityPos.x || prebuildData.pos.y != packet.EntityPos.y || prebuildData.pos.z != packet.EntityPos.z)
                        {
                            return;
                        }

                        //Check if my drone is already going there
                        if (!myMecha.droneLogic.serving.Contains(packet.EntityId))
                        {
                            myMecha.droneLogic.serving.Add(packet.EntityId);
                        }
                        else
                        {
                            //resolve conflict (two drones are going to the same building)
                            //find my drone that is going there
                            int priority = 0;
                            int droneId  = 0;
                            for (int i = 0; i < myMecha.droneCount; i++)
                            {
                                if (myMecha.drones[i].stage > 0 && myMecha.drones[i].targetObject == drone.targetObject)
                                {
                                    priority = DroneManager.DronePriorities[i];
                                    droneId  = i;
                                    break;
                                }
                            }

                            ref MechaDrone myDrone = ref myMecha.drones[droneId];
                            //for size comparison sqrMagnitude is fine, since sqrMagnitude, magnitude and the actual distance along the curve are all strictly monotonically increasing
                            float diff = (myDrone.position - myDrone.target).sqrMagnitude - (drone.position - drone.target).sqrMagnitude;
                            if (diff > 0 || (diff == 0 && packet.Priority > priority))
                            {
                                //my drone is further away (myMagnitude > otherMagnitude = difference positive) and has to return
                                myDrone.stage        = 3;
                                myDrone.targetObject = 0;
                            }
                            else
                            {
                                //their drone is further away (otherMagnitude > myMagnitude = difference negative) and has to return
                                drone.stage        = 3;
                                drone.targetObject = 0;
                            }
                        }
                    }
Beispiel #26
0
            public static void PlayerAction_BuildNotifyBuiltPrefix(int postObjId, PlanetAuxData ___planetAux)
            {
                var entityBuilt = pc.player.factory.entityPool[postObjId];

                ModelProto modelProto = LDB.models.Select(entityBuilt.modelIndex);
                var        prefabDesc = modelProto.prefabDesc;

                if (!prefabDesc.isInserter)
                {
                    // Check for pending inserter requests
                    if (PatchCopyInserters.pendingInserters.Count > 0)
                    {
                        var factory = pc.player.factory;
                        for (int i = pendingInserters.Count - 1; i >= 0; i--) // Reverse loop for removing found elements
                        {
                            var pi = pendingInserters[i];
                            // Is the NotifyBuilt assembler in the expected position for this pending inserter?
                            var distance = Vector3.Distance(entityBuilt.pos, pi.AssemblerPos);
                            if (distance < 0.2)
                            {
                                var assemblerId = entityBuilt.id;
                                //Debug.Log($"!!! found assembler id={assemblerId} at Pos={entityBuilt.pos} expected {pi.AssemblerPos} distance={distance}");

                                // Create inserter Prebuild data
                                var pbdata = new PrebuildData();
                                pbdata.protoId    = (short)pi.ci.protoId;
                                pbdata.modelIndex = (short)LDB.items.Select(pi.ci.protoId).ModelIndex;
                                pbdata.modelId    = factory.entityPool[pi.otherId].modelId;

                                pbdata.insertOffset = pi.ci.insertOffset;
                                pbdata.pickOffset   = pi.ci.pickOffset;
                                pbdata.filterId     = pi.ci.filterId;

                                // YukkuriC: recover absolute transforms
                                Helper.AbsTransform(entityBuilt.pos, pi.ci.posDelta, pi.ci.rot, out pbdata.pos, out pbdata.rot);
                                Helper.AbsTransform(entityBuilt.pos, pi.ci.pos2delta, pi.ci.rot2, out pbdata.pos2, out pbdata.rot2);
                                pbdata.pos  = ___planetAux.Snap(pbdata.pos, true, false);
                                pbdata.pos2 = ___planetAux.Snap(pbdata.pos2, true, false);

                                // Check the player has the item in inventory, no cheating here
                                var itemcount = pc.player.package.GetItemCount(pi.ci.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 pi.ci.protoId, ref qty);
                                    int pbCursor = factory.AddPrebuildData(pbdata); // Add the inserter request to Prebuild pool

                                    // Otherslot -1 will try to find one, otherwise could cache this from original assembler if it causes problems
                                    if (pi.ci.incoming)
                                    {
                                        factory.WriteObjectConn(-pbCursor, 0, true, assemblerId, -1); // assembler connection
                                        factory.WriteObjectConn(-pbCursor, 1, false, pi.otherId, -1); // other connection
                                    }
                                    else
                                    {
                                        factory.WriteObjectConn(-pbCursor, 0, false, assemblerId, -1); // assembler connection
                                        factory.WriteObjectConn(-pbCursor, 1, true, pi.otherId, -1);   // other connection
                                    }
                                }
                                pendingInserters.RemoveAt(i);
                            }
                        }
                    }
                }
            }
        public static void MechaDroneLogic_UpdateTargets_Prefix(MechaDroneLogic __instance, Player ___player)
        {
            if (___player.factory != null)
            {
                if (GameMain.data.hidePlayerModel)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because player model is hidden.  This is needed for compatability with the Render Distance mod.");
                    }
                    UpdateTipText("(Player hidden.)");
                    return;
                }

                if (!configEnableMod.Value)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because mod is disabled.");
                    }
                    return;
                }

                if (___player.movementState == EMovementState.Sail)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because movement state is Sail.");
                    }
                    UpdateTipText("(Waiting while Sailing.)");
                    RecallClearingDrones();
                    return;
                }

                if (___player.movementState == EMovementState.Drift && !configEnableClearingWhileDrifting)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping while drifting.");
                    }
                    UpdateTipText("(Waiting while Drifting.)");
                    return;
                }

                if (___player.movementState == EMovementState.Fly && !configEnableClearingWhileFlying)
                {
                    if (configEnableRecallWhileFlying)
                    {
                        if (configEnableDebug)
                        {
                            Logger.LogInfo("Recalling drones.");
                        }
                        RecallClearingDrones();
                    }
                    else if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping while flying.");
                    }
                    UpdateTipText("(Waiting while Flying.)");
                    return;
                }

                if (___player.mecha.coreEnergy < ___player.mecha.droneEjectEnergy)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping because of insufficient mecha energy to eject a drone.");
                    }
                    UpdateTipText("(Waiting for ejection energy.)");
                    return;
                }

                if ((___player.planetData.type == EPlanetType.None && !configEnableClearingPlanetGeneric) ||
                    (___player.planetData.type == EPlanetType.Vocano && !configEnableClearingPlanetVocano) ||
                    (___player.planetData.type == EPlanetType.Ocean && !configEnableClearingPlanetOcean) ||
                    (___player.planetData.type == EPlanetType.Desert && !configEnableClearingPlanetDesert) ||
                    (___player.planetData.type == EPlanetType.Ice && !configEnableClearingPlanetIce))
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping planet type " + ___player.planetData.type.ToString());
                    }
                    UpdateTipText("(Waiting on this planet type.)");
                    return;
                }

                int totalDroneTaskingCount = getTotalDroneTaskingCount();
                if (totalDroneTaskingCount >= Math.Min(configMaxClearingDroneCount, ___player.mecha.droneCount))
                {
                    if (configEnableDebug)
                    {
                        var sbc = new StringBuilder();
                        sbc.AppendFormat("Skipping due to number of drone assignments: totalDroneTaskingCount={0}, configMaxClearingDroneCount={1}, player.mecha.droneCount={2}, player.mecha.idleDroneCount={3}",
                                         totalDroneTaskingCount, configMaxClearingDroneCount, ___player.mecha.droneCount, ___player.mecha.idleDroneCount);
                        Logger.LogInfo(sbc.ToString());
                    }
                    UpdateTipText("(Available drones assigned.)");
                    return;
                }

                if (___player.mecha.coreEnergy / ___player.mecha.coreEnergyCap < configReservedPower)
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("Skipping due to low power.");
                    }
                    UpdateTipText("(Waiting for energy.)");
                    return;
                }

                if (configCollectResourcesFlag)  // ... check configReservedInventorySpace
                {
                    uint numEmptyInventorySlots = 0;
                    for (int gridIdx = 0; gridIdx < ___player.package.size; ++gridIdx)
                    {
                        if (___player.package.grids[gridIdx].count == 0)
                        {
                            numEmptyInventorySlots++;
                        }
                    }
                    if (numEmptyInventorySlots < configReservedInventorySpace)
                    {
                        if (configEnableDebug)
                        {
                            Logger.LogInfo("Too few inventory slots");
                        }
                        UpdateTipText("(Waiting for inventory space.)");
                        return;
                    }
                }

                float closestVegeDistance = ___player.mecha.buildArea * configLimitClearingDistance * 2;
                int   closestVegeId       = -1;
                foreach (VegeData vegeData in ___player.factory.vegePool)
                {
                    VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId);
                    // vegeProto.Type == EVegeType.Detail covers grass and small minable rocks.  So the check includes vegeProto.MiningItem.Length instead.
                    if (vegeProto != null && vegeProto.MiningItem.Length > 0)
                    {
                        if ((vegeProto.Type == EVegeType.Tree && !configEnableClearingItemTree) ||
                            (vegeProto.Type == EVegeType.Stone && !configEnableClearingItemStone) ||
                            (vegeProto.Type == EVegeType.Detail && !configEnableClearingItemDetail) ||
                            (vegeProto.Type == EVegeType.Ice && !configEnableClearingItemIce))
                        {
                            continue;
                        }

                        float distanceToVege = Vector3.Distance(___player.position, vegeData.pos);
                        if (distanceToVege < closestVegeDistance)
                        {
                            bool vegeBeingProcessedFlag = false;
                            foreach (PrebuildData prebuild in ___player.factory.prebuildPool)
                            {
                                if (isDroneClearingPrebuild(prebuild) && prebuild.upEntity == vegeData.id)
                                {
                                    vegeBeingProcessedFlag = true;
                                    break;
                                }
                            }

                            if (!vegeBeingProcessedFlag)
                            {
                                closestVegeDistance = distanceToVege;
                                closestVegeId       = vegeData.id;
                            }
                        }
                    }
                }

                if (closestVegeDistance <= ___player.mecha.buildArea * configLimitClearingDistance)
                {
                    VegeData  vegeData  = ___player.factory.vegePool[closestVegeId];
                    VegeProto vegeProto = LDB.veges.Select((int)vegeData.protoId);

                    //var sb = new StringBuilder();
                    //sb.AppendFormat("Initiating mining of {0} to get {1} at power level {2}", vegeProto.Type.ToString(), LDB.items.Select(vegeProto.MiningItem[0]).name, ___player.mecha.coreEnergy / ___player.mecha.coreEnergyCap);
                    //Logger.LogInfo(sb.ToString());

                    PrebuildData prebuild = default;
                    prebuild.protoId  = -1;
                    prebuild.modelId  = 0; // Saves always open as 0
                    prebuild.recipeId = -1;
                    prebuild.refCount = 0;
                    prebuild.upEntity = vegeData.id;
                    prebuild.pos      = prebuild.pos2 = vegeData.pos;
                    prebuild.rot      = vegeData.rot;

                    // This operation will cause a drone to be assigned by MechaDroneLogic.UpdateTargets.
                    int prebuildId = ___player.factory.AddPrebuildData(prebuild);
                    UpdateTipText("(Assigning drones.)");
                }
                else
                {
                    if (configEnableDebug)
                    {
                        Logger.LogInfo("No enabled items within configured distance.");
                    }
                    UpdateTipText("(No more items in range.)");
                }
            }
        }
Beispiel #28
0
        public static InserterPosition GetPositions(PlayerAction_Build actionBuild, InserterCopy copiedInserter, float yawRad, int pasteIndex, bool connectToPasted)
        {
            var pastedEntities = BlueprintManager.pastedEntities;
            var player         = actionBuild.player;

            var pastedReferenceEntityId = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.referenceBuildingId;

            var pastedReferenceEntity             = pastedEntities[pastedReferenceEntityId];
            var pastedReferenceEntityBuildPreview = pastedReferenceEntity.buildPreview;

            Quaternion absoluteBuildingRot    = pastedReferenceEntity.pose.rotation;
            Vector3    absoluteBuildingPos    = pastedReferenceEntity.pose.position;
            Vector2    absoluteBuildingPosSpr = absoluteBuildingPos.ToSpherical();

            var     posDelta            = copiedInserter.posDelta.Rotate(yawRad, copiedInserter.posDeltaCount);
            Vector3 absoluteInserterPos = absoluteBuildingPosSpr
                                          .ApplyDelta(posDelta, copiedInserter.posDeltaCount)
                                          .ToCartesian(GameMain.localPlanet.realRadius + 0.2f);

            var     pos2Delta            = copiedInserter.pos2Delta.Rotate(yawRad, copiedInserter.pos2DeltaCount);
            Vector3 absoluteInserterPos2 = absoluteBuildingPosSpr
                                           .ApplyDelta(pos2Delta, copiedInserter.pos2DeltaCount)
                                           .ToCartesian(GameMain.localPlanet.realRadius + 0.2f);

            if (pastedReferenceEntity.sourceBuilding == null)
            {
                absoluteBuildingRot = Maths.SphericalRotation(absoluteBuildingPos, yawRad * Mathf.Rad2Deg);
            }

            Quaternion absoluteInserterRot  = absoluteBuildingRot * copiedInserter.rot;
            Quaternion absoluteInserterRot2 = absoluteBuildingRot * copiedInserter.rot2;

            int startSlot = copiedInserter.startSlot;
            int endSlot   = copiedInserter.endSlot;

            short pickOffset   = copiedInserter.pickOffset;
            short insertOffset = copiedInserter.insertOffset;

            var referenceObjId = pastedReferenceEntity.objId;

            var otherPastedId = 0;
            var otherEntityId = 0;

            var otherObjId = 0;

            var pastedPickTargetId   = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.pickTarget;
            var pastedInsertTargetId = BlueprintManager_Paste.PASTE_INDEX_MULTIPLIER * pasteIndex + copiedInserter.insertTarget;


            if (pastedEntities.ContainsKey(pastedPickTargetId) && pastedEntities.ContainsKey(pastedInsertTargetId))
            {
                // cool we copied both source and target of the inserters
                otherPastedId = pastedPickTargetId == pastedReferenceEntityId ? pastedInsertTargetId : pastedPickTargetId;
                otherObjId    = pastedEntities[otherPastedId].objId;
            }
            else
            {
                // Find the other entity at the target location
                var nearcdLogic = actionBuild.nearcdLogic;
                var factory     = actionBuild.factory;
                // 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     otherPosDelta = copiedInserter.otherPosDelta.Rotate(yawRad, copiedInserter.otherPosDeltaCount);
                Vector3 testPos       = absoluteBuildingPosSpr
                                        .ApplyDelta(otherPosDelta, copiedInserter.otherPosDeltaCount)
                                        .SnapToGrid();

                if (connectToPasted)
                {
                    var compatibleType = copiedInserter.otherIsBelt ? EPastedType.BELT : EPastedType.BUILDING;
                    foreach (var pastedEntity in BlueprintManager.pastedEntities.Values)
                    {
                        // find the first compatible entity that will not been removed, that has in the same/previous/next pasteIndex and that is near enough
                        if (pastedEntity.type == compatibleType &&
                            pastedEntity.status != EPastedStatus.REMOVE &&
                            pastedEntity.pasteId != pastedReferenceEntityId &&
                            Math.Abs(pastedEntity.pasteIndex - pasteIndex) <= 1 &&
                            Vector3.Distance(pastedEntity.pose.position, testPos) < 0.2)
                        {
                            // found a pasted entity that we can connect to !
                            otherPastedId = pastedEntity.pasteId;
                            otherObjId    = pastedEntity.objId;
                            break;
                        }
                    }
                }

                if (otherObjId == 0)
                {
                    int[] _nearObjectIds = new int[256];

                    // find building nearby
                    int found = nearcdLogic.GetBuildingsInAreaNonAlloc(testPos, 0.2f, _nearObjectIds, false);

                    // find nearest building
                    float maxDistance = 1f;

                    for (int x = 0; x < found; x++)
                    {
                        var       id = _nearObjectIds[x];
                        float     distance;
                        ItemProto proto;
                        if (id == 0 || id == pastedReferenceEntityBuildPreview.objId)
                        {
                            continue;
                        }
                        else if (id > 0)
                        {
                            EntityData entityData = factory.entityPool[id];
                            proto = LDB.items.Select((int)entityData.protoId);
                            // ignore buildings without inserter poses
                            if (!proto.prefabDesc.isBelt && proto.prefabDesc.insertPoses.Length == 0)
                            {
                                continue;
                            }

                            distance = Vector3.Distance(entityData.pos, testPos);
                        }
                        else
                        {
                            PrebuildData prebuildData = factory.prebuildPool[-id];
                            proto = LDB.items.Select((int)prebuildData.protoId);

                            // ignore unbuilt belts and buildings without inserter poses
                            if (proto.prefabDesc.isBelt || proto.prefabDesc.insertPoses.Length == 0)
                            {
                                continue;
                            }

                            distance = Vector3.Distance(prebuildData.pos, testPos);
                        }

                        // ignore entitites that ore not (built) belts or don't have inserterPoses
                        if ((proto.prefabDesc.isBelt == copiedInserter.otherIsBelt || proto.prefabDesc.insertPoses.Length > 0) && distance < maxDistance)
                        {
                            otherObjId  = otherEntityId = id;
                            maxDistance = distance;
                        }
                    }
                }
            }



            if (otherObjId != 0)
            {
                if (copiedInserter.incoming)
                {
                    InserterPoses.CalculatePose(actionBuild, otherObjId, referenceObjId);
                }
                else
                {
                    InserterPoses.CalculatePose(actionBuild, referenceObjId, otherObjId);
                }


                bool hasNearbyPose = false;

                if (actionBuild.posePairs.Count > 0)
                {
                    float minDistance = 1000f;
                    PlayerAction_Build.PosePair bestFit = new PlayerAction_Build.PosePair();

                    for (int j = 0; j < actionBuild.posePairs.Count; ++j)
                    {
                        var posePair = actionBuild.posePairs[j];
                        if (
                            (copiedInserter.incoming && copiedInserter.endSlot != posePair.endSlot && copiedInserter.endSlot != -1) ||
                            (!copiedInserter.incoming && copiedInserter.startSlot != posePair.startSlot && copiedInserter.startSlot != -1)
                            )
                        {
                            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  = bestFit.startPose.position.ToSpherical() - absoluteBuildingPosSpr;
                        pos2Delta = bestFit.endPose.position.ToSpherical() - absoluteBuildingPosSpr;
                    }
                }
            }

            InserterPosition position = new InserterPosition()
            {
                copiedInserter      = copiedInserter,
                absoluteBuildingPos = absoluteBuildingPos,
                absoluteBuildingRot = absoluteBuildingRot,

                posDelta             = posDelta,
                pos2Delta            = pos2Delta,
                absoluteInserterPos  = absoluteInserterPos,
                absoluteInserterPos2 = absoluteInserterPos2,

                absoluteInserterRot  = absoluteInserterRot,
                absoluteInserterRot2 = absoluteInserterRot2,

                pickOffset   = pickOffset,
                insertOffset = insertOffset,

                startSlot = startSlot,
                endSlot   = endSlot,

                condition = EBuildCondition.Ok
            };

            if (otherEntityId != 0)
            {
                Vector3 forward = absoluteInserterPos2 - absoluteInserterPos;

                Pose pose;
                pose.position = Vector3.Lerp(absoluteInserterPos, absoluteInserterPos2, 0.5f);
                pose.rotation = Quaternion.LookRotation(forward, absoluteInserterPos.normalized);


                var colliderData = copiedInserter.itemProto.prefabDesc.buildColliders[0];
                colliderData.ext = new Vector3(colliderData.ext.x, colliderData.ext.y, Vector3.Distance(absoluteInserterPos2, absoluteInserterPos) * 0.5f + colliderData.ext.z - 0.5f);

                if (copiedInserter.otherIsBelt)
                {
                    if (copiedInserter.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;
                Collider[] _tmp_cols       = new Collider[16];
                int        collisionsFound = Physics.OverlapBoxNonAlloc(colliderData.pos, colliderData.ext, _tmp_cols, colliderData.q, mask, QueryTriggerInteraction.Collide);

                PlanetPhysics physics2 = player.planetData.physics;
                for (int j = 0; j < collisionsFound; j++)
                {
                    physics2.GetColliderData(_tmp_cols[j], out ColliderData colliderData2);
                    if (colliderData2.objId != 0 && colliderData2.objId != otherEntityId && colliderData2.usage == EColliderUsage.Build)
                    {
                        position.condition = EBuildCondition.Collide;
                        otherPastedId      = 0;
                        otherEntityId      = 0;

                        break;
                    }
                }
            }

            position.inputEntityId = copiedInserter.incoming ? otherEntityId : 0;
            position.inputPastedId = copiedInserter.incoming ? otherPastedId : pastedReferenceEntityId;

            position.outputEntityId = copiedInserter.incoming ? 0 : otherEntityId;
            position.outputPastedId = copiedInserter.incoming ? pastedReferenceEntityId : otherPastedId;

            return(position);
        }
 public static bool isDroneClearingPrebuild(PrebuildData prebuild)
 {
     return(prebuild.protoId == -1 && prebuild.modelId == 0 && prebuild.recipeId == -1);
 }
Beispiel #30
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;
        }