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

AutoMiningScript

【SpaceEngineer】全自动挖矿脚本

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

namespace AutoMiningScript.Tests
{
    public class UnreachableSurveyTests
    {
        static P.TaskPlanner Planner() => new P.TaskPlanner(TestRig.Program());
        static void Drain(P.TaskPlanner p) {for(int n=0;n<1024;n++)p.Advance();}
        static P.TaskPlanner Survey(bool complete=true)
        {
            var p=Planner();p.Survey(Vector3D.Zero,Vector3D.Zero,Vector3D.Forward,Vector3D.Up,250);
            if(complete)Drain(p);return p;
        }
        static void Block(P.TaskPlanner p,P.Job j)
        {
            p.SetOwner(j,"miner-7");
            p.Report(j,new P.JobReport {JobId=j.Id,Outcome="Blocked",EntryUnreachable=true,Message="machine flag, not a localized reason"});
        }

        [Fact]
        public void FlagRoundTripsAndLegacyMessagesAndJobsDefaultToFalse()
        {
            var p=Survey();var job=p.Jobs[0];job.EntryUnreachable=true;
            var body=job.ToIni();Assert.True(P.Job.FromIni(body).EntryUnreachable);
            body.Delete("job","EntryUnreachable");Assert.False(P.Job.FromIni(body).EntryUnreachable);
            var report=new P.JobReport {JobId=job.Id,Outcome="Blocked",EntryUnreachable=true};
            body=report.ToIni();Assert.True(P.JobReport.FromIni(body).EntryUnreachable);
            body.Delete("result","EntryUnreachable");Assert.False(P.JobReport.FromIni(body).EntryUnreachable);
        }

        [Fact]
        public void UnreachableEntrySkipsItsFortyTwoRaysWithoutClaimingAnyScan()
        {
            var p=Survey();var source=p.Jobs[0];Block(p,source);
            // The dispatcher cannot select a sibling before the bounded summary runs.
            Assert.Equal(-1,p.JobPriority(p.Jobs[1]));
            Drain(p);Assert.Equal(252,p.PendingCount);Assert.Empty(p.OwnedJobs);
            Assert.All(p.Jobs.Where(j=>j.Entry==source.Entry),j=>{Assert.Equal("Blocked",j.Outcome);Assert.Null(j.Scan);});
            Assert.All(p.Jobs.Where(j=>j.Entry!=source.Entry),j=>Assert.False(P.TaskPlanner.Finished(j)));
            p.Report(source,new P.JobReport {Outcome="Blocked",EntryUnreachable=true});Drain(p);
            Assert.Equal(252,p.PendingCount);
        }

        [Fact]
        public void OrdinaryRayOrCameraFailureDoesNotBlockOtherDirections()
        {
            var p=Survey();var source=p.Jobs[0];
            p.Report(source,new P.JobReport {Outcome="Blocked",Message=P.L.MinerSurveyEntryStalled});Drain(p);
            Assert.Equal(293,p.PendingCount);Assert.False(source.EntryUnreachable);
            Assert.Equal(0,p.JobPriority(p.Jobs[1]));Assert.False(P.TaskPlanner.Finished(p.Jobs[1]));
        }

        [Fact]
        public void OtherOwnerCanStillDiscoverAndDrillAtTheBlockedObservation()
        {
            var p=Survey();var source=p.Jobs[0];var active=p.Jobs[1];p.SetOwner(active,"miner-2");
            Block(p,source);Drain(p);Assert.Equal(active,p.OwnedJobs["miner-2"]);
            Assert.False(P.TaskPlanner.Finished(active));Assert.Equal(253,p.PendingCount);
            // A real surface report remains useful even if another miner could not approach.
            p.Report(active,new P.JobReport {Outcome="SurveyHit",EntryUnreachable=true,Position=active.Entry+Vector3D.Forward*10,Direction=Vector3D.Forward,Up=Vector3D.Up,EntityId=42});
            Drain(p);Assert.Equal("SurveyHit",active.Outcome);Assert.False(active.EntryUnreachable);
            var holes=p.Jobs.Where(j=>j.Kind==P.JobKind.Probe).ToList();Assert.Equal(145,holes.Count);
            Assert.All(holes,j=>{Assert.True(p.JobPriority(j)>0);Assert.False(P.TaskPlanner.Finished(j));});
            Assert.Equal(252+holes.Count,p.PendingCount);Assert.Empty(p.OwnedJobs);
        }

        [Fact]
        public void SameCoordinatesInAnotherRegionAndNearbyEntriesRemainAvailable()
        {
            var p=Survey();var source=p.Jobs[0];var nearby=p.Jobs[1];nearby.Entry+=Vector3D.Right*.001;
            p.Survey(Vector3D.Zero,Vector3D.Zero,Vector3D.Forward,Vector3D.Up,250);Drain(p);
            p.Manual(source.Entry,Vector3D.Forward,Vector3D.Up,6,6,10);Drain(p);
            Block(p,source);Drain(p);
            Assert.False(P.TaskPlanner.Finished(nearby));Assert.Equal(0,p.JobPriority(nearby));
            Assert.All(p.Jobs.Where(j=>j.RegionId!=source.RegionId),j=>Assert.False(P.TaskPlanner.Finished(j)));
        }

        [Fact]
        public void EarlyBlockSurvivesReloadAndAlsoSkipsRaysGeneratedLater()
        {
            var p=Survey(false);Assert.InRange(p.Jobs.Count,1,8);var source=p.Jobs[0];Block(p,source);
            var save=new MyIni();p.Save(save);var restored=Planner();restored.Load(save);
            Drain(restored);Assert.Equal(294,restored.Jobs.Count);Assert.Equal(252,restored.PendingCount);
            Assert.True(restored.Find(source.Id).EntryUnreachable);
            Assert.All(restored.Jobs.Where(j=>j.Entry==source.Entry),j=>{Assert.Equal("Blocked",j.Outcome);Assert.Null(j.Scan);});
        }

        [Fact]
        public void CheckpointAlreadyInProgressRecordsSkippedSiblingsAndSourceFlag()
        {
            var p=Survey();var save=new MyIni();Assert.False(p.Checkpoint(save));
            Block(p,p.Jobs[0]);Drain(p);bool complete=false;
            for(int n=0;n<1024&&!complete;n++)complete=p.Checkpoint(save);
            Assert.True(complete);var restored=Planner();restored.Load(save);Drain(restored);
            Assert.Equal(252,restored.PendingCount);Assert.True(restored.Jobs[0].EntryUnreachable);
            Assert.All(restored.Jobs.Take(42),j=>Assert.Equal("Blocked",j.Outcome));
        }

        [Fact]
        public void WholeBlockedSearchIsIncompleteAndNeverCreatesCoverage()
        {
            var p=Survey();foreach(var group in p.Jobs.GroupBy(j=>j.Entry))Block(p,group.First());
            Drain(p);Assert.Equal(0,p.PendingCount);Assert.Equal("Sampling incomplete: blocked observations",p.Regions[0].Status);
            Assert.All(p.Jobs,j=>{Assert.Equal("Blocked",j.Outcome);Assert.Null(j.Scan);});
            p.ClearTasks();p.Survey(Vector3D.Zero,Vector3D.Zero,Vector3D.Forward,Vector3D.Up,250);Drain(p);
            Assert.Equal(294,p.PendingCount);Assert.All(p.Jobs,j=>Assert.Equal(0,p.JobPriority(j)));
        }

        [Fact]
        public void OccupiedSiblingIsSkippedOnlyAfterItsOwnerReleasesIt()
        {
            var p=Survey();var active=p.Jobs[1];p.SetOwner(active,"miner-2");Block(p,p.Jobs[0]);Drain(p);
            Assert.Equal(253,p.PendingCount);p.SetOwner(active,"");
            Assert.Equal(-1,p.JobPriority(active));Assert.Equal(252,p.PendingCount);Assert.Empty(p.OwnedJobs);
        }

        [Fact]
        public void SkippingYieldsToBudgetButAssignmentStillCannotTakeBlockedEntry()
        {
            var program=TestRig.Program();var runtime=new Stub<IMyGridProgramRuntimeInfo>().Set("MaxInstructionCount",50000).Set("CurrentInstructionCount",0);
            TestRig.SetBase(program,"Runtime",runtime.Value);var p=new P.TaskPlanner(program);
            p.Survey(Vector3D.Zero,Vector3D.Zero,Vector3D.Forward,Vector3D.Up,250);Drain(p);Block(p,p.Jobs[0]);
            runtime.Set("CurrentInstructionCount",30000);p.Advance();Assert.Equal(293,p.PendingCount);
            runtime.Set("CurrentInstructionCount",0);Assert.Equal(-1,p.JobPriority(p.Jobs[1]));Drain(p);Assert.Equal(252,p.PendingCount);
        }
    }
}