XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

AutoMiningScript

【SpaceEngineer】全自动挖矿脚本

公开
关注 0 Fork 0 Star 0
UTF-8
using System;
using System.Collections.Generic;
using System.Reflection;
using Sandbox.ModAPI.Ingame;
using VRage;
using VRage.Game.ModAPI.Ingame;
using Xunit;
using P=AutoMiningScript.Program;

namespace AutoMiningScript.Tests
{
    public class SorterSamplingTests
    {
        static readonly BindingFlags Private=BindingFlags.Instance|BindingFlags.NonPublic;
        static void Call(object target,string name)=>target.GetType().GetMethod(name,Private).Invoke(target,null);
        static void Put(List<MyInventoryItem> items,double amount)
        {
            items.Clear();if(amount<=0)return;object value=default(MyInventoryItem);
            typeof(MyInventoryItem).GetField("Type").SetValue(value,MyItemType.MakeOre("Stone"));
            typeof(MyInventoryItem).GetField("Amount").SetValue(value,(MyFixedPoint)amount);
            items.Add((MyInventoryItem)value);
        }
        sealed class Rig
        {
            public readonly MinerStateTests.MinerRig R=new MinerStateTests.MinerRig();
            public readonly List<MyInventoryItem> First=new List<MyInventoryItem>(),Second=new List<MyInventoryItem>(),Port=new List<MyInventoryItem>(),Buffer=new List<MyInventoryItem>();
            public readonly Stub<IMyConveyorSorter> Sorter;
            public Rig()
            {
                R.Task();R.Hardware.InventoryBlocks.Clear();
                Add<IMyShipDrill>(First);Add<IMyShipDrill>(Second);Add<IMyShipConnector>(Port);
                Sorter=Add<IMyConveyorSorter>(Buffer).Set("Enabled",true).Set("DrainAll",true);
                R.Hardware.SetSampling(true);
            }
            Stub<T> Add<T>(List<MyInventoryItem> items) where T:class,IMyTerminalBlock
            {
                var inventory=new Stub<IMyInventory>().Set("CurrentMass",(MyFixedPoint)0).Set("CurrentVolume",(MyFixedPoint)0).Set("MaxVolume",(MyFixedPoint)100)
                    .Method("get_ItemCount",a=>items.Count).Method("GetItems",a=>{((List<MyInventoryItem>)a[0]).AddRange(items);return null;});
                var block=new Stub<T>().Set("CubeGrid",R.Program.Me.CubeGrid).Set("HasInventory",true).Set("InventoryCount",1).Method("GetInventory",a=>inventory.Value);
                R.Hardware.InventoryBlocks.Add(block.Value);return block;
            }
            public void Amounts(double first,double second,double buffer)
            {Put(First,first);Put(Second,second);Put(Buffer,buffer);}
            public void Scan(P.FlightState state=P.FlightState.Drilling)
            {R.Program.Now+=.5;R.Resources.Update(.5,state,0,0);}
            public void Sample()=>Call(R.Miner,"SampleOre");
            public void Baseline()=>Call(R.Miner,"ResetSample");
        }

        [Fact]
        public void ActualDrillToSorterTransfersPreserveOreAndAllowAConfirmedDiscovery()
        {
            var r=new Rig();
            // Real miner 7, 2026-09-15: inventory-03 JSONL lines 348/349 and 351/352.
            // Two drill buffers transfer to central sorter 95026802382736041.
            r.Amounts(93.481720,424.960224,45.786960);r.Scan(P.FlightState.Align);r.Baseline();
            Assert.Equal(564.228904,r.R.Resources.Ores["Stone"],5);
            r.Amounts(93.481720,0,470.747184);r.Scan();
            Assert.Equal(564.228904,r.R.Resources.OreAmount,5);Assert.True(r.R.Resources.SamplingValid);
            r.Sample();r.Sample();Assert.DoesNotContain(r.R.Sent,p=>p.Kind=="RESULT");

            r.Amounts(704.451512,1232.909312,470.747184);r.Scan();
            Assert.Equal(2408.108008,r.R.Resources.Ores["Stone"],5);Assert.True(r.R.Resources.SamplingValid);
            r.Sample();Assert.DoesNotContain(r.R.Sent,p=>p.Kind=="RESULT");
            r.Amounts(678.375836,0,1729.732172);r.Scan();
            Assert.Equal(2408.108008,r.R.Resources.Ores["Stone"],5);Assert.True(r.R.Resources.SamplingValid);
            r.Sample();var report=P.JobReport.FromIni(Assert.Single(r.R.Sent,p=>p.Kind=="RESULT").Body);
            Assert.Equal("Discovery",report.Outcome);Assert.Equal("Stone",report.Ore);
            Assert.True(r.Sorter.Value.Enabled);Assert.True(r.Sorter.Value.DrainAll);
        }

        [Fact]
        public void ActualLossFromASorterStillInvalidatesAndLatchesTheSample()
        {
            var r=new Rig();r.Amounts(10,0,100);r.Scan();r.Baseline();
            r.Amounts(10,0,80);r.Scan();Assert.False(r.R.Resources.SamplingValid);
            r.Amounts(10,0,100);r.Scan();Assert.False(r.R.Resources.SamplingValid);
            r.Sample();Assert.DoesNotContain(r.R.Sent,p=>p.Kind=="RESULT");
            Assert.True((bool)typeof(P.MinerController).GetField("invalidSample",Private).GetValue(r.R.Miner));
            r.R.Resources.ResetSampleValidation();r.Scan();Assert.True(r.R.Resources.SamplingValid);
        }

        [Fact]
        public void PreexistingSorterOreIsInTheAlignmentBaselineAndCannotBecomeANewDiscovery()
        {
            var r=new Rig();r.Amounts(0,0,100);r.Scan(P.FlightState.Align);r.Baseline();
            r.Amounts(100,0,0);r.Scan();Assert.True(r.R.Resources.SamplingValid);
            r.Sample();r.Sample();Assert.DoesNotContain(r.R.Sent,p=>p.Kind=="RESULT");
            Assert.Equal(100,r.R.Resources.Ores["Stone"]);
        }

        [Fact]
        public void AForeignSorterCannotBeCountedAsLocalMinedOre()
        {
            var r=new Rig();r.Amounts(0,0,100);
            r.Sorter.Set("CubeGrid",new Stub<IMyCubeGrid>().Set("EntityId",999L).Value);
            r.Scan();Assert.Empty(r.R.Resources.Ores);Assert.False(r.R.Resources.SamplingValid);
            r.Sample();Assert.DoesNotContain(r.R.Sent,p=>p.Kind=="RESULT");
        }
    }
}