From 9d8712c62fc6adefbbfdba0312f4daec5794639d Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sat, 2 Dec 2023 14:19:21 +0800 Subject: [PATCH 01/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E4=B8=A5=E9=87=8D=E7=9A=84=E4=BB=A3=E7=A0=81=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E4=BC=9A=E5=AE=A2=E5=AE=A4=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E8=A2=AB=E6=AD=A3=E7=A1=AE=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Simulator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 3692ffd..57ccd59 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -178,7 +178,7 @@ public Office Office { } public Reception Reception { get => (Reception)Facilities[2]!; - private set => Facilities[3] = value; + private set => Facilities[2] = value; } public Training Training { get => (Training)Facilities[3]!; From 275f13dd9b3f2d6638fd8292f25d30635c20e932 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sat, 2 Dec 2023 15:00:20 +0800 Subject: [PATCH 02/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=96=87=E8=96=87?= =?UTF-8?q?=E5=AE=89=E5=A8=9C=E3=80=81=E7=87=95=E5=B0=BE=E3=80=81=E7=81=B5?= =?UTF-8?q?=E7=9F=A5=E5=9F=BA=E5=BB=BA=E6=8A=80=E8=83=BD=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Flametail.cs | 2 +- InfrastSim/TimeDriven/Operators/Gnosis.cs | 2 +- InfrastSim/TimeDriven/Operators/Viviana.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/InfrastSim/TimeDriven/Operators/Flametail.cs b/InfrastSim/TimeDriven/Operators/Flametail.cs index d367cc6..e482bc4 100644 --- a/InfrastSim/TimeDriven/Operators/Flametail.cs +++ b/InfrastSim/TimeDriven/Operators/Flametail.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter control && !IsTired) { - control.ExtraMoodModifier.SetValue(Name, 0.05); + control.ExtraMoodModifier.SetValue(Name, -0.05); if (Upgraded >= 2) { foreach (var op in simu.ManufacturingStations.SelectMany(t => t.WorkingOperators)) { diff --git a/InfrastSim/TimeDriven/Operators/Gnosis.cs b/InfrastSim/TimeDriven/Operators/Gnosis.cs index 4efd325..a25fed6 100644 --- a/InfrastSim/TimeDriven/Operators/Gnosis.cs +++ b/InfrastSim/TimeDriven/Operators/Gnosis.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { if (Facility is ControlCenter control && !IsTired) { var amount = control.GroupMemberCount("喀兰贸易"); - control.ExtraMoodModifier.SetValue(Name, amount * 0.05); + control.ExtraMoodModifier.SetValue(Name, amount * -0.05); if (Upgraded >= 2) { foreach (var op in simu.TradingStations.SelectMany(t => t.WorkingOperators)) { diff --git a/InfrastSim/TimeDriven/Operators/Viviana.cs b/InfrastSim/TimeDriven/Operators/Viviana.cs index 1d04ce0..3b7fa19 100644 --- a/InfrastSim/TimeDriven/Operators/Viviana.cs +++ b/InfrastSim/TimeDriven/Operators/Viviana.cs @@ -7,7 +7,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter control && !IsTired) { - control.ExtraMoodModifier.SetValue(Name, 0.05); + control.ExtraMoodModifier.SetValue(Name, -0.05); if (Upgraded >= 2) { var ops = simu.ManufacturingStations.SelectMany(fac => fac.WorkingOperators); From ba3a92f427534b7cf8f217b9bd9e2591f3efd538 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sat, 2 Dec 2023 17:18:21 +0800 Subject: [PATCH 03/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=B0=E9=85=BF?= =?UTF-8?q?=E3=80=81=E5=B7=AB=E6=81=8B=E6=8A=80=E8=83=BD=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=AE=BF=E8=88=8D=E3=80=81=E6=B5=81?= =?UTF-8?q?=E6=98=8E=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Dormitory.cs | 5 +++-- InfrastSim/TimeDriven/Operators/Coldshot.cs | 2 +- InfrastSim/TimeDriven/Operators/Lumen.cs | 2 +- InfrastSim/TimeDriven/Operators/Shamare.cs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/InfrastSim/TimeDriven/Dormitory.cs b/InfrastSim/TimeDriven/Dormitory.cs index 5ec9a92..46aaf6d 100644 --- a/InfrastSim/TimeDriven/Dormitory.cs +++ b/InfrastSim/TimeDriven/Dormitory.cs @@ -66,8 +66,9 @@ public override void Resolve(Simulator simu) { simu.Delay((simu) => { foreach (var op in Operators) { - op.MoodConsumeRate.SetValue("dorm-extra", DormMoodModifier + -0.0004 * Atmosphere); - op.MoodConsumeRate.Disable("control-center-mod"); + op.MoodConsumeRate.SetValue("dorm-atmosphere", -0.0004 * Atmosphere); + op.MoodConsumeRate.SetValue("dorm-extra", DormMoodModifier); + op.MoodConsumeRate.Disable("control-center"); op.MoodConsumeRate.Disable("control-center-extra"); } }, Priority.Facility); diff --git a/InfrastSim/TimeDriven/Operators/Coldshot.cs b/InfrastSim/TimeDriven/Operators/Coldshot.cs index 1726e58..ed57b08 100644 --- a/InfrastSim/TimeDriven/Operators/Coldshot.cs +++ b/InfrastSim/TimeDriven/Operators/Coldshot.cs @@ -13,7 +13,7 @@ public override void Resolve(Simulator simu) { var count = dorm.Operators.Where(op => !op.IsFullOfEnergy).Count(); if (count == 1) { dorm.SetVipMoodModifier(-0.8); - } else { + } else if (count > 1) { var amount = -0.8 / count; dorm.SetDormMoodModifier(amount); } diff --git a/InfrastSim/TimeDriven/Operators/Lumen.cs b/InfrastSim/TimeDriven/Operators/Lumen.cs index 32b4db8..5d0a0fb 100644 --- a/InfrastSim/TimeDriven/Operators/Lumen.cs +++ b/InfrastSim/TimeDriven/Operators/Lumen.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { simu.Delay(simu => { foreach (var op in dorm.Operators) { var amount = simu.PowerStationsCount() * -0.05 + (Upgraded >= 2 ? -0.15 : -0.1); - op.MoodConsumeRate.SetIfLesser("dorm-extra", amount + -0.0004 * dorm.Atmosphere); + op.MoodConsumeRate.SetIfLesser("dorm-extra", amount); } }); } diff --git a/InfrastSim/TimeDriven/Operators/Shamare.cs b/InfrastSim/TimeDriven/Operators/Shamare.cs index 729f4ea..fada339 100644 --- a/InfrastSim/TimeDriven/Operators/Shamare.cs +++ b/InfrastSim/TimeDriven/Operators/Shamare.cs @@ -18,7 +18,7 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MinValue = 0; op.EfficiencyModifier.MaxValue = 0; } - op.MoodConsumeRate.SetValue(Name, 0.25); + op.MoodConsumeRate.AddValue(Name, 0.25); } EfficiencyModifier.SetValue(Name, (trading.Operators.Count() - 1) * 0.45); }, Priority.Shamare); From 9783796296dc9f40d431beb8c8993faec9df71bf Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sat, 2 Dec 2023 18:01:43 +0800 Subject: [PATCH 04/39] =?UTF-8?q?=E9=87=8D=E8=A6=81=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9A=E4=BD=BF=E7=94=A8=E7=A8=8D=E9=95=BF?= =?UTF-8?q?=E4=B8=8E=E9=A2=84=E4=BC=B0=E6=97=B6=E9=97=B4=E7=89=87=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E9=97=B4=EF=BC=8C=E4=BB=A5=E9=98=B2=E6=AD=A2=E6=B5=AE?= =?UTF-8?q?=E7=82=B9=E8=AF=AF=E5=B7=AE=E9=80=A0=E6=88=90=E7=9A=84=E5=A4=A7?= =?UTF-8?q?=E9=87=8F=E7=A2=8E=E7=89=87=E6=97=B6=E9=97=B4=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/OperatorBase.cs | 1 + InfrastSim/TimeDriven/Simulator.cs | 7 +++---- InfrastSimServer/SimulatorService.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/InfrastSim/TimeDriven/OperatorBase.cs b/InfrastSim/TimeDriven/OperatorBase.cs index 6455a5b..dde3045 100644 --- a/InfrastSim/TimeDriven/OperatorBase.cs +++ b/InfrastSim/TimeDriven/OperatorBase.cs @@ -90,6 +90,7 @@ public virtual void QueryInterest(Simulator simu) { foreach (var threshold in WorkingTimeThresholds) { if (threshold > WorkingTime) { ticks = Math.Min(ticks, TimeSpanToTicks(threshold - WorkingTime)); + break; } } } diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 57ccd59..29ab1ad 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -105,7 +105,7 @@ public Simulator(in JsonElement elem) { public XoshiroRandom Random { get; set; } ITimeDrivenObject? _interestSource; TimeSpan _nextInterest; - TimeSpan _minSpan = TimeSpan.FromSeconds(2); + static readonly TimeSpan MinSpan = TimeSpan.FromSeconds(2); internal void SetInterest(ITimeDrivenObject o, TimeSpan span) { if (span < _nextInterest) { _interestSource = o; @@ -148,14 +148,13 @@ public void SimulateUntil(DateTime dateTime) { QueryInterest(); var span = dateTime - Now; - if (span < _minSpan) { + if (span < MinSpan) { SimulateImpl(span); return; } if (_nextInterest < span) span = _nextInterest; - if (_minSpan > span) span = _minSpan; - SimulateImpl(span); + SimulateImpl(span + MinSpan); } } diff --git a/InfrastSimServer/SimulatorService.cs b/InfrastSimServer/SimulatorService.cs index fd4f7f4..583a3a3 100644 --- a/InfrastSimServer/SimulatorService.cs +++ b/InfrastSimServer/SimulatorService.cs @@ -40,8 +40,8 @@ public void Create(HttpContext httpContext) { writer.Flush(); } - public void CreateWithData(HttpContext httpContext, bool newRandom = true) { - var doc = JsonDocument.Parse(httpContext.Request.Body); + public async Task CreateWithData(HttpContext httpContext, bool newRandom = true) { + var doc = await JsonDocument.ParseAsync(httpContext.Request.Body); var id = Interlocked.Increment(ref _simuId); var simu = _simus[id] = new Simulator(doc.RootElement); if (newRandom) simu.Random = new(); From 44dfa9b569afcd21214e9563c75afe0c9dc427e3 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sat, 2 Dec 2023 19:18:40 +0800 Subject: [PATCH 05/39] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=9C=9C=E8=8E=93?= =?UTF-8?q?=E3=80=81=E5=87=AF=E5=B0=94=E5=B8=8C=E3=80=81=E5=B9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Honeyberry.cs | 14 ++++++++++++++ InfrastSim/TimeDriven/Operators/Kaltsit.cs | 14 ++++++++++++++ InfrastSim/TimeDriven/Operators/Nian.cs | 12 ++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 InfrastSim/TimeDriven/Operators/Honeyberry.cs create mode 100644 InfrastSim/TimeDriven/Operators/Kaltsit.cs create mode 100644 InfrastSim/TimeDriven/Operators/Nian.cs diff --git a/InfrastSim/TimeDriven/Operators/Honeyberry.cs b/InfrastSim/TimeDriven/Operators/Honeyberry.cs new file mode 100644 index 0000000..2a88a6a --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Honeyberry.cs @@ -0,0 +1,14 @@ +namespace InfrastSim.TimeDriven.Operators; +internal class Honeyberry : OperatorBase { + public override string Name => "蜜莓"; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + // TODO: missing skill 1 + + if (Facility is Dormitory dorm && Upgraded >= 2) { + dorm.SetVipMoodModifier(-0.7); + } + } +} diff --git a/InfrastSim/TimeDriven/Operators/Kaltsit.cs b/InfrastSim/TimeDriven/Operators/Kaltsit.cs new file mode 100644 index 0000000..7d66b3e --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Kaltsit.cs @@ -0,0 +1,14 @@ +namespace InfrastSim.TimeDriven.Operators; +internal class Kaltsit : OperatorBase { + public override string Name => "凯尔希"; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + // TODO: missing skill 1 + + if (Facility?.Type == FacilityType.ControlCenter && !IsTired && Upgraded >= 2) { + simu.GlobalManufacturingEfficiency.SetIfGreater(0.02); + } + } +} diff --git a/InfrastSim/TimeDriven/Operators/Nian.cs b/InfrastSim/TimeDriven/Operators/Nian.cs new file mode 100644 index 0000000..87586a2 --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Nian.cs @@ -0,0 +1,12 @@ +namespace InfrastSim.TimeDriven.Operators; +internal class Nian : OperatorBase { + public override string Name => "年"; + static string[] _groups = { "岁" }; + public override string[] Groups => _groups; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + // TODO: missing skill 1 & 2 + } +} \ No newline at end of file From 798ad76cab65c7a71a09621e98e76337ff5f87c8 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sun, 3 Dec 2023 11:10:00 +0800 Subject: [PATCH 06/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8DVip=E4=B8=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Dormitory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/Dormitory.cs b/InfrastSim/TimeDriven/Dormitory.cs index 46aaf6d..a61c82f 100644 --- a/InfrastSim/TimeDriven/Dormitory.cs +++ b/InfrastSim/TimeDriven/Dormitory.cs @@ -53,7 +53,7 @@ public int Compare(OperatorBase? x, OperatorBase? y) { public override void Resolve(Simulator simu) { base.Resolve(simu); - if (VipMoodModifier == 0 || Vip != null && Vip.Facility != this) { + if (VipMoodModifier == 0 || Vip != null && (Vip.Facility != this || Vip.IsFullOfEnergy)) { Vip = null; } if (VipMoodModifier > 0 && Vip == null) { From 14d031cd2579a372b51c9220d728f044a82ff8e4 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sun, 3 Dec 2023 11:39:11 +0800 Subject: [PATCH 07/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A1=91=E5=BF=83?= =?UTF-8?q?=E3=80=81=E8=8A=99=E8=93=89BUG=EF=BC=8C=E4=BF=AE=E5=A4=8DVIP?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Dormitory.cs | 4 ++-- InfrastSim/TimeDriven/Operators/Hibiscus.cs | 2 +- InfrastSim/TimeDriven/Operators/Virtuosa.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/InfrastSim/TimeDriven/Dormitory.cs b/InfrastSim/TimeDriven/Dormitory.cs index a61c82f..277965f 100644 --- a/InfrastSim/TimeDriven/Dormitory.cs +++ b/InfrastSim/TimeDriven/Dormitory.cs @@ -56,13 +56,13 @@ public override void Resolve(Simulator simu) { if (VipMoodModifier == 0 || Vip != null && (Vip.Facility != this || Vip.IsFullOfEnergy)) { Vip = null; } - if (VipMoodModifier > 0 && Vip == null) { + if (VipMoodModifier < 0 && Vip == null) { Vip = Operators .OrderBy(op => op, new VipPriorityComparer()) .Where(op => !op.IsFullOfEnergy) .FirstOrDefault(); - Vip?.MoodConsumeRate.SetValue("dorm-vip", VipMoodModifier); } + Vip?.MoodConsumeRate.SetValue("dorm-vip", VipMoodModifier); simu.Delay((simu) => { foreach (var op in Operators) { diff --git a/InfrastSim/TimeDriven/Operators/Hibiscus.cs b/InfrastSim/TimeDriven/Operators/Hibiscus.cs index e498f73..2e807b2 100644 --- a/InfrastSim/TimeDriven/Operators/Hibiscus.cs +++ b/InfrastSim/TimeDriven/Operators/Hibiscus.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(0.55); + dorm.SetVipMoodModifier(-0.55); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/Virtuosa.cs b/InfrastSim/TimeDriven/Operators/Virtuosa.cs index b9c83e4..6eeb8a1 100644 --- a/InfrastSim/TimeDriven/Operators/Virtuosa.cs +++ b/InfrastSim/TimeDriven/Operators/Virtuosa.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { if (Upgraded >= 2) { simu.Delay(simu => { - dorm.SetDormMoodModifier(0.2 + (int)simu.Wushenggongming / 5 * 0.01); + dorm.SetDormMoodModifier(-0.2 - (int)simu.Wushenggongming / 5 * 0.01); }); } } From 742bce03ab4f7f08790b133069f5f313f3d269aa Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sun, 3 Dec 2023 23:49:30 +0800 Subject: [PATCH 08/39] =?UTF-8?q?=E5=85=B1=E7=94=A8TestOp=E6=98=AF?= =?UTF-8?q?=E4=B8=8D=E5=8F=AF=E5=8F=96=E7=9A=84=EF=BC=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?;=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AAAPI=E5=8F=98=E5=8A=A8?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=E4=BB=A3=E7=A0=81=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs index 908565d..cdac3f8 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs @@ -3,11 +3,9 @@ namespace InfrastSim.TimeDriven.WebHelper; public static class EnumerateHelper { - static readonly OperatorBase TestOp; internal static readonly JsonSerializerOptions Options; static EnumerateHelper() { - TestOp = new TestOp(); Options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; @@ -61,7 +59,7 @@ internal static void ReplaceByTestOp(this OperatorBase op) { if (fac != null) { var index = fac.IndexOf(op); fac.RemoveAt(index); - fac.AssignAt(TestOp, index); + fac.AssignAt(new TestOp(), index); } } internal static void FillTestOp(this Simulator simu) { @@ -73,7 +71,7 @@ internal static void FillTestOp(this FacilityBase fac) { for (int i = 0; i < fac.AcceptOperatorNums; i++) { if (fac._operators[i]?.Name != "测试干员") { fac.RemoveAt(i); - fac.AssignAt(TestOp, i); + fac.AssignAt(new TestOp(), i); } } } @@ -98,7 +96,7 @@ internal static bool TestAssign(this FacilityBase fac, OperatorBase op) { } internal static OperatorBase Assign(this Simulator simu, OpEnumData data) { var op = simu.GetOperator(data.Name); - op.SetMood((data.MoodLow + data.MoodHigh) >> 1); + op.SetMood((double)((data.MoodLow + data.MoodHigh) >> 1)); op.WorkingTime = data.WarmUp ? TimeSpan.FromHours(10) : TimeSpan.Zero; var facName = data.Fac.ToLower(); From 72d6ce507fc4b4c3a06c46ce9666656c26980b0c Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Tue, 5 Dec 2023 11:29:30 +0800 Subject: [PATCH 09/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AD=91=E5=92=8C?= =?UTF-8?q?=E8=AF=97=E6=80=80=E9=9B=85=E7=9A=84=E6=95=88=E7=8E=87=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Jaye.cs | 2 +- InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs | 2 +- InfrastSim/TimeDriven/Priority.cs | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/InfrastSim/TimeDriven/Operators/Jaye.cs b/InfrastSim/TimeDriven/Operators/Jaye.cs index 2dff0fe..6cefbdc 100644 --- a/InfrastSim/TimeDriven/Operators/Jaye.cs +++ b/InfrastSim/TimeDriven/Operators/Jaye.cs @@ -18,7 +18,7 @@ public override void Resolve(Simulator simu) { var total = trading.Operators.Sum(op => op.EfficiencyModifier); trading.Capacity.SetValue(Name, -Math.Floor(total / 0.1)); EfficiencyModifier.SetValue(Name, trading.Capacity * 0.04); - }, 130); + }, Priority.Jaye); } } } diff --git a/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs b/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs index 761203e..3c1971e 100644 --- a/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs +++ b/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs @@ -15,7 +15,7 @@ public override void Resolve(Simulator simu) { simu.Delay(simu => { var diff = trading.Capacity - trading.BaseCapacity; EfficiencyModifier.AddValue(Name, diff * 0.04); - }); + }, Priority.Swire); } } } diff --git a/InfrastSim/TimeDriven/Priority.cs b/InfrastSim/TimeDriven/Priority.cs index 8bb7e1a..ed06d38 100644 --- a/InfrastSim/TimeDriven/Priority.cs +++ b/InfrastSim/TimeDriven/Priority.cs @@ -4,6 +4,8 @@ internal static class Priority { public const int Common = 100; public const int AccordingToFacilityAmount = 110; public const int WaaiFu = 120; + public const int Jaye = 130; + public const int Swire = 140; public const int Shamare = 150; public const int Facility = 200; } From 749b4261939996c88bab1e2ba3bd0de0c1769284 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Wed, 13 Dec 2023 15:03:50 +0800 Subject: [PATCH 10/39] =?UTF-8?q?=E6=96=B0=E5=A2=9E4=E4=BD=8D=E5=B9=B2?= =?UTF-8?q?=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Cliffheart.cs | 20 ++++++++++++++ .../TimeDriven/Operators/Degenbrecher.cs | 26 +++++++++++++++++++ InfrastSim/TimeDriven/Operators/Jieyun.cs | 18 +++++++++++++ .../\320\233\320\265\321\202\320\276.cs" | 19 ++++++++++++++ InfrastSim/TimeDriven/Priority.cs | 9 ++++--- InfrastSim/TimeDriven/Simulator.cs | 1 + 6 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 InfrastSim/TimeDriven/Operators/Cliffheart.cs create mode 100644 InfrastSim/TimeDriven/Operators/Degenbrecher.cs create mode 100644 InfrastSim/TimeDriven/Operators/Jieyun.cs create mode 100644 "InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" diff --git a/InfrastSim/TimeDriven/Operators/Cliffheart.cs b/InfrastSim/TimeDriven/Operators/Cliffheart.cs new file mode 100644 index 0000000..3124e11 --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Cliffheart.cs @@ -0,0 +1,20 @@ +namespace InfrastSim.TimeDriven.Operators; + +internal class Cliffheart : OperatorBase { + public override string Name => "崖心"; + static string[] _groups = { "喀兰贸易" }; + public override string[] Groups => _groups; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + if (Facility is Dormitory dorm) { + dorm.SetVipMoodModifier(-0.25); + MoodConsumeRate.SetValue(Name, -0.5); + } + if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { + EfficiencyModifier.SetValue(Name, 0.15); + trading.Capacity.SetValue(Name, Upgraded >= 2 ? 4 : 2); + } + } +} \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Degenbrecher.cs b/InfrastSim/TimeDriven/Operators/Degenbrecher.cs new file mode 100644 index 0000000..ac4883f --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Degenbrecher.cs @@ -0,0 +1,26 @@ +namespace InfrastSim.TimeDriven.Operators; + +internal class Degenbrecher : OperatorBase { + public override string Name => "锏"; + static string[] _groups = { "喀兰贸易" }; + public override string[] Groups => _groups; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + if (Facility is TradingStation trading && !IsTired) { + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.2); + trading.Capacity.SetValue(Name, Upgraded >= 2 ? -6 : -2); + + if (Upgraded >= 2) { + simu.Delay(simu => { + var cap = trading.Capacity + .EnumerateValues() + .Where(kvp => kvp.Key != "base") + .Sum(kvp => kvp.Value); + EfficiencyModifier.AddValue(Name, Math.Clamp((int)cap / 5 * 0.25, 0.0, 1.0)); + }); + } + } + } +} \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Jieyun.cs b/InfrastSim/TimeDriven/Operators/Jieyun.cs new file mode 100644 index 0000000..4732962 --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Jieyun.cs @@ -0,0 +1,18 @@ +namespace InfrastSim.TimeDriven.Operators; + +internal class Jieyun : OperatorBase { + public override string Name => "截云"; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + if (Facility is ManufacturingStation manufacturing && !IsTired) { + simu.Delay(simu => { + simu.Wushujiejing.SetValue(Name, (int)simu.Renjianyanhuo / 5); + }, Priority.PropConversion); + simu.Delay(simu => { + EfficiencyModifier.SetValue(Name, simu.Wushujiejing * (Upgraded >= 2 ? 0.02 : 0.01)); + }); + } + } +} \ No newline at end of file diff --git "a/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" "b/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" new file mode 100644 index 0000000..eb408df --- /dev/null +++ "b/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" @@ -0,0 +1,19 @@ +namespace InfrastSim.TimeDriven.Operators; +internal class Лето : OperatorBase { + public override string Name => "烈夏"; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + // TODO: missing skill 1 + + if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 2) { + if (manufacturing.IsProduceCombatRecord() + && simu.IsOpInFacility("古米", FacilityType.Trading)) { + + EfficiencyModifier.SetValue(Name, 0.3); + } + } + } +} + diff --git a/InfrastSim/TimeDriven/Priority.cs b/InfrastSim/TimeDriven/Priority.cs index ed06d38..6cbd010 100644 --- a/InfrastSim/TimeDriven/Priority.cs +++ b/InfrastSim/TimeDriven/Priority.cs @@ -4,8 +4,9 @@ internal static class Priority { public const int Common = 100; public const int AccordingToFacilityAmount = 110; public const int WaaiFu = 120; - public const int Jaye = 130; - public const int Swire = 140; - public const int Shamare = 150; - public const int Facility = 200; + public const int Degenbrecher = 160; + public const int Jaye = 170; + public const int Swire = 180; + public const int Shamare = 190; + public const int Facility = 1000; } diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 29ab1ad..b27ad91 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -262,6 +262,7 @@ public AggregateValue GetGlobalValue(string name) { #region 全局参数 public AggregateValue SilverVine => GetGlobalValue("木天蓼"); public AggregateValue Renjianyanhuo => GetGlobalValue("人间烟火"); + public AggregateValue Wushujiejing => GetGlobalValue("巫术结晶"); public AggregateValue Ganzhixinxi => GetGlobalValue("感知信息"); public AggregateValue Wushenggongming => GetGlobalValue("无声共鸣"); public AggregateValue Siweilianhuan => GetGlobalValue("思维链环"); From f28a2ca076f5ca375eff09e4e0c05ec4c0eba365 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 14 Dec 2023 09:57:04 +0800 Subject: [PATCH 11/39] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A7=92=E5=B3=B0=20cl?= =?UTF-8?q?oses=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Matterhorn.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 InfrastSim/TimeDriven/Operators/Matterhorn.cs diff --git a/InfrastSim/TimeDriven/Operators/Matterhorn.cs b/InfrastSim/TimeDriven/Operators/Matterhorn.cs new file mode 100644 index 0000000..4c76969 --- /dev/null +++ b/InfrastSim/TimeDriven/Operators/Matterhorn.cs @@ -0,0 +1,18 @@ +namespace InfrastSim.TimeDriven.Operators; + +internal class Matterhorn : OperatorBase { + public override string Name => "角峰"; + static string[] _groups = { "喀兰贸易" }; + public override string[] Groups => _groups; + + public override void Resolve(Simulator simu) { + base.Resolve(simu); + + if (Facility is TradingStation trading && !IsTired) { + EfficiencyModifier.SetValue(Name, 0.15); + trading.Capacity.SetValue(Name, 2); + } + + // TODO: missing skill 2 + } +} \ No newline at end of file From 21c845ab01f84721fa72095075014814ed894e2e Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Sun, 17 Dec 2023 19:50:13 +0800 Subject: [PATCH 12/39] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=B8=85=E6=B5=81=E6=A7=90=E7=90=A5=E9=97=AE=E9=A2=98=20#3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Priority.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InfrastSim/TimeDriven/Priority.cs b/InfrastSim/TimeDriven/Priority.cs index 6cbd010..71b9dbf 100644 --- a/InfrastSim/TimeDriven/Priority.cs +++ b/InfrastSim/TimeDriven/Priority.cs @@ -2,8 +2,8 @@ namespace InfrastSim.TimeDriven; internal static class Priority { public const int PropConversion = 20; public const int Common = 100; - public const int AccordingToFacilityAmount = 110; - public const int WaaiFu = 120; + public const int WaaiFu = 110; + public const int AccordingToFacilityAmount = 120; public const int Degenbrecher = 160; public const int Jaye = 170; public const int Swire = 180; From 0a9d7da8fab08f553be4a25661fbb31290016631 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Mon, 18 Dec 2023 11:12:52 +0800 Subject: [PATCH 13/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AD=91=E7=9A=84?= =?UTF-8?q?=E6=B5=AE=E7=82=B9=E8=88=8D=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Operators/Jaye.cs | 2 +- InfrastSim/Util.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/InfrastSim/TimeDriven/Operators/Jaye.cs b/InfrastSim/TimeDriven/Operators/Jaye.cs index 6cefbdc..dd769f5 100644 --- a/InfrastSim/TimeDriven/Operators/Jaye.cs +++ b/InfrastSim/TimeDriven/Operators/Jaye.cs @@ -16,7 +16,7 @@ public override void Resolve(Simulator simu) { // FIXME: 孑的技能和不同干员的交互仍然需要重点关注 simu.Delay(simu => { var total = trading.Operators.Sum(op => op.EfficiencyModifier); - trading.Capacity.SetValue(Name, -Math.Floor(total / 0.1)); + trading.Capacity.SetValue(Name, -Math.Floor((total + Util.Epsilon) / 0.1)); EfficiencyModifier.SetValue(Name, trading.Capacity * 0.04); }, Priority.Jaye); } diff --git a/InfrastSim/Util.cs b/InfrastSim/Util.cs index 45cb09f..2239371 100644 --- a/InfrastSim/Util.cs +++ b/InfrastSim/Util.cs @@ -9,7 +9,7 @@ public static bool Equals(double self, double other, double epsilon = Epsilon) { return Math.Abs(self - other) < epsilon; } public static double Align(double a, double b) { - return Math.Floor(a / b) * b; + return Math.Floor(a / b + Epsilon) * b; } From a98dacdfa4e2fe6b9c8f26606c0626ceca3a1a40 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Wed, 10 Jan 2024 16:00:27 +0800 Subject: [PATCH 14/39] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E3=80=81=E6=89=A7=E8=A1=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/Localization/AliasAttribute.cs | 6 + InfrastSim/Localization/Language.cs | 7 + InfrastSim/Product.cs | 24 ++- InfrastSim/Script/Parser.cs | 88 +++++++++ InfrastSim/Script/Scanner.cs | 99 ++++++++++ InfrastSim/Script/ScriptException.cs | 3 + InfrastSim/Script/Symbol.cs | 4 + InfrastSim/Script/SymbolType.cs | 8 + InfrastSim/Script/Token.cs | 6 + InfrastSim/Script/TokenSequence.cs | 25 +++ InfrastSim/Script/TokenType.cs | 13 ++ InfrastSim/TimeDriven/Helper.cs | 3 - InfrastSim/TimeDriven/ScriptHelper.cs | 173 ++++++++++++++++++ InfrastSim/TimeDriven/Simulator.cs | 48 ++++- InfrastSim/TimeDriven/TradingStation.cs | 1 - InfrastSim/TimeDriven/WebHelper/Helper.cs | 124 +++++++------ InfrastSimServer/Program.cs | 5 - InfrastSimServer/SimulatorService.cs | 5 - .../ScriptSourceGenerator.cs | 76 ++++++++ InfrastSimTest/ScriptTest.cs | 34 ++++ InfrastSimWasm/SimulatorService.cs | 6 + 21 files changed, 669 insertions(+), 89 deletions(-) create mode 100644 InfrastSim/Localization/AliasAttribute.cs create mode 100644 InfrastSim/Localization/Language.cs create mode 100644 InfrastSim/Script/Parser.cs create mode 100644 InfrastSim/Script/Scanner.cs create mode 100644 InfrastSim/Script/ScriptException.cs create mode 100644 InfrastSim/Script/Symbol.cs create mode 100644 InfrastSim/Script/SymbolType.cs create mode 100644 InfrastSim/Script/Token.cs create mode 100644 InfrastSim/Script/TokenSequence.cs create mode 100644 InfrastSim/Script/TokenType.cs create mode 100644 InfrastSim/TimeDriven/ScriptHelper.cs create mode 100644 InfrastSimSourceGenerator/ScriptSourceGenerator.cs create mode 100644 InfrastSimTest/ScriptTest.cs diff --git a/InfrastSim/Localization/AliasAttribute.cs b/InfrastSim/Localization/AliasAttribute.cs new file mode 100644 index 0000000..56a612c --- /dev/null +++ b/InfrastSim/Localization/AliasAttribute.cs @@ -0,0 +1,6 @@ +namespace InfrastSim.Localization; +[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] +public class AliasAttribute(Language language, string alias) : Attribute { + public Language Language { get; set; } = language; + public string Alias { get; set; } = alias ?? throw new ArgumentNullException(nameof(alias)); +} diff --git a/InfrastSim/Localization/Language.cs b/InfrastSim/Localization/Language.cs new file mode 100644 index 0000000..12cac72 --- /dev/null +++ b/InfrastSim/Localization/Language.cs @@ -0,0 +1,7 @@ +namespace InfrastSim.Localization; +public enum Language { + EN, + English = EN, + CN, + Chinese = CN, +} diff --git a/InfrastSim/Product.cs b/InfrastSim/Product.cs index 19069da..572102b 100644 --- a/InfrastSim/Product.cs +++ b/InfrastSim/Product.cs @@ -1,20 +1,18 @@ namespace InfrastSim; -public record Product(string Name, int Volume, int RequiredLevel, TimeSpan ProduceTime, Material[]? Consumes = null) { - public readonly static Product[] CombatRecords = { +public record Product( + string Name, int Volume, int RequiredLevel, TimeSpan ProduceTime, Material[]? Consumes = null) { + + public readonly static Product[] CombatRecords = [ new("基础作战记录", 2, 1, TimeSpan.FromMinutes(45)), new("初级作战记录", 3, 2, TimeSpan.FromMinutes(80)), new("中级作战记录", 5, 3, TimeSpan.FromMinutes(180)), - }; + ]; public readonly static Product Gold = new("赤金", 2, 1, TimeSpan.FromMinutes(72)); - public readonly static Product[] StoneFragment = { - new("源石碎片", 3, 3, TimeSpan.FromMinutes(60), - new[]{ new Material("龙门币", 1600), - new Material("固源岩", 2),}), - new("源石碎片", 3, 3, TimeSpan.FromMinutes(60), - new[]{ new Material("龙门币", 1000), - new Material("装置", 1),}), - }; + public readonly static Product[] StoneFragment = [ + new("源石碎片", 3, 3, TimeSpan.FromMinutes(60), [new("龙门币", 1600), new("固源岩", 2)]), + new("源石碎片", 3, 3, TimeSpan.FromMinutes(60), [new("龙门币", 1000), new("装置", 1)] + ), + ]; - public readonly static Product[] AllProducts = - CombatRecords.Append(Gold).Concat(StoneFragment).ToArray(); + public readonly static Product[] AllProducts = [..CombatRecords, Gold, ..StoneFragment]; } \ No newline at end of file diff --git a/InfrastSim/Script/Parser.cs b/InfrastSim/Script/Parser.cs new file mode 100644 index 0000000..4d03b8d --- /dev/null +++ b/InfrastSim/Script/Parser.cs @@ -0,0 +1,88 @@ +namespace InfrastSim.Script; +internal class Parser(TokenSequence tokens) { + private TokenSequence tokens = tokens; + + public static Script Parse(TokenSequence tokens) { + return new Parser(tokens).ParseScript(); + } + + private bool Match(TokenType type) { + if (tokens.Current.Type == type) { + tokens.MoveNext(); + return true; + } + return false; + } + + private Script ParseScript() { + tokens.Reset(); + + if (tokens.Current.Type == TokenType.Begin) { + tokens.MoveNext(); + } + + var statements = new List(); + while (tokens.Current.Type != TokenType.Final) { + statements.Add(ParseStatement()); + } + return new(statements); + } + + private Statement ParseStatement() { + while (tokens.Current.Type == TokenType.NewLine || tokens.Current.Type == TokenType.Comment) { + tokens.MoveNext(); + } + + var command = ParseCommand(); + var parameters = new List(); + while (tokens.Current.Type == TokenType.String) { + parameters.Add(ParseParameter()); + } + Match(TokenType.Semicolon); // Optional semicolon + return new Statement(command, parameters); + } + + private Command ParseCommand() { + if (tokens.Current.Type != TokenType.String) { + throw new ParseException("Expected a command.", tokens.Current.Line, tokens.Current.Column); + } + var command = new Command(tokens.Current.RawValue); + tokens.MoveNext(); + return command; + } + + private Parameter ParseParameter() { + if (tokens.Current.Type != TokenType.String) { + throw new ParseException("Expected a parameter.", tokens.Current.Line, tokens.Current.Column); + } + var parameter = new Parameter(tokens.Current.RawValue); + tokens.MoveNext(); + return parameter; + } +} + +internal class Script(List statements) { + public List Statements { get; } = statements; +} + +internal class Statement(Command command, List parameters) { + public Command Command { get; } = command; + public List Parameters { get; } = parameters; + + public override string ToString() { + return $"{Command.Value} [{string.Join(',', Parameters.Select(p => p.Value))}]"; + } +} + +internal class Command(string value) { + public string Value { get; } = value; +} + +internal class Parameter(string value) { + public string Value { get; } = value; +} + +internal class ParseException(string message, int line, int col) + : Exception($"Parse error at line {line + 1}, column {col + 1}: {message}") +{ +} diff --git a/InfrastSim/Script/Scanner.cs b/InfrastSim/Script/Scanner.cs new file mode 100644 index 0000000..3c5e29f --- /dev/null +++ b/InfrastSim/Script/Scanner.cs @@ -0,0 +1,99 @@ +namespace InfrastSim.Script; +internal class Scanner { + string inputs; + int index = 0; + int line = 0; + int col = 0; + int forwardSlashCount = 0; + List tokens = new(); + + private Scanner(string inputs) { + this.inputs = inputs; + } + private void ScanImpl() { + tokens.Add(new Token(TokenType.Begin, string.Empty, 0, 0)); + while (index < inputs.Length) { + ReadToken(); + } + tokens.Add(new Token(TokenType.Final, string.Empty, line + 1, 0)); + } + + private char CurrentChar => inputs[index]; + private bool ValidStringChar(char ch) + => !(char.IsWhiteSpace(ch) || @"/\#;,.()*|[]!?@$%&+=<>`~'""".Contains(ch)); + private void MoveNext(int n = 1) { index += n; col += n; } + private void NewLine() { index++; line++; col = 0; forwardSlashCount = 0; } + + private void ReadToken() { + int tokenIndex = index; + int tokenLength = 1; + TokenType tokenType = TokenType.None; + switch (CurrentChar) { + case '/': + tokenType = TokenType.ForwardSlash; + break; + case '#': + tokenType = TokenType.NumberSign; + break; + case ';': + tokenType = TokenType.Semicolon; + break; + case '\n': + tokenType = TokenType.NewLine; + break; + default: + if (ValidStringChar(CurrentChar)) { + tokenType = TokenType.String; + while (tokenIndex + tokenLength < inputs.Length + && ValidStringChar(inputs[tokenIndex + tokenLength])) { + tokenLength++; + } + } else if (!char.IsWhiteSpace(CurrentChar)) { + tokenType = TokenType.UnknownMark; + } else { + // whitespaces + } + break; + } + + if (tokenType == TokenType.ForwardSlash) { + forwardSlashCount++; + if (forwardSlashCount == 2) { + tokens.RemoveAt(tokens.Count - 1); + tokenIndex -= 1; + tokenLength = 2; + tokenType = TokenType.Comment; + while (tokenIndex + tokenLength < inputs.Length + && inputs[tokenIndex + tokenLength] != '\n') { + tokenLength++; + } + } + } else if (tokenType == TokenType.NumberSign) { + tokenType = TokenType.Comment; + while (tokenIndex + tokenLength < inputs.Length + && inputs[tokenIndex + tokenLength] != '\n') { + tokenLength++; + } + } else { + forwardSlashCount = 0; + } + + if (tokenType != TokenType.None) { + var token = new Token( + tokenType, inputs.Substring(tokenIndex, tokenLength), line, col); + tokens.Add(token); + } + + if (tokenType == TokenType.NewLine) { + NewLine(); + } else { + MoveNext(tokenLength); + } + } + + static public TokenSequence Scan(string inputs) { + var scanner = new Scanner(inputs); + scanner.ScanImpl(); + return new(scanner.tokens); + } +} diff --git a/InfrastSim/Script/ScriptException.cs b/InfrastSim/Script/ScriptException.cs new file mode 100644 index 0000000..f2dd95e --- /dev/null +++ b/InfrastSim/Script/ScriptException.cs @@ -0,0 +1,3 @@ +namespace InfrastSim.Script; +public class ScriptException(string message) : Exception(message) { +} diff --git a/InfrastSim/Script/Symbol.cs b/InfrastSim/Script/Symbol.cs new file mode 100644 index 0000000..df987fc --- /dev/null +++ b/InfrastSim/Script/Symbol.cs @@ -0,0 +1,4 @@ +namespace InfrastSim.Script; +internal class Symbol(SymbolType type) { + public SymbolType Type { get; } = type; +} diff --git a/InfrastSim/Script/SymbolType.cs b/InfrastSim/Script/SymbolType.cs new file mode 100644 index 0000000..6d03408 --- /dev/null +++ b/InfrastSim/Script/SymbolType.cs @@ -0,0 +1,8 @@ +namespace InfrastSim.Script; +internal enum SymbolType { + Script, + Statements, + Statement, + Parameters, + Parameter, +} diff --git a/InfrastSim/Script/Token.cs b/InfrastSim/Script/Token.cs new file mode 100644 index 0000000..1935730 --- /dev/null +++ b/InfrastSim/Script/Token.cs @@ -0,0 +1,6 @@ +namespace InfrastSim.Script; +internal record Token(TokenType Type, string RawValue, int Line, int Column) { + public override string ToString() { + return $"{RawValue}<{Type}>[ln {Line + 1}, col {Column + 1}]"; + } +} diff --git a/InfrastSim/Script/TokenSequence.cs b/InfrastSim/Script/TokenSequence.cs new file mode 100644 index 0000000..f58fc52 --- /dev/null +++ b/InfrastSim/Script/TokenSequence.cs @@ -0,0 +1,25 @@ +namespace InfrastSim.Script; +internal class TokenSequence(IList tokens) { + IList tokens = tokens; + int cur = 0; + + public Token MoveNext() { + if (cur + 1 == tokens.Count) { + return tokens[cur]; + } + return tokens[++cur]; + } + public Token Peek() { + if (cur + 1 < tokens.Count) { + return tokens[cur + 1]; + } else { + return tokens.Last(); + } + } + public void Reset() => cur = 0; + + public Token Current => tokens[cur]; + public IList GetTokens() => tokens; + public int Count => tokens.Count; + public Token At(int index) => tokens[index]; +} diff --git a/InfrastSim/Script/TokenType.cs b/InfrastSim/Script/TokenType.cs new file mode 100644 index 0000000..152cd93 --- /dev/null +++ b/InfrastSim/Script/TokenType.cs @@ -0,0 +1,13 @@ +namespace InfrastSim.Script; +internal enum TokenType { + None, + Semicolon, // ; + ForwardSlash, // / + NumberSign, // # + UnknownMark, + NewLine, + String, + Comment, + Begin, + Final, +} diff --git a/InfrastSim/TimeDriven/Helper.cs b/InfrastSim/TimeDriven/Helper.cs index 78a3667..8c1eaae 100644 --- a/InfrastSim/TimeDriven/Helper.cs +++ b/InfrastSim/TimeDriven/Helper.cs @@ -1,6 +1,3 @@ -using System.Text; -using System.Text.Json; - namespace InfrastSim.TimeDriven; internal static class Helper { public static bool VisibleToLookupSkill(this OperatorBase op) { diff --git a/InfrastSim/TimeDriven/ScriptHelper.cs b/InfrastSim/TimeDriven/ScriptHelper.cs new file mode 100644 index 0000000..0e878d6 --- /dev/null +++ b/InfrastSim/TimeDriven/ScriptHelper.cs @@ -0,0 +1,173 @@ +using InfrastSim.Localization; +using InfrastSim.Script; +using InfrastSim.TimeDriven.WebHelper; + +namespace InfrastSim.TimeDriven; +internal static partial class ScriptHelper { + [Alias(Language.CN, "切换设施")] + public static void With(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("切换设施需要一个参数 [设施名]"); + } + simu.SelectedFacilityString = args[0]; + simu.SelectedFacilityCache = simu.GetFacilityByName(args[0]); + } + + [Alias(Language.CN, "进驻干员")] + public static void SetOps(Simulator simu, string[] args) { + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + var ops = args.Select(simu.GetOperator); + fac.AssignMany(ops); + } + + [Alias(Language.CN, "配置干员")] + public static void SetOpState(Simulator simu, string[] args) { + if (args.Length != 3) { + throw new ScriptException("配置干员需要三个参数 [干员名,进阶,心情]"); + } + + var op = simu.GetOperatorNoThrow(args[0]) ?? + throw new ScriptException($"{args[0]} 干员不存在"); + if (!int.TryParse(args[1], out var upgraded)) { + throw new ScriptException($"{args[1]} 不是一个有效的整数"); + } + if (!double.TryParse(args[2], out var mood)) { + throw new ScriptException($"{args[2]} 不是一个有效的浮点数"); + } + op.Upgraded = upgraded; + op.SetMood(mood); + } + + [Alias(Language.CN, "设置等级")] + public static void SetLevel(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("设置等级需要一个参数 [等级]"); + } + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + if (!int.TryParse(args[0], out var level)) { + throw new ScriptException($"{args[0]} 不是一个有效的整数"); + } + fac.SetLevel(level); + } + [Alias(Language.CN, "设置类型")] + public static void SetFac(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("设置类型需要一个参数 [设施名]"); + } + if (!WebHelper.Helper.RoomLabelRegex.IsMatch(simu.SelectedFacilityString)) { + throw new ScriptException("当前设施不是可切换类型的设施"); + } + var index = WebHelper.Helper.LabelToIndex(simu.SelectedFacilityString); + + simu.Facilities[index]?.RemoveAll(); + simu.Facilities[index] = args[0].ToLower() switch { + "trading" => new TradingStation(), + "贸易站" => new TradingStation(), + "manufacturing" => new ManufacturingStation(), + "制造站" => new ManufacturingStation(), + "power" => new PowerStation(), + "发电站" => new PowerStation(), + "_" => null, + _ => throw new ScriptException("无效设施类型名") + }; + } + + [Alias(Language.CN, "设置产物")] + public static void SetProduct(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("设置产物需要一个参数 [产物名]"); + } + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + if (fac is not ManufacturingStation) { + throw new ScriptException($"{simu.SelectedFacilityString} 设施不是一个制造站"); + } + + try { + WebHelper.Helper.SetProduct(simu, fac, args[0]); + } catch (Exception e) { + throw new ScriptException(e.Message); + } + } + + [Alias(Language.CN, "设置策略")] + public static void SetStrategy(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("设置策略需要一个参数 [策略名]"); + } + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + if (fac is not TradingStation) { + throw new ScriptException($"{simu.SelectedFacilityString} 设施不是一个贸易站"); + } + + try { + WebHelper.Helper.SetStrategy(simu, fac, args[0]); + } catch (Exception e) { + throw new ScriptException(e.Message); + } + } + + [Alias(Language.CN, "收集产出")] + public static void Collect(Simulator simu, string[] args) { + if (args.Length > 1) { + throw new ScriptException("收集产出需要零个或一个参数 [(订单序号)]"); + } + + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + if (fac is not TradingStation && args.Length == 1) { + throw new ScriptException("输入了订单序号,但设施不是贸易站"); + } + var idx = 0; + if (args.Length == 1 && !int.TryParse(args[0], out idx)) { + throw new ScriptException($"{args[0]} 不是一个有效的整数"); + } + + try { + WebHelper.Helper.Collect(simu, fac, idx); + } catch (Exception e) { + throw new ScriptException(e.Message); + } + } + + [Alias(Language.CN, "收集全部产出")] + public static void CollectAll(Simulator simu, string[] args) { + if (args.Length > 0) { + throw new ScriptException("收集全部产出不需要参数"); + } + + simu.CollectAll(); + } + + [Alias(Language.CN, "使用无人机")] + public static void UseDrones(Simulator simu, string[] args) { + if (args.Length > 1) { + throw new ScriptException("收集产出需要一个参数 [无人机数量]"); + } + + var fac = (simu.SelectedFacilityCache ??= simu.GetFacilityByName(simu.SelectedFacilityString)) + ?? throw new ScriptException($"{simu.SelectedFacilityString} 设施不存在"); + if (fac is not IApplyDrones canApplyDrones) { + throw new ScriptException($"{simu.SelectedFacilityString} 设施不是一个制造站或贸易站"); + } + if (!int.TryParse(args[0], out var amount)) { + throw new ScriptException($"{args[0]} 不是一个有效的整数"); + } + canApplyDrones.ApplyDrones(simu, amount); + } + + [Alias(Language.CN, "模拟")] + public static void Simulate(Simulator simu, string[] args) { + if (args.Length != 1) { + throw new ScriptException("模拟需要一个参数 [时长]"); + } + + if (!TimeSpan.TryParse(args[0], out var span)) { + throw new ScriptException($"{args[0]} 不是一个有效的时长"); + } + simu.SimulateUntil(simu.Now + span); + } +} \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index b27ad91..521c0ab 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -39,6 +39,22 @@ public Simulator(in JsonElement elem) { _refresh = refreshElem.GetDouble(); } + if (elem.TryGetProperty("total-manu-product", out JsonElement totManuProdElem)) { + _totalManuProduct = totManuProdElem.GetDouble(); + } + + if (elem.TryGetProperty("total-trad-product", out JsonElement totTradProdElem)) { + _totalTradProduct = totTradProdElem.GetDouble(); + } + + if (elem.TryGetProperty("total-office-product", out JsonElement totOfficeProdElem)) { + _totalOfficeProduct = totOfficeProdElem.GetDouble(); + } + + if (elem.TryGetProperty("total-drones-product", out JsonElement totDronesProdElem)) { + _totalDronesProduct = totDronesProdElem.GetDouble(); + } + if (elem.TryGetProperty("materials", out JsonElement materialsElem)) { foreach (var prop in materialsElem.EnumerateObject()) { _materials.Add(prop.Name, prop.Value.GetInt32()); @@ -140,6 +156,7 @@ void SimulateImpl(TimeSpan span) { } AddDrones(DronesEfficiency * (info.TimeElapsed / TimeSpan.FromMinutes(6))); _refresh += OfficeEfficiency * (info.TimeElapsed / TimeSpan.FromHours(12)); + _totalOfficeProduct += OfficeEfficiency * (info.TimeElapsed.Ticks / 100000); Now += span; } public void SimulateUntil(DateTime dateTime) { @@ -219,8 +236,20 @@ public IEnumerable WorkingOperators public double NextDroneTimeInSeconds => (Math.Ceiling(_drones) - _drones) * 360 / DronesEfficiency; + + // 这两个参数本来应该由脚本执行器维护,为了方便直接实现到模拟器类 + // 更好的做法是模拟器实现一种扩展方法来管理这些额外的变量的生命周期 + public string SelectedFacilityString { get; set; } + public FacilityBase? SelectedFacilityCache { get; set; } + double _drones; double _refresh; + double _totalManuProduct; + double _totalTradProduct; + double _totalOfficeProduct; + double _totalDronesProduct; + + Dictionary _materials = new(); Dictionary _globalValues = new(); SortedDictionary> _delayActions = new(); @@ -233,8 +262,10 @@ public void Delay(Action action, int priority = 100) { } } public int Drones => (int)Math.Floor(_drones); - public void AddDrones(double amount) => _drones = Math.Min(200, _drones + amount); - + public void AddDrones(double amount) { + _drones = Math.Min(200, _drones + amount); + _totalDronesProduct += amount; + } internal void RemoveDrones(int amount) => _drones -= Math.Min(Drones, amount); internal void RemoveMaterial(Material mat) { _materials[mat.Name] = _materials.GetValueOrDefault(mat.Name) - mat.Count; @@ -248,6 +279,15 @@ internal void AddMaterial(Material mat) { internal void AddMaterial(string name, int amount) { _materials[name] = _materials.GetValueOrDefault(name) + amount; } + internal void AddManuProduct(double amount) { + _totalManuProduct += amount; + } + internal void AddTradProduct(double amount) { + _totalTradProduct += amount; + } + internal void AddOfficeProduct(double amount) { + _totalOfficeProduct += amount; + } public AggregateValue GetGlobalValue(string name) { if (!_globalValues.ContainsKey(name)) { @@ -312,6 +352,10 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { Random.ToJson(writer); writer.WriteNumber("drones", _drones); writer.WriteNumber("refresh", _refresh); + writer.WriteNumber("total-manu-product", _totalManuProduct); + writer.WriteNumber("total-trad-product", _totalTradProduct); + writer.WriteNumber("total-office-product", _totalOfficeProduct); + writer.WriteNumber("total-drones-product", _totalDronesProduct); if (detailed) { writer.WriteNumber("drones-efficiency", DronesEfficiency); writer.WriteNumber("office-efficiency", OfficeEfficiency); diff --git a/InfrastSim/TimeDriven/TradingStation.cs b/InfrastSim/TimeDriven/TradingStation.cs index 4d4cd09..b858499 100644 --- a/InfrastSim/TimeDriven/TradingStation.cs +++ b/InfrastSim/TimeDriven/TradingStation.cs @@ -1,6 +1,5 @@ using RandomEx; using System.Diagnostics; -using System.Net.Http; using System.Text.Json; namespace InfrastSim.TimeDriven; diff --git a/InfrastSim/TimeDriven/WebHelper/Helper.cs b/InfrastSim/TimeDriven/WebHelper/Helper.cs index 3bc4999..6251690 100644 --- a/InfrastSim/TimeDriven/WebHelper/Helper.cs +++ b/InfrastSim/TimeDriven/WebHelper/Helper.cs @@ -1,3 +1,4 @@ +using InfrastSim.Script; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; @@ -21,39 +22,37 @@ public static void SetUpgraded(this Simulator simu, string name, int upgraded) { /// /// 返回门牌号对应与simu.Facilities中的下标 /// - static int LabelToIndex(string label) => (label[1] - '0' - 1) * 3 + (label[3] - '0' - 1) + 9; - static Regex _roomLabelRegex = RoomLabelRegex(); - static Regex _roomNameRegex = RoomNameWithOptionalIndexRegex(); - static FacilityBase? GetFacilityByName(this Simulator simu, string fac) { + internal static int LabelToIndex(string label) => (label[1] - '0' - 1) * 3 + (label[3] - '0' - 1) + 9; + internal static Regex RoomLabelRegex = GenRoomLabelRegex(); + internal static Regex RoomNameRegex = GenRoomNameWithOptionalIndexRegex(); + public static FacilityBase? GetFacilityByName(this Simulator simu, string fac) { fac = fac.Replace('-', ' ').Replace('_', ' ').ToLower(); - if (_roomLabelRegex.IsMatch(fac)) { + if (RoomLabelRegex.IsMatch(fac)) { var index = LabelToIndex(fac); return simu.Facilities[index]; } - var match = _roomNameRegex.Match(fac); + var match = RoomNameRegex.Match(fac); var fac_name = match.Groups[1].Value; if (fac_name == "dormitory") { var index = int.Parse(match.Groups[2].Value.Trim()) - 1; return simu.Dormitories[index]; } else { return fac_name switch { + "控制中枢" => simu.ControlCenter, "controlcenter" => simu.ControlCenter, "control center" => simu.ControlCenter, + "会客室" => simu.Reception, "reception" => simu.Reception, + "制造站" => simu.Crafting, "crafting" => simu.Crafting, + "办公室" => simu.Office, "office" => simu.Office, + "训练站" => simu.Training, "training" => simu.Training, _ => throw new ArgumentException($"{fac} 名称不存在对应的设施") }; } } - public static void SelectOperators(this Simulator simu, string fac, string[] ops) { - var facility = GetFacilityByName(simu, fac) - ?? throw new ArgumentException($"{fac} 名称对应的设施未建造"); - foreach (var op in ops) { - facility.Assign(simu.GetOperator(op)); - } - } public static void RemoveOperator(this Simulator simu, string fac, int idx) { var facility = GetFacilityByName(simu, fac) ?? throw new ArgumentException($"{fac} 名称对应的设施未建造"); @@ -71,7 +70,35 @@ public static int UseDrones(this Simulator simu, string fac, int amount) { throw new ArgumentException($"{fac} 未建造或不是可以使用无人机的设施"); } } - static void Collect(Simulator simu, FacilityBase? fac, int idx = 0) { + internal static void SetProduct(Simulator simu, FacilityBase? fac, string productName) { + if (fac is not ManufacturingStation manu) { + throw new ArgumentException($"设施不是一个制造站"); + } + Product product; + if (productName.StartsWith("源石碎片")) { + var splits = productName.Split('_', StringSplitOptions.RemoveEmptyEntries); + if (splits.Length != 2) { + throw new ArgumentException("无效的源石碎片材料"); + } + var consumes = splits[1]; + product = Product.AllProducts + .Where(p => p.Name == "源石碎片" && p.Consumes![1].Name == consumes) + .FirstOrDefault() ?? throw new ArgumentException($"无效源石碎片材料 {consumes}"); + } else { + product = Product.AllProducts + .Where(p => p.Name == productName) + .FirstOrDefault() ?? throw new ArgumentException($"未知的产品名称 {productName}"); + } + Collect(simu, fac); + manu.ChangeProduct(product); + } + internal static void SetStrategy(Simulator simu, FacilityBase? fac, string strategyName) { + if (fac is not TradingStation trading) { + throw new ArgumentException($"设施不是一个贸易站"); + } + trading.Strategy = ToStrategy(strategyName); + } + internal static void Collect(Simulator simu, FacilityBase? fac, int idx = 0) { if (fac is ManufacturingStation manufacturing) { if (manufacturing.Product == null) return; @@ -114,7 +141,7 @@ public static void CollectAll(this Simulator simu) { } public static TradingStation.OrderStrategy ToStrategy(string text) { - return text switch { + return text.ToLower() switch { "龙门商法" => TradingStation.OrderStrategy.Gold, "赤金" => TradingStation.OrderStrategy.Gold, "龙门币" => TradingStation.OrderStrategy.Gold, @@ -133,7 +160,7 @@ public static void SetFacilityState(this Simulator simu, string fac, JsonElement var facility = simu.GetFacilityByName(fac); if (facility != null) { if (elem.TryGetProperty("destroy", out _)) { - if (_roomLabelRegex.IsMatch(fac)) { + if (RoomLabelRegex.IsMatch(fac)) { var index = LabelToIndex(fac); facility.RemoveAll(); simu.Facilities[index] = null; @@ -141,7 +168,7 @@ public static void SetFacilityState(this Simulator simu, string fac, JsonElement } } if (elem.TryGetProperty("refactor", out var refactor)) { - if (_roomLabelRegex.IsMatch(fac)) { + if (RoomLabelRegex.IsMatch(fac)) { var index = LabelToIndex(fac); FacilityBase new_fac = refactor.GetString() switch { "Trading" => new TradingStation(), @@ -157,30 +184,10 @@ public static void SetFacilityState(this Simulator simu, string fac, JsonElement facility.SetLevel(level.GetInt32()); } if (elem.TryGetProperty("strategy", out var strategy)) { - if (facility is TradingStation trading) { - var strategyText = strategy.GetString().ToLower(); - trading.Strategy = ToStrategy(strategyText); - } + SetStrategy(simu, facility, strategy.GetString()); } if (elem.TryGetProperty("product", out var prod)) { - if (facility is ManufacturingStation manufacturing) { - var product = prod.GetString(); - Product newProduct; - if (product.StartsWith("源石碎片")) { - var splits = product.Split('_', StringSplitOptions.RemoveEmptyEntries); - var consumes = splits[1]; - newProduct = Product.AllProducts - .Where(p => p.Name == "源石碎片" && p.Consumes[1].Name == consumes) - .FirstOrDefault() ?? throw new ApplicationException($"未知的源石碎片材料 {consumes}"); - } - else { - newProduct = Product.AllProducts - .Where(p => p.Name == product) - .FirstOrDefault() ?? throw new ApplicationException($"未知的产品名称 {product}"); - } - Collect(simu, manufacturing); - manufacturing.ChangeProduct(newProduct); - } + SetProduct(simu, facility, prod.GetString()); } if (elem.TryGetProperty("operators", out var ops)) { var operators = ops.EnumerateArray().Select(e => simu.GetOperator(e.GetString())); @@ -194,38 +201,24 @@ public static void SetFacilityState(this Simulator simu, string fac, JsonElement Collect(simu, facility, collect_idx.GetInt32()); } } else { - if (_roomLabelRegex.IsMatch(fac)) { + if (RoomLabelRegex.IsMatch(fac)) { var index = LabelToIndex(fac); facility = FacilityBase.FromJson(elem, simu); simu.Facilities[index] = facility; } else { fac = fac.Replace('-', ' ').Replace('_', ' ').ToLower(); - var match = _roomNameRegex.Match(fac); + var match = RoomNameRegex.Match(fac); var fac_name = match.Groups[1].Value; if (fac_name == "dormitory") { var index = int.Parse(match.Groups[2].Value.Trim()) - 1; simu.Facilities[index + 5] = FacilityBase.FromJson(elem, simu); } } - if (elem.TryGetProperty("strategy", out var strategy)) { - if (facility is TradingStation trading) { - var strategyText = strategy.GetString().ToLower(); - trading.Strategy = strategyText switch { - "gold" => TradingStation.OrderStrategy.Gold, - "originium" => TradingStation.OrderStrategy.OriginStone, - _ => throw new ApplicationException($"未知的订单类型 {strategyText}") - }; - } + SetStrategy(simu, facility, strategy.GetString()); } if (elem.TryGetProperty("product", out var prod)) { - if (facility is ManufacturingStation manufacturing) { - var product = prod.GetString(); - var newProduct = Product.AllProducts.Where(p => p.Name == product).FirstOrDefault() - ?? throw new ApplicationException($"未知的产品名称 {product}"); - Collect(simu, manufacturing); - manufacturing.ChangeProduct(newProduct); - } + SetProduct(simu, facility, prod.GetString()); } } } @@ -238,9 +231,20 @@ public static void WriteOperators(this Utf8JsonWriter writer, Simulator simu) { writer.WriteEndArray(); } + public static void ExecuteScript(this Simulator simu, string script) { + var tokens = Scanner.Scan(script); + var res = Parser.Parse(tokens); + foreach (var statement in res.Statements) { + if (!ScriptHelper.MethodMappings.TryGetValue(statement.Command.Value.ToLower(), out var method)) { + throw new ScriptException($"没有找到命令 {statement.Command.Value}"); + } + method(simu, statement.Parameters.Select(p => p.Value).ToArray()); + } + } + [GeneratedRegex(@"^[bB][1-3]0[1-3]$")] - private static partial Regex RoomLabelRegex(); + private static partial Regex GenRoomLabelRegex(); - [GeneratedRegex(@"^([a-zA-Z ]+)( [1-4])?$")] - private static partial Regex RoomNameWithOptionalIndexRegex(); + [GeneratedRegex(@"^([a-zA-Z \u4e00-\u9fff]+)( [1-4])?$")] + private static partial Regex GenRoomNameWithOptionalIndexRegex(); } \ No newline at end of file diff --git a/InfrastSimServer/Program.cs b/InfrastSimServer/Program.cs index 7bb6850..cc8957b 100644 --- a/InfrastSimServer/Program.cs +++ b/InfrastSimServer/Program.cs @@ -110,11 +110,6 @@ public static void Main(string[] args) { .WithDescription("接受JSON数据并快速设置设施状态(含降级、升级、创建设施、快速调整干员位置等) strategy表示切贸易站策略;product表示改变制造站产品;level代表升降级设施,但不会计算无人机消耗") .WithOpenApi(); - app.MapPost("/simulator/{id}/{facility}/operators", simulatorService.SelectOperators) - .WithName("SelectOperators") - .WithDescription("设定某设施的干员列表") - .WithOpenApi(); - app.MapDelete("/simulator/{id}/{facility}/operators/{idx}", simulatorService.RemoveOperator) .WithName("RemoveOperator") .WithDescription("撤出某设施的第idx个干员(从1开始计数)") diff --git a/InfrastSimServer/SimulatorService.cs b/InfrastSimServer/SimulatorService.cs index 583a3a3..92d7e32 100644 --- a/InfrastSimServer/SimulatorService.cs +++ b/InfrastSimServer/SimulatorService.cs @@ -100,11 +100,6 @@ public void SetUpgraded(HttpContext httpContext, int id, Dictionary } } - public void SelectOperators(HttpContext httpContext, int id, SelectOperatorsData data) { - var simu = GetSimulator(id); - simu.SelectOperators(data.Facility, data.Operators); - } - public void RemoveOperator(HttpContext httpContext, int id, string facility, int idx) { var simu = GetSimulator(id); simu.RemoveOperator(facility, idx); diff --git a/InfrastSimSourceGenerator/ScriptSourceGenerator.cs b/InfrastSimSourceGenerator/ScriptSourceGenerator.cs new file mode 100644 index 0000000..927f9f6 --- /dev/null +++ b/InfrastSimSourceGenerator/ScriptSourceGenerator.cs @@ -0,0 +1,76 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis; +using System.Text; +using System.Linq; +using System.Collections.Generic; + +namespace InfrastSimSourceGenerator; + +[Generator] +public class ScriptSourceGenerator : ISourceGenerator { + public void Initialize(GeneratorInitializationContext context) { + //System.Diagnostics.Debugger.Launch(); + } + + public void Execute(GeneratorExecutionContext context) { + var targetClassName = "ScriptHelper"; // 指定目标类名 + var targetNamespace = "InfrastSim.TimeDriven"; // 指定目标命名空间 + var semanticModels = context.Compilation.SyntaxTrees + .Select(tree => context.Compilation.GetSemanticModel(tree)); + + var source = new StringBuilder($@" +// +using System; +using System.Linq; +using System.Collections.Generic; +using InfrastSim.Localization; + +namespace InfrastSim.TimeDriven; + +internal static partial class ScriptHelper +{{ + public static readonly Dictionary> MethodMappings = new(); + public static readonly List MethodNames = new(); + public static readonly Dictionary> AliasMappings = new(); + static ScriptHelper() {{ +"); + + var languages = new HashSet(); + foreach (var model in semanticModels) { + foreach (var classDeclaration in model.SyntaxTree.GetRoot().DescendantNodes().OfType()) { + var classSymbol = model.GetDeclaredSymbol(classDeclaration); + if (classSymbol != null && classSymbol.Name == targetClassName && classSymbol.ContainingNamespace.ToDisplayString() == targetNamespace) { + foreach (var method in classDeclaration.Members.OfType()) { + var methodName = method.Identifier.Text; + var methodNameLowerCase = methodName.ToLowerInvariant(); + source.AppendLine($" MethodMappings.Add(\"{methodNameLowerCase}\", {methodName});"); + source.AppendLine($" MethodNames.Add(\"{methodNameLowerCase}\");"); + + var aliasAttrs = method.AttributeLists + .SelectMany(attrList => attrList.Attributes) + .Where(attr => attr.Name.ToString() == "Alias"); + foreach (var aliasAttr in aliasAttrs) { + var aliasArgs = aliasAttr.ArgumentList.Arguments; + if (aliasArgs.Count == 2) { + var language = aliasArgs[0].ToString(); + var aliasName = aliasArgs[1].ToString(); + if (!languages.Contains(language)) { + languages.Add(language); + source.AppendLine($" AliasMappings[{language}] = new Dictionary();"); + } + source.AppendLine($" MethodMappings.Add({aliasName}, {methodName});"); + source.AppendLine($" AliasMappings[{language}].Add({aliasName}, \"{methodNameLowerCase}\");"); + } + } + } + } + } + } + + source.AppendLine(" }"); + source.AppendLine("}"); + + context.AddSource("ScriptHelper.g.cs", SourceText.From(source.ToString(), Encoding.UTF8)); + } +} \ No newline at end of file diff --git a/InfrastSimTest/ScriptTest.cs b/InfrastSimTest/ScriptTest.cs new file mode 100644 index 0000000..0805032 --- /dev/null +++ b/InfrastSimTest/ScriptTest.cs @@ -0,0 +1,34 @@ +using InfrastSim.Script; +using InfrastSim.TimeDriven.WebHelper; + +namespace InfrastSimTest; +[TestClass] +public class ScriptTest { + [TestMethod] + public void TestScript() { + var script = """ + //setStartTime 20240104 12:00:00 ; 设置启动时间 20240104 12:00:00 + //setCurrentTime 20240104 16:00:00 ; 设置当前时间 20240104 16:00:00 + //setRelevantTime 1:4:0:0 ; 设置相对时间 1:4:0:0 + + // 注释可以使用 # 和 // + // 语句默认独占一行, ';' 表示换行 + // 命令同时支持中英版本, 不考虑大小写 + + with B101 ; 切换设施 B101 + with Office ; 切换设施 办公室 // 切换命令持续到下个切换命令为止, 此前所有命令针对于该设施 + + setOps 芬 克洛丝 ; 进驻干员 芬 克洛丝 + useDrones 50 ; 使用无人机 50 + setProduct 源石碎片_固源岩 ; 设置产物 源石碎片_固源岩 + setStrategy 龙门商法 ; 设置策略 龙门商法 + collect ; 收集产出 + collect 3 ; 收集3号订单 + + collectAll ; 收集全部产出 + simulate 1:30:00 ; 模拟 1:30:00 + """; + var simu = new InfrastSim.TimeDriven.Simulator(); + Assert.ThrowsException(() => Helper.ExecuteScript(simu, script)); + } +} diff --git a/InfrastSimWasm/SimulatorService.cs b/InfrastSimWasm/SimulatorService.cs index 6be906a..c768990 100644 --- a/InfrastSimWasm/SimulatorService.cs +++ b/InfrastSimWasm/SimulatorService.cs @@ -181,4 +181,10 @@ public static string EnumerateGroup(string json) { EnumerateHelper.Enumerate(doc, writer); return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length); } + + [JSExport] + public static void ExecuteScript(int id, string script) { + var simu = GetSimulator(id); + Helper.ExecuteScript(simu, script); + } } From eff6bb7f71bb8917912546e2f145ec4af72508cb Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Tue, 23 Jan 2024 13:48:43 +0800 Subject: [PATCH 15/39] =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=97=B6=E9=97=B4=E5=80=BC=E6=88=96=E7=A7=92?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/ScriptHelper.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/ScriptHelper.cs b/InfrastSim/TimeDriven/ScriptHelper.cs index 0e878d6..8b03c1a 100644 --- a/InfrastSim/TimeDriven/ScriptHelper.cs +++ b/InfrastSim/TimeDriven/ScriptHelper.cs @@ -165,9 +165,13 @@ public static void Simulate(Simulator simu, string[] args) { throw new ScriptException("模拟需要一个参数 [时长]"); } - if (!TimeSpan.TryParse(args[0], out var span)) { + var seconds = -1; + if (!TimeSpan.TryParse(args[0], out var span) && !int.TryParse(args[0], out seconds)) { throw new ScriptException($"{args[0]} 不是一个有效的时长"); } + if (seconds > 0) { + span = TimeSpan.FromSeconds(seconds); + } simu.SimulateUntil(simu.Now + span); } } \ No newline at end of file From 04a0cdb7e87637e1351c843ac35dec54986b8c63 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Tue, 23 Jan 2024 15:24:03 +0800 Subject: [PATCH 16/39] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B9=B2=E5=91=98?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E6=B7=BB=E5=8A=A0=E7=A9=BA=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/ScriptHelper.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/InfrastSim/TimeDriven/ScriptHelper.cs b/InfrastSim/TimeDriven/ScriptHelper.cs index 8b03c1a..1fff46b 100644 --- a/InfrastSim/TimeDriven/ScriptHelper.cs +++ b/InfrastSim/TimeDriven/ScriptHelper.cs @@ -29,14 +29,17 @@ public static void SetOpState(Simulator simu, string[] args) { var op = simu.GetOperatorNoThrow(args[0]) ?? throw new ScriptException($"{args[0]} 干员不存在"); - if (!int.TryParse(args[1], out var upgraded)) { + int upgraded = -1; + double mood = double.NaN; + + if (args[1] != "_" && !int.TryParse(args[1], out upgraded)) { throw new ScriptException($"{args[1]} 不是一个有效的整数"); } - if (!double.TryParse(args[2], out var mood)) { + if (args[2] != "_" && !double.TryParse(args[2], out mood)) { throw new ScriptException($"{args[2]} 不是一个有效的浮点数"); } - op.Upgraded = upgraded; - op.SetMood(mood); + if (upgraded != -1) op.Upgraded = upgraded; + if (mood != double.NaN) op.SetMood(mood); } [Alias(Language.CN, "设置等级")] From 4df5839cacc22144c48a971109fb1ffbd83920a3 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Tue, 23 Jan 2024 17:21:44 +0800 Subject: [PATCH 17/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/ScriptHelper.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/InfrastSim/TimeDriven/ScriptHelper.cs b/InfrastSim/TimeDriven/ScriptHelper.cs index 1fff46b..233d65f 100644 --- a/InfrastSim/TimeDriven/ScriptHelper.cs +++ b/InfrastSim/TimeDriven/ScriptHelper.cs @@ -168,13 +168,16 @@ public static void Simulate(Simulator simu, string[] args) { throw new ScriptException("模拟需要一个参数 [时长]"); } - var seconds = -1; - if (!TimeSpan.TryParse(args[0], out var span) && !int.TryParse(args[0], out seconds)) { + TimeSpan span = default; + if (!int.TryParse(args[0], out var seconds) && !TimeSpan.TryParse(args[0], out span)) { throw new ScriptException($"{args[0]} 不是一个有效的时长"); } if (seconds > 0) { span = TimeSpan.FromSeconds(seconds); } + if (span <= default(TimeSpan)) { + throw new ScriptException($"{args[0]} 不是一个有效的时长"); + } simu.SimulateUntil(simu.Now + span); } } \ No newline at end of file From 146a6871cf5b3dab1d28d3ef2056e4eac6081d69 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 25 Jan 2024 19:00:19 +0800 Subject: [PATCH 18/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AANaN?= =?UTF-8?q?=E4=B8=8D=E7=9B=B8=E7=AD=89=E9=80=A0=E6=88=90=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/ScriptHelper.cs | 2 +- InfrastSim/TimeDriven/WebHelper/Helper.cs | 12 +++++++++++ InfrastSimServer/Program.cs | 25 ++++++++++++++--------- InfrastSimServer/SimulatorService.cs | 14 ++++++++++++- InfrastSimWasm/SimulatorService.cs | 17 ++++++++++++++- 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/InfrastSim/TimeDriven/ScriptHelper.cs b/InfrastSim/TimeDriven/ScriptHelper.cs index 233d65f..8ec3ccb 100644 --- a/InfrastSim/TimeDriven/ScriptHelper.cs +++ b/InfrastSim/TimeDriven/ScriptHelper.cs @@ -39,7 +39,7 @@ public static void SetOpState(Simulator simu, string[] args) { throw new ScriptException($"{args[2]} 不是一个有效的浮点数"); } if (upgraded != -1) op.Upgraded = upgraded; - if (mood != double.NaN) op.SetMood(mood); + if (!double.IsNaN(mood)) op.SetMood(mood); } [Alias(Language.CN, "设置等级")] diff --git a/InfrastSim/TimeDriven/WebHelper/Helper.cs b/InfrastSim/TimeDriven/WebHelper/Helper.cs index 6251690..47e6323 100644 --- a/InfrastSim/TimeDriven/WebHelper/Helper.cs +++ b/InfrastSim/TimeDriven/WebHelper/Helper.cs @@ -1,4 +1,6 @@ using InfrastSim.Script; +using InfrastSim.Localization; +using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; @@ -242,6 +244,16 @@ public static void ExecuteScript(this Simulator simu, string script) { } } + public static string[] GetCommands() { + return [.. ScriptHelper.MethodNames]; + } + public static string?[] GetLanguages() { + return Enum.GetValuesAsUnderlyingType(typeof(Language)).Cast().Distinct().Select(Enum.GetName).ToArray(); + } + public static Dictionary GetCommandMappings(Language language) { + return ScriptHelper.AliasMappings.GetValueOrDefault(language) ?? []; + } + [GeneratedRegex(@"^[bB][1-3]0[1-3]$")] private static partial Regex GenRoomLabelRegex(); diff --git a/InfrastSimServer/Program.cs b/InfrastSimServer/Program.cs index cc8957b..544372d 100644 --- a/InfrastSimServer/Program.cs +++ b/InfrastSimServer/Program.cs @@ -105,6 +105,21 @@ public static void Main(string[] args) { .WithDescription("设定给出列表干员的精英化程度") .WithOpenApi(); + app.MapPost("/simulator/{id}/script", simulatorService.ExecuteScript) + .WithName("ExecuteScript") + .WithDescription("执行脚本") + .WithOpenApi(); + + app.MapGet("/simulator/{id}/collectAll", simulatorService.CollectAll) + .WithName("CollectAll") + .WithDescription("收获全部产物并交付所有订单") + .WithOpenApi(); + + app.MapGet("/simulator/{id}/sanity", simulatorService.Sanity) + .WithName("Sanity") + .WithDescription("源石冲无人机 必填查询参数: amount") + .WithOpenApi(); + app.MapPost("/simulator/{id}/{facility}", simulatorService.SetFacilityState) .WithName("SetFacilityState") .WithDescription("接受JSON数据并快速设置设施状态(含降级、升级、创建设施、快速调整干员位置等) strategy表示切贸易站策略;product表示改变制造站产品;level代表升降级设施,但不会计算无人机消耗") @@ -125,16 +140,6 @@ public static void Main(string[] args) { .WithDescription("收获贸易站的全部产物;交付贸易站全部订单或交付贸易站第idx个订单(从1开始计数) 可选查询参数: idx") .WithOpenApi(); - app.MapGet("/simulator/{id}/collectAll", simulatorService.CollectAll) - .WithName("CollectAll") - .WithDescription("收获全部产物并交付所有订单") - .WithOpenApi(); - - app.MapGet("/simulator/{id}/sanity", simulatorService.Sanity) - .WithName("Sanity") - .WithDescription("源石冲无人机 必填查询参数: amount") - .WithOpenApi(); - app.MapGet("/simulator/{id}/{facility}/use_drones", simulatorService.UseDrones) .WithName("UseDrones") .WithDescription("使用无人机 必填查询参数: amount") diff --git a/InfrastSimServer/SimulatorService.cs b/InfrastSimServer/SimulatorService.cs index 92d7e32..59e283f 100644 --- a/InfrastSimServer/SimulatorService.cs +++ b/InfrastSimServer/SimulatorService.cs @@ -1,4 +1,5 @@ using InfrastSim; +using InfrastSim.Script; using InfrastSim.TimeDriven; using InfrastSim.TimeDriven.WebHelper; using System.Collections.Concurrent; @@ -6,7 +7,7 @@ using System.Text.Json.Nodes; namespace InfrastSimServer; -public class SimulatorService : IDisposable { +public sealed class SimulatorService : IDisposable { //public static readonly SimulatorService Instance = new(); private Timer? _timer; @@ -154,6 +155,17 @@ public async Task GetDataForMower(HttpContext httpContext, int id) { writer.Flush(); } + public async Task ExecuteScript(HttpContext httpContext, int id) { + var simu = GetSimulator(id); + try { + using var reader = new StreamReader(httpContext.Request.Body); + + simu.ExecuteScript(await reader.ReadToEndAsync() ?? ""); + } catch (ScriptException ex) { + await httpContext.Response.WriteAsync(ex.ToString()); + } + } + void Cleanup(object? state) { var simToCleanup = _lastAccess .Where(kvp => DateTime.Now - kvp.Value > TimeSpan.FromDays(1)) diff --git a/InfrastSimWasm/SimulatorService.cs b/InfrastSimWasm/SimulatorService.cs index c768990..6586cb0 100644 --- a/InfrastSimWasm/SimulatorService.cs +++ b/InfrastSimWasm/SimulatorService.cs @@ -1,12 +1,13 @@ +using InfrastSim.Localization; using InfrastSim.TimeDriven; using InfrastSim.TimeDriven.WebHelper; using System.Collections.Concurrent; -using System.Runtime.InteropServices; using System.Runtime.InteropServices.JavaScript; using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; +using System.Text.Json.Serialization; namespace InfrastSim.Wasm; @@ -187,4 +188,18 @@ public static void ExecuteScript(int id, string script) { var simu = GetSimulator(id); Helper.ExecuteScript(simu, script); } + + [JsonSerializable(typeof(Dictionary))] + [JsonSerializable(typeof(string))] + public partial class SerializeContext : JsonSerializerContext { } + + //[JSExport] + //public static string GetScriptInfo() { + // var commands = Helper.GetCommands(); + // var languages = Helper.GetLanguages(); + // var mappings = new Dictionary>(); + // foreach (var language in languages) { + // mappings[language] = Helper.GetCommandMappings(Enum.Parse(language)); + // } + //} } From 5722230f28df54208d307873ca7ac9e8e24f0c4c Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 26 Jan 2024 00:54:07 +0800 Subject: [PATCH 19/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/Script/Parser.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/InfrastSim/Script/Parser.cs b/InfrastSim/Script/Parser.cs index 4d03b8d..e74bd08 100644 --- a/InfrastSim/Script/Parser.cs +++ b/InfrastSim/Script/Parser.cs @@ -14,6 +14,13 @@ private bool Match(TokenType type) { return false; } + private bool ConsumeNonContentLines() { + while (tokens.Current.Type == TokenType.NewLine || tokens.Current.Type == TokenType.Comment) { + tokens.MoveNext(); + } + return tokens.Current.Type != TokenType.Final; + } + private Script ParseScript() { tokens.Reset(); @@ -23,16 +30,14 @@ private Script ParseScript() { var statements = new List(); while (tokens.Current.Type != TokenType.Final) { - statements.Add(ParseStatement()); + if (ConsumeNonContentLines()) { + statements.Add(ParseStatement()); + } } return new(statements); } private Statement ParseStatement() { - while (tokens.Current.Type == TokenType.NewLine || tokens.Current.Type == TokenType.Comment) { - tokens.MoveNext(); - } - var command = ParseCommand(); var parameters = new List(); while (tokens.Current.Type == TokenType.String) { From 940f74f276d185bd6a28fc3bda7c3c07cafd640d Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 21 Mar 2024 17:10:25 +0800 Subject: [PATCH 20/39] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebHelper/Enumerate/EnumerateContext.cs | 161 +++++++++++------- .../WebHelper/Enumerate/EnumerateHelper.cs | 2 +- 2 files changed, 101 insertions(+), 62 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index 0afda30..e912043 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -2,8 +2,8 @@ using InfrastSim.TimeDriven.WebHelper.Enumerate; using System.Collections; using System.Collections.Concurrent; -using System.Linq; using System.Text.Json; +using System.Threading.Tasks.Dataflow; namespace InfrastSim.TimeDriven.WebHelper; internal class EnumerateContext { @@ -13,25 +13,25 @@ internal class EnumerateContext { int max_size; int ucnt = 0; OpEnumData[] ops = null!; - Simulator simu1 = null!; + ThreadLocal simu = null!; Efficiency baseline; ConcurrentDictionary results = new(); - Efficiency TestSingle(Simulator simu, OpEnumData data) { - var op = simu.Assign(data); - var diff = simu.GetEfficiency() - baseline; + Efficiency TestSingle(OpEnumData data) { + var op = simu.Value.Assign(data); + var diff = simu.Value.GetEfficiency() - baseline; op.ReplaceByTestOp(); return diff; } - Efficiency TestMany(Simulator simu, IEnumerable datas) { + Efficiency TestMany(IEnumerable datas) { try { foreach (var data in datas) { - simu.Assign(data); + simu.Value.Assign(data); } - var diff = simu.GetEfficiency() - baseline; + var diff = simu.Value.GetEfficiency() - baseline; return diff; } finally { - simu.FillTestOp(); + simu.Value.FillTestOp(); } } bool ValidateResult(in EnumResult result) { @@ -40,7 +40,7 @@ bool ValidateResult(in EnumResult result) { var comb = result.comb; for (int i = 0; i < result.init_size; i++) { - var eff = TestMany(simu1, comb.Where(o => o != comb[i])); + var eff = TestMany(comb.Where(o => o != comb[i])); var div_eff = eff + comb[i].SingleEfficiency; var diff_eff = result.eff - div_eff; if (!diff_eff.IsPositive()) return false; @@ -58,12 +58,19 @@ bool ValidateResult(in EnumResult result) { // return 0; // } //} - public IOrderedEnumerable Enumerate(JsonDocument json) { + + private EnumerateContext() { } + public static IOrderedEnumerable Enumerate(JsonDocument json) { + return new EnumerateContext().EnumerateImpl(json); + } + + public IOrderedEnumerable EnumerateImpl(JsonDocument json) { var root = json.RootElement; var preset = root.GetProperty("preset"); - simu1 = InitSimulator(preset); - baseline = simu1.GetEfficiency(); - ops = root.GetProperty("ops").Deserialize(EnumerateHelper.Options); + simu = new(() => InitSimulator(preset)); + baseline = simu.Value.GetEfficiency(); + ops = root.GetProperty("ops").Deserialize(EnumerateHelper.Options) + ?? throw new InvalidOperationException("expected 'ops' as an array, readed null"); var uidmap = new Dictionary(); for(var i = 0; i < ops.Length; i++) { @@ -75,7 +82,7 @@ public IOrderedEnumerable Enumerate(JsonDocument json) { } op.id = i; op.prime = primes[i]; - op.SingleEfficiency = TestSingle(simu1, op); + op.SingleEfficiency = TestSingle(op); } max_size = Math.Min(32, ops.Length); @@ -83,16 +90,23 @@ public IOrderedEnumerable Enumerate(JsonDocument json) { max_size = Math.Min(max_size, max_size_elem.GetInt32()); } - var tasks = new Task[ops.Length]; + // dataflows + var generateFrames = new TransformManyBlock(GenerateFrames); + var processFrame = new TransformManyBlock(ProcessFrame); + + var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; + generateFrames.LinkTo(processFrame, linkOptions); + processFrame.LinkTo(processFrame, linkOptions); + foreach (var op in ops) { - tasks[op.id] = Task.Run(() => { - InitProc(op, InitSimulator(preset)); - }); + generateFrames.Post(op); } - Task.WaitAll(tasks); + generateFrames.Complete(); + processFrame.Completion.Wait(); + return results.Values.Where(v => ValidateResult(v)).OrderByDescending(v => v.eff.GetScore()); } - static Simulator InitSimulator(JsonElement elem) { + static Simulator InitSimulator(in JsonElement elem) { var simu = new Simulator(); foreach (var prop in elem.EnumerateObject()) { simu.SetFacilityState(prop.Name, prop.Value); @@ -108,67 +122,92 @@ static int GetGroupId(OpEnumData[] comb) { return (comb.Length << 24) | (int)f; } - void InitProc(OpEnumData op, Simulator simu) { - RecursivelyProc(new[] { op }, 1, simu, op.SingleEfficiency); + struct Frame { + public OpEnumData[] comb = null!; + public BitArray uset = null!; + public int gid; + public int init_size; + public Efficiency base_eff; + + public Frame(OpEnumData[] comb, in Efficiency base_eff, int ucnt) { + this.comb = comb; + this.base_eff = base_eff; + this.gid = GetGroupId(comb); + this.init_size = comb.Length; + uset = new(ucnt); + foreach (var op in comb) { + uset[op.uid] = true; + } + } + public Frame FromComb(OpEnumData[] new_comb) { + var op = new_comb[^1]; + BitArray new_uset = new(uset); + new_uset[op.uid] = true; + return new Frame { + comb = new_comb, + base_eff = base_eff, + gid = (new_comb.Length << 24) | (gid & 0xffffff) * op.prime % MOD, + init_size = init_size, + uset = new_uset + }; + } + } + + IEnumerable GenerateFrames(OpEnumData op) { + yield return new([op], op.SingleEfficiency, ucnt); if (op.RelevantOps == null) { - return; + yield break; } + var relevants = ops.Where(o => op.RelevantOps.Contains(o.Name)).ToArray(); for (int i = 1; i <= relevants.Length; i++) { var combs = new Combination(relevants, i); foreach (var e in combs.ToEnumerable()) { - var c = (OpEnumData[])e; - var comb = new OpEnumData[i + 1]; - Array.Copy(c, comb, c.Length); - comb[^1] = op; + OpEnumData[] comb = [.. (OpEnumData[])e, op]; // 这里利用了Combination实现返回值为内部数组的特性 Efficiency eff; try { - eff = TestMany(simu, comb); + eff = TestMany(comb); } catch { continue; } - RecursivelyProc(comb, comb.Length, simu, eff); + yield return new(comb, eff, ucnt); } } } - void RecursivelyProc(OpEnumData[] comb, int init_size, Simulator simu, Efficiency eff) { + IEnumerable ProcessFrame(Frame frame) { var f = new BitArray(ucnt); - foreach (var op in comb) { + foreach (var op in frame.comb) { f[op.uid] = true; } foreach (var op in ops) { - if (f[op.uid]) continue; - var new_comb = new OpEnumData[comb.Length + 1]; - Array.Copy(comb, new_comb, comb.Length); - new_comb[comb.Length] = op; - Proc(new_comb, init_size, simu, eff); - } - } - void Proc(OpEnumData[] comb, int init_size, Simulator simu, Efficiency base_eff) { - var gid = GetGroupId(comb); - if (!results.TryAdd(gid, default)) { - return; - } - Efficiency eff; - try { - eff = TestMany(simu, comb); - } catch { - return; - } - var extra_eff = eff - base_eff - comb.Last().SingleEfficiency; - if (!extra_eff.IsPositive()) { - return; - } - var tot_extra_eff = eff; - foreach (var opd in comb) { - tot_extra_eff -= opd.SingleEfficiency; - } - results[gid] = new(comb, init_size, eff, tot_extra_eff); + if (f[op.uid]) continue; // 处理干员表中有同一干员的不同位置 + + OpEnumData[] next_comb = [.. frame.comb, op]; + var gid = GetGroupId(next_comb); + if (!results.TryAdd(gid, default)) { + continue; + } + Efficiency eff; + try { // 检验组合是否能被基建容纳,如果可以,则计算其效率 + eff = TestMany(frame.comb); + } catch { + continue; + } - if (comb.Length < max_size) { - RecursivelyProc(comb, init_size, simu, eff); + // 检验新加入组合的干员是否贡献了额外效率 + var extra_eff = eff - frame.base_eff - frame.comb.Last().SingleEfficiency; + if (!extra_eff.IsPositive()) { + continue; + } + // 计算相较于单干员效率总和的额外效率 + var tot_extra_eff = eff; + foreach (var opd in frame.comb) { + tot_extra_eff -= opd.SingleEfficiency; + } + results[gid] = new(next_comb, frame.init_size, eff, tot_extra_eff); + if (next_comb.Length < max_size) yield return frame.FromComb(next_comb); } } } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs index cdac3f8..925de39 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs @@ -13,7 +13,7 @@ static EnumerateHelper() { } public static void Enumerate(JsonDocument json, Utf8JsonWriter writer) { - var results = new EnumerateContext().Enumerate(json); + var results = EnumerateContext.Enumerate(json); writer.WriteStartArray(); foreach (var r in results) { if (r.eff.IsZero()) continue; From 88f855b7503313bdb225e869a26fa5120b93915b Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Thu, 21 Mar 2024 18:25:00 +0800 Subject: [PATCH 21/39] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B9=B6=E8=A1=8C?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebHelper/Enumerate/EnumerateContext.cs | 55 +++++++++++++------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index e912043..a488db8 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -2,8 +2,9 @@ using InfrastSim.TimeDriven.WebHelper.Enumerate; using System.Collections; using System.Collections.Concurrent; +using System.Diagnostics; using System.Text.Json; -using System.Threading.Tasks.Dataflow; +using System.Threading.Channels; namespace InfrastSim.TimeDriven.WebHelper; internal class EnumerateContext { @@ -17,6 +18,10 @@ internal class EnumerateContext { Efficiency baseline; ConcurrentDictionary results = new(); +#if DEBUG + int[] _lock = new int[Environment.ProcessorCount * 2]; +#endif + Efficiency TestSingle(OpEnumData data) { var op = simu.Value.Assign(data); var diff = simu.Value.GetEfficiency() - baseline; @@ -25,6 +30,14 @@ Efficiency TestSingle(OpEnumData data) { } Efficiency TestMany(IEnumerable datas) { try { +#if DEBUG + var v = Interlocked.CompareExchange(ref _lock[Environment.CurrentManagedThreadId], 1, 0); + if (v != 0) { + if (!Debugger.IsAttached) + Debugger.Launch(); + Debugger.Break(); + } +#endif foreach (var data in datas) { simu.Value.Assign(data); } @@ -32,6 +45,7 @@ Efficiency TestMany(IEnumerable datas) { return diff; } finally { simu.Value.FillTestOp(); + _lock[Environment.CurrentManagedThreadId] = 0; } } bool ValidateResult(in EnumResult result) { @@ -90,19 +104,24 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { max_size = Math.Min(max_size, max_size_elem.GetInt32()); } - // dataflows - var generateFrames = new TransformManyBlock(GenerateFrames); - var processFrame = new TransformManyBlock(ProcessFrame); - - var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; - generateFrames.LinkTo(processFrame, linkOptions); - processFrame.LinkTo(processFrame, linkOptions); - + var channel = Channel.CreateUnbounded(); foreach (var op in ops) { - generateFrames.Post(op); + Task.Run(async () => { + foreach (var frame in GenerateFrames(op)) + await channel.Writer.WriteAsync(frame); + }); + } + var tasks = new Task[Environment.ProcessorCount]; + for (int i = 0; i < tasks.Length; i++) { + tasks[i] = Task.Run(async () => { + while (channel.Reader.TryRead(out var frame)) { + foreach (var outFrame in ProcessFrame(frame)) { + await channel.Writer.WriteAsync(outFrame); + } + } + }); } - generateFrames.Complete(); - processFrame.Completion.Wait(); + Task.WaitAll(tasks); return results.Values.Where(v => ValidateResult(v)).OrderByDescending(v => v.eff.GetScore()); } @@ -129,7 +148,7 @@ struct Frame { public int init_size; public Efficiency base_eff; - public Frame(OpEnumData[] comb, in Efficiency base_eff, int ucnt) { + public Frame(OpEnumData[] comb, Efficiency base_eff, int ucnt) { this.comb = comb; this.base_eff = base_eff; this.gid = GetGroupId(comb); @@ -139,7 +158,7 @@ public Frame(OpEnumData[] comb, in Efficiency base_eff, int ucnt) { uset[op.uid] = true; } } - public Frame FromComb(OpEnumData[] new_comb) { + public Frame FromComb(OpEnumData[] new_comb, Efficiency base_eff) { var op = new_comb[^1]; BitArray new_uset = new(uset); new_uset[op.uid] = true; @@ -191,23 +210,23 @@ IEnumerable ProcessFrame(Frame frame) { } Efficiency eff; try { // 检验组合是否能被基建容纳,如果可以,则计算其效率 - eff = TestMany(frame.comb); + eff = TestMany(next_comb); } catch { continue; } // 检验新加入组合的干员是否贡献了额外效率 - var extra_eff = eff - frame.base_eff - frame.comb.Last().SingleEfficiency; + var extra_eff = eff - frame.base_eff - op.SingleEfficiency; if (!extra_eff.IsPositive()) { continue; } // 计算相较于单干员效率总和的额外效率 var tot_extra_eff = eff; - foreach (var opd in frame.comb) { + foreach (var opd in next_comb) { tot_extra_eff -= opd.SingleEfficiency; } results[gid] = new(next_comb, frame.init_size, eff, tot_extra_eff); - if (next_comb.Length < max_size) yield return frame.FromComb(next_comb); + if (next_comb.Length < max_size) yield return frame.FromComb(next_comb, eff); } } } From 1a9ece3b7a703284316338b2338d1a824cd6c34b Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Thu, 21 Mar 2024 18:29:03 +0800 Subject: [PATCH 22/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E4=B8=8D=E5=AE=8C=E5=85=A8=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimeDriven/WebHelper/Enumerate/EnumerateContext.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index a488db8..4cb4f71 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -18,8 +18,8 @@ internal class EnumerateContext { Efficiency baseline; ConcurrentDictionary results = new(); -#if DEBUG - int[] _lock = new int[Environment.ProcessorCount * 2]; +#if DEBUG // 该参数用于验证是否发生了对 ThreadLocal 参数 simu 的访问冲突 + int[] _lock = new int[Environment.ProcessorCount * 2 + 10]; #endif Efficiency TestSingle(OpEnumData data) { @@ -45,7 +45,9 @@ Efficiency TestMany(IEnumerable datas) { return diff; } finally { simu.Value.FillTestOp(); +#if DEBUG _lock[Environment.CurrentManagedThreadId] = 0; +#endif } } bool ValidateResult(in EnumResult result) { From 4a73f577f94017a74ba6c38b7087437464767f11 Mon Sep 17 00:00:00 2001 From: funny-ppt <1763341376@qq.com> Date: Thu, 21 Mar 2024 18:46:49 +0800 Subject: [PATCH 23/39] =?UTF-8?q?=E4=BF=AE=E6=94=B9WriteAsync=E4=B8=BATryW?= =?UTF-8?q?rite;=E7=90=86=E8=AE=BA=E4=B8=8A=E4=B8=8D=E7=94=A8=E5=88=86?= =?UTF-8?q?=E9=85=8D=E5=92=8C=E7=AD=89=E5=BE=85Task=E4=BC=9A=E6=9B=B4?= =?UTF-8?q?=E5=BF=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimeDriven/WebHelper/Enumerate/EnumerateContext.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index 4cb4f71..047f4db 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -108,17 +108,17 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { var channel = Channel.CreateUnbounded(); foreach (var op in ops) { - Task.Run(async () => { + Task.Run(() => { foreach (var frame in GenerateFrames(op)) - await channel.Writer.WriteAsync(frame); + channel.Writer.TryWrite(frame); }); } var tasks = new Task[Environment.ProcessorCount]; for (int i = 0; i < tasks.Length; i++) { - tasks[i] = Task.Run(async () => { + tasks[i] = Task.Run(() => { while (channel.Reader.TryRead(out var frame)) { foreach (var outFrame in ProcessFrame(frame)) { - await channel.Writer.WriteAsync(outFrame); + channel.Writer.TryWrite(outFrame); } } }); From 9109fe1a12bf94160f20c9cc2c4da3b9742e5310 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 22 Mar 2024 15:36:51 +0800 Subject: [PATCH 24/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E6=97=B6=E5=AF=B9ThreadLocal?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=E7=9A=84=E5=86=B2=E7=AA=81=EF=BC=8C=E7=95=A5?= =?UTF-8?q?=E5=BE=AE=E4=BC=98=E5=8C=96=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebHelper/Enumerate/EnumerateContext.cs | 71 +++++++------------ 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index 047f4db..f0c7076 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -14,49 +14,33 @@ internal class EnumerateContext { int max_size; int ucnt = 0; OpEnumData[] ops = null!; - ThreadLocal simu = null!; Efficiency baseline; ConcurrentDictionary results = new(); -#if DEBUG // 该参数用于验证是否发生了对 ThreadLocal 参数 simu 的访问冲突 - int[] _lock = new int[Environment.ProcessorCount * 2 + 10]; -#endif - - Efficiency TestSingle(OpEnumData data) { - var op = simu.Value.Assign(data); - var diff = simu.Value.GetEfficiency() - baseline; + Efficiency TestSingle(Simulator simu, OpEnumData data) { + var op = simu.Assign(data); + var diff = simu.GetEfficiency() - baseline; op.ReplaceByTestOp(); return diff; } - Efficiency TestMany(IEnumerable datas) { + Efficiency TestMany(Simulator simu, IEnumerable datas) { try { -#if DEBUG - var v = Interlocked.CompareExchange(ref _lock[Environment.CurrentManagedThreadId], 1, 0); - if (v != 0) { - if (!Debugger.IsAttached) - Debugger.Launch(); - Debugger.Break(); - } -#endif foreach (var data in datas) { - simu.Value.Assign(data); + simu.Assign(data); } - var diff = simu.Value.GetEfficiency() - baseline; + var diff = simu.GetEfficiency() - baseline; return diff; } finally { - simu.Value.FillTestOp(); -#if DEBUG - _lock[Environment.CurrentManagedThreadId] = 0; -#endif + simu.FillTestOp(); } } - bool ValidateResult(in EnumResult result) { + bool ValidateResult(Simulator simu, in EnumResult result) { if (result.eff.IsZero()) return false; if (result.init_size == 1) return true; var comb = result.comb; for (int i = 0; i < result.init_size; i++) { - var eff = TestMany(comb.Where(o => o != comb[i])); + var eff = TestMany(simu, comb.Where(o => o != comb[i])); var div_eff = eff + comb[i].SingleEfficiency; var diff_eff = result.eff - div_eff; if (!diff_eff.IsPositive()) return false; @@ -83,8 +67,8 @@ public static IOrderedEnumerable Enumerate(JsonDocument json) { public IOrderedEnumerable EnumerateImpl(JsonDocument json) { var root = json.RootElement; var preset = root.GetProperty("preset"); - simu = new(() => InitSimulator(preset)); - baseline = simu.Value.GetEfficiency(); + var simu1 = InitSimulator(preset); + baseline = simu1.GetEfficiency(); ops = root.GetProperty("ops").Deserialize(EnumerateHelper.Options) ?? throw new InvalidOperationException("expected 'ops' as an array, readed null"); @@ -98,7 +82,7 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { } op.id = i; op.prime = primes[i]; - op.SingleEfficiency = TestSingle(op); + op.SingleEfficiency = TestSingle(simu1, op); } max_size = Math.Min(32, ops.Length); @@ -107,17 +91,16 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { } var channel = Channel.CreateUnbounded(); - foreach (var op in ops) { - Task.Run(() => { - foreach (var frame in GenerateFrames(op)) - channel.Writer.TryWrite(frame); - }); - } + foreach (var op in ops) + foreach (var frame in GenerateFrames(simu1, op)) + channel.Writer.TryWrite(frame); + var tasks = new Task[Environment.ProcessorCount]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Run(() => { + var simu = simu1.Clone(); while (channel.Reader.TryRead(out var frame)) { - foreach (var outFrame in ProcessFrame(frame)) { + foreach (var outFrame in ProcessFrame(simu, frame)) { channel.Writer.TryWrite(outFrame); } } @@ -125,7 +108,9 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { } Task.WaitAll(tasks); - return results.Values.Where(v => ValidateResult(v)).OrderByDescending(v => v.eff.GetScore()); + return results.Values + .Where(v => ValidateResult(simu1, v)) + .OrderByDescending(v => v.eff.GetScore()); } static Simulator InitSimulator(in JsonElement elem) { var simu = new Simulator(); @@ -174,7 +159,7 @@ public Frame FromComb(OpEnumData[] new_comb, Efficiency base_eff) { } } - IEnumerable GenerateFrames(OpEnumData op) { + IEnumerable GenerateFrames(Simulator simu, OpEnumData op) { yield return new([op], op.SingleEfficiency, ucnt); if (op.RelevantOps == null) { @@ -189,7 +174,7 @@ IEnumerable GenerateFrames(OpEnumData op) { Efficiency eff; try { - eff = TestMany(comb); + eff = TestMany(simu, comb); } catch { continue; } @@ -197,13 +182,9 @@ IEnumerable GenerateFrames(OpEnumData op) { } } } - IEnumerable ProcessFrame(Frame frame) { - var f = new BitArray(ucnt); - foreach (var op in frame.comb) { - f[op.uid] = true; - } + IEnumerable ProcessFrame(Simulator simu, Frame frame) { foreach (var op in ops) { - if (f[op.uid]) continue; // 处理干员表中有同一干员的不同位置 + if (frame.uset[op.uid]) continue; // 处理干员表中有同一干员的不同位置 OpEnumData[] next_comb = [.. frame.comb, op]; var gid = GetGroupId(next_comb); @@ -212,7 +193,7 @@ IEnumerable ProcessFrame(Frame frame) { } Efficiency eff; try { // 检验组合是否能被基建容纳,如果可以,则计算其效率 - eff = TestMany(next_comb); + eff = TestMany(simu, next_comb); } catch { continue; } From 3991f58252f9e2e4af851cad3cb028d88887c99b Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 22 Mar 2024 15:39:27 +0800 Subject: [PATCH 25/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AF=B9Clone()?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E8=B0=83=E7=94=A8=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E6=9E=9A=E4=B8=BE=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index f0c7076..46b3e22 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -98,7 +98,7 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { var tasks = new Task[Environment.ProcessorCount]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Run(() => { - var simu = simu1.Clone(); + var simu = InitSimulator(preset); while (channel.Reader.TryRead(out var frame)) { foreach (var outFrame in ProcessFrame(simu, frame)) { channel.Writer.TryWrite(outFrame); From bb687af912461b490ff132c858c7b4e1b765bf54 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 22 Mar 2024 16:27:45 +0800 Subject: [PATCH 26/39] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B0=8F=E7=9A=84?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9B=E5=87=86=E5=A4=87=E5=85=A8=E9=9D=A2?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0=E6=95=B0=E6=8D=AE=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E5=88=B0int=E3=80=81=E9=99=8D=E4=BD=8E=E7=B2=BE=E5=BA=A6?= =?UTF-8?q?=E5=88=B0=E7=A7=92=E7=BA=A7=E5=B9=B6=E4=BC=98=E5=8C=96=E6=95=B4?= =?UTF-8?q?=E4=B8=AA=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebHelper/Enumerate/EnumResult.cs | 13 +----------- .../WebHelper/Enumerate/EnumerateContext.cs | 20 +++++++++---------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs index 7771829..b52637a 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs @@ -1,14 +1,3 @@ namespace InfrastSim.TimeDriven.WebHelper.Enumerate; -internal struct EnumResult { - public EnumResult(OpEnumData[] comb, int init_size, in Efficiency eff, in Efficiency extra_eff) { - this.comb = comb; - this.init_size = init_size; - this.eff = eff; - this.extra_eff = extra_eff; - } - - public OpEnumData[] comb { get; set; } - public int init_size { get; set; } - public Efficiency eff { get; set; } - public Efficiency extra_eff { get; set; } +internal record struct EnumResult(OpEnumData[] comb, int init_size, Efficiency eff, Efficiency extra_eff) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs index 46b3e22..0b26d4c 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs @@ -1,12 +1,10 @@ using InfrastSim.Algorithms; -using InfrastSim.TimeDriven.WebHelper.Enumerate; using System.Collections; using System.Collections.Concurrent; -using System.Diagnostics; using System.Text.Json; using System.Threading.Channels; -namespace InfrastSim.TimeDriven.WebHelper; +namespace InfrastSim.TimeDriven.WebHelper.Enumerate; internal class EnumerateContext { static readonly List primes = EularSieve.Resolve((1 << 24) - 1); const int MOD = 16777213; @@ -34,7 +32,7 @@ Efficiency TestMany(Simulator simu, IEnumerable datas) { simu.FillTestOp(); } } - bool ValidateResult(Simulator simu, in EnumResult result) { + bool ValidateResult(Simulator simu, EnumResult result) { if (result.eff.IsZero()) return false; if (result.init_size == 1) return true; @@ -112,7 +110,7 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { .Where(v => ValidateResult(simu1, v)) .OrderByDescending(v => v.eff.GetScore()); } - static Simulator InitSimulator(in JsonElement elem) { + static Simulator InitSimulator(JsonElement elem) { var simu = new Simulator(); foreach (var prop in elem.EnumerateObject()) { simu.SetFacilityState(prop.Name, prop.Value); @@ -128,12 +126,12 @@ static int GetGroupId(OpEnumData[] comb) { return (comb.Length << 24) | (int)f; } - struct Frame { - public OpEnumData[] comb = null!; - public BitArray uset = null!; - public int gid; - public int init_size; - public Efficiency base_eff; + readonly struct Frame { + public OpEnumData[] comb { get; init; } = null!; + public BitArray uset { get; init; } = null!; + public int gid { get; init; } + public int init_size { get; init; } + public Efficiency base_eff { get; init; } public Frame(OpEnumData[] comb, Efficiency base_eff, int ucnt) { this.comb = comb; From add20fc95d742433db8f9f1e306a39713c225091 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 22 Mar 2024 16:38:10 +0800 Subject: [PATCH 27/39] =?UTF-8?q?=E7=A7=BB=E5=8A=A8Enumerate=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E7=A9=BA=E9=97=B4=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E7=BC=96=E8=AF=91=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{WebHelper => }/Enumerate/DispatchGroup.cs | 2 +- .../{WebHelper => }/Enumerate/Efficiency.cs | 2 +- .../{WebHelper => }/Enumerate/EnumResult.cs | 2 +- .../{WebHelper => }/Enumerate/EnumerateContext.cs | 13 +++++++------ .../{WebHelper => }/Enumerate/EnumerateHelper.cs | 6 +++--- .../TimeDriven/{WebHelper => }/Enumerate/FacConf.cs | 2 +- .../{WebHelper => }/Enumerate/MoodScheduler.cs | 4 ++-- .../TimeDriven/{WebHelper => }/Enumerate/OpConf.cs | 2 +- .../{WebHelper => }/Enumerate/OpEnumData.cs | 2 +- .../TimeDriven/{WebHelper => }/Enumerate/PosConf.cs | 2 +- .../Enumerate/SourceGenerationContext.cs | 2 +- .../TimeDriven/{WebHelper => }/Enumerate/TestOp.cs | 2 +- InfrastSimExports/SimulatorService.cs | 1 + InfrastSimTest/SimulatorTest.cs | 1 + InfrastSimWasm/SimulatorService.cs | 1 + 15 files changed, 24 insertions(+), 20 deletions(-) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/DispatchGroup.cs (56%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/Efficiency.cs (95%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/EnumResult.cs (67%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/EnumerateContext.cs (95%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/EnumerateHelper.cs (98%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/FacConf.cs (56%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/MoodScheduler.cs (89%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/OpConf.cs (66%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/OpEnumData.cs (95%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/PosConf.cs (57%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/SourceGenerationContext.cs (89%) rename InfrastSim/TimeDriven/{WebHelper => }/Enumerate/TestOp.cs (68%) diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/DispatchGroup.cs b/InfrastSim/TimeDriven/Enumerate/DispatchGroup.cs similarity index 56% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/DispatchGroup.cs rename to InfrastSim/TimeDriven/Enumerate/DispatchGroup.cs index 70b129b..47ebe56 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/DispatchGroup.cs +++ b/InfrastSim/TimeDriven/Enumerate/DispatchGroup.cs @@ -1,3 +1,3 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal record class DispatchGroup(FacConf[] Main, string[] Sub) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/Efficiency.cs b/InfrastSim/TimeDriven/Enumerate/Efficiency.cs similarity index 95% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/Efficiency.cs rename to InfrastSim/TimeDriven/Enumerate/Efficiency.cs index 7b10f71..4cda874 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/Efficiency.cs +++ b/InfrastSim/TimeDriven/Enumerate/Efficiency.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven.WebHelper; +namespace InfrastSim.TimeDriven.Enumerate; public record struct Efficiency(double TradEff, double ManuEff, double PowerEff) { public static Efficiency operator -(Efficiency a, Efficiency b) { return new Efficiency(a.TradEff - b.TradEff, a.ManuEff - b.ManuEff, a.PowerEff - b.PowerEff); diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs b/InfrastSim/TimeDriven/Enumerate/EnumResult.cs similarity index 67% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs rename to InfrastSim/TimeDriven/Enumerate/EnumResult.cs index b52637a..80b4890 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumResult.cs +++ b/InfrastSim/TimeDriven/Enumerate/EnumResult.cs @@ -1,3 +1,3 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal record struct EnumResult(OpEnumData[] comb, int init_size, Efficiency eff, Efficiency extra_eff) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs similarity index 95% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs rename to InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs index 0b26d4c..c211362 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs @@ -1,10 +1,11 @@ using InfrastSim.Algorithms; +using InfrastSim.TimeDriven.WebHelper; using System.Collections; using System.Collections.Concurrent; using System.Text.Json; using System.Threading.Channels; -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal class EnumerateContext { static readonly List primes = EularSieve.Resolve((1 << 24) - 1); const int MOD = 16777213; @@ -71,7 +72,7 @@ public IOrderedEnumerable EnumerateImpl(JsonDocument json) { ?? throw new InvalidOperationException("expected 'ops' as an array, readed null"); var uidmap = new Dictionary(); - for(var i = 0; i < ops.Length; i++) { + for (var i = 0; i < ops.Length; i++) { var op = ops[i]; if (uidmap.TryGetValue(op.Name, out var uid)) { op.uid = uid; @@ -123,7 +124,7 @@ static int GetGroupId(OpEnumData[] comb) { foreach (var op in comb) { f = f * op.prime % MOD; } - return (comb.Length << 24) | (int)f; + return comb.Length << 24 | (int)f; } readonly struct Frame { @@ -136,8 +137,8 @@ readonly struct Frame { public Frame(OpEnumData[] comb, Efficiency base_eff, int ucnt) { this.comb = comb; this.base_eff = base_eff; - this.gid = GetGroupId(comb); - this.init_size = comb.Length; + gid = GetGroupId(comb); + init_size = comb.Length; uset = new(ucnt); foreach (var op in comb) { uset[op.uid] = true; @@ -150,7 +151,7 @@ public Frame FromComb(OpEnumData[] new_comb, Efficiency base_eff) { return new Frame { comb = new_comb, base_eff = base_eff, - gid = (new_comb.Length << 24) | (gid & 0xffffff) * op.prime % MOD, + gid = new_comb.Length << 24 | (gid & 0xffffff) * op.prime % MOD, init_size = init_size, uset = new_uset }; diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs b/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs similarity index 98% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs rename to InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs index 925de39..60638a0 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/EnumerateHelper.cs +++ b/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs @@ -1,7 +1,7 @@ -using System.Collections.Concurrent; +using InfrastSim.TimeDriven.WebHelper; using System.Text.Json; -namespace InfrastSim.TimeDriven.WebHelper; +namespace InfrastSim.TimeDriven.Enumerate; public static class EnumerateHelper { internal static readonly JsonSerializerOptions Options; @@ -96,7 +96,7 @@ internal static bool TestAssign(this FacilityBase fac, OperatorBase op) { } internal static OperatorBase Assign(this Simulator simu, OpEnumData data) { var op = simu.GetOperator(data.Name); - op.SetMood((double)((data.MoodLow + data.MoodHigh) >> 1)); + op.SetMood((double)(data.MoodLow + data.MoodHigh >> 1)); op.WorkingTime = data.WarmUp ? TimeSpan.FromHours(10) : TimeSpan.Zero; var facName = data.Fac.ToLower(); diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/FacConf.cs b/InfrastSim/TimeDriven/Enumerate/FacConf.cs similarity index 56% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/FacConf.cs rename to InfrastSim/TimeDriven/Enumerate/FacConf.cs index a14c53d..816a9b5 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/FacConf.cs +++ b/InfrastSim/TimeDriven/Enumerate/FacConf.cs @@ -1,3 +1,3 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal record class FacConf(string FacName, PosConf[] PosConfs) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/MoodScheduler.cs b/InfrastSim/TimeDriven/Enumerate/MoodScheduler.cs similarity index 89% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/MoodScheduler.cs rename to InfrastSim/TimeDriven/Enumerate/MoodScheduler.cs index 79d597b..3b83ce0 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/MoodScheduler.cs +++ b/InfrastSim/TimeDriven/Enumerate/MoodScheduler.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal class MoodScheduler { DispatchGroup[] groups; Dictionary opSettings; @@ -12,7 +12,7 @@ public MoodScheduler(DispatchGroup[] groups, Dictionary opSettin this.groups = groups; this.opSettings = opSettings; this.times = times; - this.cycle = TimeSpan.Zero; + cycle = TimeSpan.Zero; foreach (var time in times) { cycle += time; } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/OpConf.cs b/InfrastSim/TimeDriven/Enumerate/OpConf.cs similarity index 66% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/OpConf.cs rename to InfrastSim/TimeDriven/Enumerate/OpConf.cs index 2336e75..4484d02 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/OpConf.cs +++ b/InfrastSim/TimeDriven/Enumerate/OpConf.cs @@ -1,3 +1,3 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal record class OpConf(string Name, string pos, double InitMood = 24, bool AllowRest = true) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/OpEnumData.cs b/InfrastSim/TimeDriven/Enumerate/OpEnumData.cs similarity index 95% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/OpEnumData.cs rename to InfrastSim/TimeDriven/Enumerate/OpEnumData.cs index 61a36bb..11506d6 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/OpEnumData.cs +++ b/InfrastSim/TimeDriven/Enumerate/OpEnumData.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace InfrastSim.TimeDriven.WebHelper; +namespace InfrastSim.TimeDriven.Enumerate; public class OpEnumData { [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public int id { get; set; } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/PosConf.cs b/InfrastSim/TimeDriven/Enumerate/PosConf.cs similarity index 57% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/PosConf.cs rename to InfrastSim/TimeDriven/Enumerate/PosConf.cs index d6afd65..68ba596 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/PosConf.cs +++ b/InfrastSim/TimeDriven/Enumerate/PosConf.cs @@ -1,3 +1,3 @@ -namespace InfrastSim.TimeDriven.WebHelper.Enumerate; +namespace InfrastSim.TimeDriven.Enumerate; internal record class PosConf(string Name, string[]? Alternatives) { } diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/SourceGenerationContext.cs b/InfrastSim/TimeDriven/Enumerate/SourceGenerationContext.cs similarity index 89% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/SourceGenerationContext.cs rename to InfrastSim/TimeDriven/Enumerate/SourceGenerationContext.cs index 2e601b5..930d850 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/SourceGenerationContext.cs +++ b/InfrastSim/TimeDriven/Enumerate/SourceGenerationContext.cs @@ -1,4 +1,4 @@ -using InfrastSim.TimeDriven.WebHelper.Enumerate; +using InfrastSim.TimeDriven.Enumerate; using System.Text.Json.Serialization; namespace InfrastSim.TimeDriven.WebHelper; diff --git a/InfrastSim/TimeDriven/WebHelper/Enumerate/TestOp.cs b/InfrastSim/TimeDriven/Enumerate/TestOp.cs similarity index 68% rename from InfrastSim/TimeDriven/WebHelper/Enumerate/TestOp.cs rename to InfrastSim/TimeDriven/Enumerate/TestOp.cs index 18abd0e..a2a6912 100644 --- a/InfrastSim/TimeDriven/WebHelper/Enumerate/TestOp.cs +++ b/InfrastSim/TimeDriven/Enumerate/TestOp.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven.WebHelper; +namespace InfrastSim.TimeDriven.Enumerate; internal class TestOp : OperatorBase { public override string Name => "测试干员"; } diff --git a/InfrastSimExports/SimulatorService.cs b/InfrastSimExports/SimulatorService.cs index 8ca980b..4b472ec 100644 --- a/InfrastSimExports/SimulatorService.cs +++ b/InfrastSimExports/SimulatorService.cs @@ -1,4 +1,5 @@ using InfrastSim.TimeDriven; +using InfrastSim.TimeDriven.Enumerate; using InfrastSim.TimeDriven.WebHelper; using System.Collections.Concurrent; using System.Runtime.InteropServices; diff --git a/InfrastSimTest/SimulatorTest.cs b/InfrastSimTest/SimulatorTest.cs index e63f950..c51500a 100644 --- a/InfrastSimTest/SimulatorTest.cs +++ b/InfrastSimTest/SimulatorTest.cs @@ -1,3 +1,4 @@ +using InfrastSim.TimeDriven.Enumerate; using InfrastSim.TimeDriven.WebHelper; using InfrastSim.Wasm; using System.Text; diff --git a/InfrastSimWasm/SimulatorService.cs b/InfrastSimWasm/SimulatorService.cs index 6586cb0..af359e2 100644 --- a/InfrastSimWasm/SimulatorService.cs +++ b/InfrastSimWasm/SimulatorService.cs @@ -1,5 +1,6 @@ using InfrastSim.Localization; using InfrastSim.TimeDriven; +using InfrastSim.TimeDriven.Enumerate; using InfrastSim.TimeDriven.WebHelper; using System.Collections.Concurrent; using System.Runtime.InteropServices.JavaScript; From 087fb162cae446d4df4146f1fb91a17b718f8404 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 16:52:55 +0800 Subject: [PATCH 28/39] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=80=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=EF=BC=9A=E5=86=85=E9=83=A8=E8=AE=A1=E7=AE=97=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E8=BF=81=E7=A7=BB=E5=88=B0=E4=BD=BF=E7=94=A8int?= =?UTF-8?q?=EF=BC=9B=E4=BC=98=E5=8C=96=E8=AE=A1=E7=AE=97=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E5=92=8C=E6=95=B0=E6=8D=AE=E6=94=B6=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/AggregateValue.cs | 100 ++++++------ InfrastSim/Algorithms/Combination.cs | 10 +- InfrastSim/EventDriven/OperatorBase.cs | 2 +- InfrastSim/InfrastSim.csproj | 4 - InfrastSim/NamedValue.cs | 15 +- InfrastSim/Order.cs | 6 +- InfrastSim/Product.cs | 1 + InfrastSim/TicksHelper.cs | 15 ++ InfrastSim/TimeDriven/ControlCenter.cs | 4 +- InfrastSim/TimeDriven/Crafting.cs | 4 +- InfrastSim/TimeDriven/Dormitory.cs | 16 +- InfrastSim/TimeDriven/FacilityBase.cs | 8 +- InfrastSim/TimeDriven/Helper.cs | 4 +- InfrastSim/TimeDriven/ManufacturingStation.cs | 85 +++++----- InfrastSim/TimeDriven/Office.cs | 4 +- InfrastSim/TimeDriven/OperatorBase.cs | 41 ++--- InfrastSim/TimeDriven/OperatorSkillBuilder.cs | 10 +- InfrastSim/TimeDriven/Operators/12F.cs | 2 +- InfrastSim/TimeDriven/Operators/Almond.cs | 8 +- InfrastSim/TimeDriven/Operators/Amiya.cs | 4 +- InfrastSim/TimeDriven/Operators/Ansel.cs | 2 +- InfrastSim/TimeDriven/Operators/Archetto.cs | 2 +- InfrastSim/TimeDriven/Operators/Ashlock.cs | 2 +- InfrastSim/TimeDriven/Operators/Bassline.cs | 4 +- InfrastSim/TimeDriven/Operators/Bena.cs | 8 +- InfrastSim/TimeDriven/Operators/Bibeak.cs | 8 +- InfrastSim/TimeDriven/Operators/Bryophyta.cs | 4 +- InfrastSim/TimeDriven/Operators/Bubble.cs | 6 +- InfrastSim/TimeDriven/Operators/Castle_3.cs | 4 +- InfrastSim/TimeDriven/Operators/Catapult.cs | 4 +- InfrastSim/TimeDriven/Operators/Cement.cs | 4 +- InfrastSim/TimeDriven/Operators/Chestnut.cs | 4 +- InfrastSim/TimeDriven/Operators/Chongyue.cs | 4 +- InfrastSim/TimeDriven/Operators/Cliffheart.cs | 6 +- InfrastSim/TimeDriven/Operators/Coldshot.cs | 6 +- InfrastSim/TimeDriven/Operators/Conviction.cs | 4 +- InfrastSim/TimeDriven/Operators/Czerny.cs | 2 +- .../TimeDriven/Operators/Degenbrecher.cs | 4 +- InfrastSim/TimeDriven/Operators/Delphine.cs | 2 +- InfrastSim/TimeDriven/Operators/Dorothy.cs | 2 +- InfrastSim/TimeDriven/Operators/Durin.cs | 4 +- InfrastSim/TimeDriven/Operators/Dusk.cs | 6 +- .../TimeDriven/Operators/Earthspirit.cs | 6 +- InfrastSim/TimeDriven/Operators/Ebenholz.cs | 2 +- InfrastSim/TimeDriven/Operators/Eunectes.cs | 2 +- .../Operators/ExecutorTheExFoedere.cs | 2 +- InfrastSim/TimeDriven/Operators/FEater.cs | 2 +- InfrastSim/TimeDriven/Operators/Fang.cs | 6 +- InfrastSim/TimeDriven/Operators/Fartooth.cs | 6 +- InfrastSim/TimeDriven/Operators/Fiammetta.cs | 4 +- InfrastSim/TimeDriven/Operators/Flametail.cs | 6 +- InfrastSim/TimeDriven/Operators/Forstleaf.cs | 4 +- InfrastSim/TimeDriven/Operators/Gnosis.cs | 4 +- InfrastSim/TimeDriven/Operators/Goldenglow.cs | 2 +- InfrastSim/TimeDriven/Operators/Gravel.cs | 2 +- InfrastSim/TimeDriven/Operators/Greyy.cs | 2 +- .../Operators/GreyyTheLightningbearer.cs | 2 +- InfrastSim/TimeDriven/Operators/Haze.cs | 4 +- InfrastSim/TimeDriven/Operators/Hibiscus.cs | 2 +- InfrastSim/TimeDriven/Operators/Hoederer.cs | 8 +- InfrastSim/TimeDriven/Operators/Honeyberry.cs | 2 +- InfrastSim/TimeDriven/Operators/Iris.cs | 2 +- InfrastSim/TimeDriven/Operators/Jaye.cs | 6 +- InfrastSim/TimeDriven/Operators/Jessica.cs | 2 +- .../Operators/JessicaTheLiberated.cs | 6 +- InfrastSim/TimeDriven/Operators/Jieyun.cs | 4 +- InfrastSim/TimeDriven/Operators/Kaltsit.cs | 2 +- InfrastSim/TimeDriven/Operators/Kirara.cs | 2 +- InfrastSim/TimeDriven/Operators/KirinRYato.cs | 4 +- InfrastSim/TimeDriven/Operators/Kroos.cs | 5 +- InfrastSim/TimeDriven/Operators/Lancet_2.cs | 4 +- InfrastSim/TimeDriven/Operators/Lava.cs | 4 +- InfrastSim/TimeDriven/Operators/Liskarm.cs | 2 +- InfrastSim/TimeDriven/Operators/Lumen.cs | 2 +- InfrastSim/TimeDriven/Operators/Matterhorn.cs | 2 +- InfrastSim/TimeDriven/Operators/Mayer.cs | 2 +- InfrastSim/TimeDriven/Operators/Melantha.cs | 2 +- InfrastSim/TimeDriven/Operators/Midnight.cs | 6 +- InfrastSim/TimeDriven/Operators/Minimalist.cs | 2 +- InfrastSim/TimeDriven/Operators/Mizuki.cs | 4 +- InfrastSim/TimeDriven/Operators/Morgan.cs | 8 +- InfrastSim/TimeDriven/Operators/Mousse.cs | 6 +- InfrastSim/TimeDriven/Operators/MrNothing.cs | 4 +- InfrastSim/TimeDriven/Operators/Muelsyse.cs | 6 +- InfrastSim/TimeDriven/Operators/Mulberry.cs | 4 +- InfrastSim/TimeDriven/Operators/Myrtle.cs | 4 +- .../TimeDriven/Operators/Nightingale.cs | 2 +- InfrastSim/TimeDriven/Operators/NoirCorne.cs | 4 +- InfrastSim/TimeDriven/Operators/Orchid.cs | 4 +- InfrastSim/TimeDriven/Operators/Pallas.cs | 4 +- InfrastSim/TimeDriven/Operators/Passenger.cs | 4 +- InfrastSim/TimeDriven/Operators/Perfumer.cs | 2 +- InfrastSim/TimeDriven/Operators/Podenco.cs | 4 +- InfrastSim/TimeDriven/Operators/Popukar.cs | 8 +- InfrastSim/TimeDriven/Operators/Ptilopsis.cs | 2 +- InfrastSim/TimeDriven/Operators/Purestream.cs | 4 +- InfrastSim/TimeDriven/Operators/Rangers.cs | 2 +- .../Operators/RathalosSNoirCorne.cs | 2 +- InfrastSim/TimeDriven/Operators/Rosmontis.cs | 2 +- InfrastSim/TimeDriven/Operators/Saileach.cs | 2 +- InfrastSim/TimeDriven/Operators/Scene.cs | 3 +- InfrastSim/TimeDriven/Operators/Shamare.cs | 8 +- InfrastSim/TimeDriven/Operators/Shining.cs | 2 +- InfrastSim/TimeDriven/Operators/ShiraYuki.cs | 4 +- InfrastSim/TimeDriven/Operators/Siege.cs | 2 +- InfrastSim/TimeDriven/Operators/Silence.cs | 2 +- .../Operators/SilenceTheParadigmatic.cs | 2 +- InfrastSim/TimeDriven/Operators/SilverAsh.cs | 2 +- InfrastSim/TimeDriven/Operators/Spot.cs | 2 +- InfrastSim/TimeDriven/Operators/Steward.cs | 4 +- InfrastSim/TimeDriven/Operators/Swire.cs | 2 +- .../Operators/SwireTheElegantWit.cs | 4 +- InfrastSim/TimeDriven/Operators/Tequila.cs | 2 +- .../Operators/TerraResearchCommission.cs | 4 +- InfrastSim/TimeDriven/Operators/Tuye.cs | 2 +- InfrastSim/TimeDriven/Operators/Vanilla.cs | 4 +- InfrastSim/TimeDriven/Operators/Vendela.cs | 4 +- InfrastSim/TimeDriven/Operators/Vermeil.cs | 4 +- InfrastSim/TimeDriven/Operators/Vigil.cs | 2 +- InfrastSim/TimeDriven/Operators/Virtuosa.cs | 2 +- InfrastSim/TimeDriven/Operators/Viviana.cs | 4 +- InfrastSim/TimeDriven/Operators/Vulcan.cs | 4 +- InfrastSim/TimeDriven/Operators/WaaiFu.cs | 11 +- InfrastSim/TimeDriven/Operators/Weedy.cs | 2 +- InfrastSim/TimeDriven/Operators/Whisperain.cs | 2 +- InfrastSim/TimeDriven/Operators/WildMane.cs | 2 +- InfrastSim/TimeDriven/Operators/Windflit.cs | 2 +- InfrastSim/TimeDriven/Operators/Yato.cs | 4 +- .../Operators/\320\223\321\203\320\274.cs" | 8 +- .../\320\233\320\265\321\202\320\276.cs" | 2 +- ...20\267\321\221\320\274\320\272\320\260.cs" | 2 +- InfrastSim/TimeDriven/PowerStation.cs | 4 +- InfrastSim/TimeDriven/Priority.cs | 2 +- InfrastSim/TimeDriven/Reception.cs | 4 +- InfrastSim/TimeDriven/Simulator.cs | 147 ++++++++++-------- InfrastSim/TimeDriven/Skills.cs | 6 +- InfrastSim/TimeDriven/TradingStation.cs | 81 +++++----- InfrastSim/TimeDriven/Training.cs | 4 +- .../TimeDriven/WebHelper/MowerHelper.cs | 13 +- .../GlobalSuppressions.cs | 8 + .../InfrastSimSourceGenerator.csproj | 1 + 141 files changed, 502 insertions(+), 516 deletions(-) create mode 100644 InfrastSim/TicksHelper.cs create mode 100644 InfrastSimSourceGenerator/GlobalSuppressions.cs diff --git a/InfrastSim/AggregateValue.cs b/InfrastSim/AggregateValue.cs index b7b956c..680a705 100644 --- a/InfrastSim/AggregateValue.cs +++ b/InfrastSim/AggregateValue.cs @@ -2,23 +2,14 @@ namespace InfrastSim; -public class AggregateValue : IJsonSerializable { - double _baseValue; - double _value = new(); - readonly Dictionary _additionValues = new(); - readonly HashSet _disables = new(); +public class AggregateValue(int baseValue = 0, int min = int.MinValue, int max = int.MaxValue, bool displayAsPercentage = false) : IJsonSerializable { + int _baseValue = baseValue; + int _value = 0; + readonly Dictionary _additionValues = []; + readonly HashSet _disables = []; bool _upToDate = false; - public AggregateValue(double baseValue = 0.0, double min = double.MinValue, double max = double.MaxValue) { - _baseValue = baseValue; - MinValue = min; - MaxValue = max; - } - - public bool UpToDate { - get => _upToDate; - } - public double CalculatedValue { + public int CalculatedValue { get { if (_upToDate) return _value; _upToDate = true; @@ -28,69 +19,57 @@ public double CalculatedValue { return _value = Math.Clamp(_baseValue + additions, MinValue, MaxValue); } } - public double BaseValue => _baseValue; - public double MinValue { get; set; } - public double MaxValue { get; set; } + public int BaseValue => _baseValue; + public int MinValue { get; set; } = min; + public int MaxValue { get; set; } = max; - public IEnumerable> EnumerateValues() { + public IEnumerable> EnumerateValues() { return _additionValues .ExceptBy(_disables, p => p.Key); } - public double GetValue(string name) - => _additionValues.GetValueOrDefault(name); - public double SetValue(string name, double value) { + public int GetValue(string name) => _additionValues.GetValueOrDefault(name); + public int SetValue(string name, int value) { var oldValue = GetValue(name); - if (Util.Equals(value, oldValue)) { + if (value == oldValue) return oldValue; - } - if (!_disables.Contains(name)) _upToDate = false; + if (!_disables.Contains(name)) + _upToDate = false; return _additionValues[name] = value; } - public double AddValue(string name, double value) { + public int AddValue(string name, int value) { return SetValue(name, value + GetValue(name)); } - public double SetIfGreater(string name, double value) { + public int SetIfGreater(string name, int value) { return SetValue(name, Math.Max(value, GetValue(name))); } - public double SetIfLesser(string name, double value) { + public int SetIfLesser(string name, int value) { return SetValue(name, Math.Min(value, GetValue(name))); } - public double SetValue(NamedValue namedValue) { - return SetValue(namedValue.Name, namedValue.Value); - } - public double AddValue(NamedValue namedValue) { - return AddValue(namedValue.Name, namedValue.Value); - } - public double SetIfGreater(NamedValue namedValue) { - return SetIfGreater(namedValue.Name, namedValue.Value); - } - public double SetIfLesser(NamedValue namedValue) { - return SetIfLesser(namedValue.Name, namedValue.Value); - } + public int SetValue(int value) => SetValue("common", value); + public int AddValue(int value) => AddValue("common", value); + public int SetIfGreater(int value) => SetIfGreater("common", value); + public int SetIfLesser(int value) => SetIfLesser("common", value); public void Disable(string name) { - if (!_disables.Contains(name)) { - if (!Util.Equals(GetValue(name), 0)) _upToDate = false; - _disables.Add(name); + if (_disables.Add(name)) { + if (GetValue(name) != 0) _upToDate = false; } } public void Enable(string name) { - if (_disables.Contains(name)) { - if (!Util.Equals(GetValue(name), 0)) _upToDate = false; - _disables.Remove(name); + if (_disables.Remove(name)) { + if (GetValue(name) != 0) _upToDate = false; } } - public void Remove(string name) { - if (!Util.Equals(GetValue(name), 0)) { + if (GetValue(name) != 0) { _upToDate = false; } _additionValues.Remove(name); } public void Clear() { _disables.Clear(); - foreach (var key in _additionValues.Keys) { + foreach (var key in _additionValues.Keys) { // BENCHMARK REQUIRED: use Clear() or manually set value to 0? _additionValues[key] = 0; } _upToDate = true; @@ -99,17 +78,28 @@ public void Clear() { public void ToJson(Utf8JsonWriter writer, bool detailed = false) { writer.WriteStartObject(); - writer.WriteNumber("value", CalculatedValue); - writer.WriteNumber("base-value", BaseValue); - writer.WriteNumber("min-value", MinValue); - writer.WriteNumber("max-value", MaxValue); + if (displayAsPercentage) { + writer.WriteNumber("value", CalculatedValue / 100.0); + writer.WriteNumber("base-value", BaseValue / 100.0); + writer.WriteNumber("min-value", MinValue / 100.0); + writer.WriteNumber("max-value", MaxValue / 100.0); + } else { + writer.WriteNumber("value", CalculatedValue); + writer.WriteNumber("base-value", BaseValue); + writer.WriteNumber("min-value", MinValue); + writer.WriteNumber("max-value", MaxValue); + } writer.WritePropertyName("details"); writer.WriteStartArray(); foreach (var kvp in _additionValues) { writer.WriteStartObject(); writer.WriteString("tag", kvp.Key); - writer.WriteNumber("value", kvp.Value); + if (displayAsPercentage) { + writer.WriteNumber("value", kvp.Value / 100.0); + } else { + writer.WriteNumber("value", kvp.Value); + } writer.WriteBoolean("disabled", _disables.Contains(kvp.Key)); writer.WriteEndObject(); } @@ -118,7 +108,7 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { writer.WriteEndObject(); } - public static implicit operator double(AggregateValue aggregateValue) { + public static implicit operator int(AggregateValue aggregateValue) { return aggregateValue.CalculatedValue; } } diff --git a/InfrastSim/Algorithms/Combination.cs b/InfrastSim/Algorithms/Combination.cs index ba823b6..56d2f8c 100644 --- a/InfrastSim/Algorithms/Combination.cs +++ b/InfrastSim/Algorithms/Combination.cs @@ -38,18 +38,18 @@ public Combination(IList values, int n) { return arr; } - public IEnumerator> GetEnumerator() { + public IEnumerator?> GetEnumerator() { return new Enumerator(this); } public IEnumerable> ToEnumerable() { - IEnumerable? cur = null; + IEnumerable? cur; while ((cur = Enumerate()) != null) { yield return cur; } } - class Enumerator : IEnumerator> { + class Enumerator : IEnumerator?> { Combination _combination; IEnumerable? _cur = null; @@ -57,8 +57,8 @@ public Enumerator(Combination combination) { _combination = combination; } - public IEnumerable Current => _cur; - object IEnumerator.Current => _cur; + public IEnumerable? Current => _cur; + object? IEnumerator.Current => _cur; public bool MoveNext() { _cur = _combination.Enumerate(); diff --git a/InfrastSim/EventDriven/OperatorBase.cs b/InfrastSim/EventDriven/OperatorBase.cs index 59a5463..07d265f 100644 --- a/InfrastSim/EventDriven/OperatorBase.cs +++ b/InfrastSim/EventDriven/OperatorBase.cs @@ -3,7 +3,7 @@ namespace InfrastSim.EventDriven; internal abstract class OperatorBase : IEventSource { public double Mood { get; private set; } - public AggregateValue MoodConsumeRate { get; private set; } = new(1.0); + public AggregateValue MoodConsumeRate { get; private set; } = new(100); public DateTime TriggerTime => throw new NotImplementedException(); diff --git a/InfrastSim/InfrastSim.csproj b/InfrastSim/InfrastSim.csproj index f60cfc1..67034f0 100644 --- a/InfrastSim/InfrastSim.csproj +++ b/InfrastSim/InfrastSim.csproj @@ -6,12 +6,8 @@ enable true true - true - - - diff --git a/InfrastSim/NamedValue.cs b/InfrastSim/NamedValue.cs index 95b6846..c69645b 100644 --- a/InfrastSim/NamedValue.cs +++ b/InfrastSim/NamedValue.cs @@ -1,17 +1,12 @@ namespace InfrastSim; -public struct NamedValue { - public string Name; - public double Value; +public struct NamedValue(string name, int value) { + public string Name = name ?? throw new ArgumentNullException(nameof(name)); + public int Value = value; - public NamedValue(string name, double value) { - Name = name ?? throw new ArgumentNullException(nameof(name)); - Value = value; - } - - public static implicit operator NamedValue(double value) { + public static implicit operator NamedValue(int value) { return new("common", value); } - public static implicit operator double(NamedValue value) { + public static implicit operator int(NamedValue value) { return value.Value; } } diff --git a/InfrastSim/Order.cs b/InfrastSim/Order.cs index bad36f6..41cf41e 100644 --- a/InfrastSim/Order.cs +++ b/InfrastSim/Order.cs @@ -5,11 +5,13 @@ namespace InfrastSim; public record Order(int RequiredLevel, TimeSpan ProduceTime, Material Consumes, Material Earns) : IJsonSerializable { - public readonly static Order[] Gold = { + public int ProduceTicks { get; init; } = ProduceTime.ToSimuTicks(); + + public readonly static Order[] Gold = [ new(1, TimeSpan.FromMinutes(144), new Material("赤金", 2), new Material("龙门币", 1000)), new(2, TimeSpan.FromMinutes(210), new Material("赤金", 3), new Material("龙门币", 1500)), new(3, TimeSpan.FromMinutes(276), new Material("赤金", 4), new Material("龙门币", 2000)), - }; + ]; public readonly static Order OriginStone = new(3, TimeSpan.FromMinutes(120), new Material("源石碎片", 2), new Material("合成玉", 20)); public void ToJson(Utf8JsonWriter writer, bool detailed = false) { diff --git a/InfrastSim/Product.cs b/InfrastSim/Product.cs index 572102b..631d98c 100644 --- a/InfrastSim/Product.cs +++ b/InfrastSim/Product.cs @@ -1,6 +1,7 @@ namespace InfrastSim; public record Product( string Name, int Volume, int RequiredLevel, TimeSpan ProduceTime, Material[]? Consumes = null) { + public int ProduceTicks { get; init; } = ProduceTime.ToSimuTicks(); public readonly static Product[] CombatRecords = [ new("基础作战记录", 2, 1, TimeSpan.FromMinutes(45)), diff --git a/InfrastSim/TicksHelper.cs b/InfrastSim/TicksHelper.cs new file mode 100644 index 0000000..1ff3978 --- /dev/null +++ b/InfrastSim/TicksHelper.cs @@ -0,0 +1,15 @@ +namespace InfrastSim; +internal static class TicksHelper { + public const long TimeSpanTicksPerTick = 100000L; + public const int TicksPerSecond = 100; + public const int TicksPerMinute = TicksPerSecond * 60; + public const int TicksPerHours = TicksPerMinute * 24; + public const int TicksPerDrone = TicksPerMinute * 3; // 3 minute + public const int TicksToProduceDrone = TicksPerMinute * 6; // 6 minute + public const int TicksToProducerefresh = TicksPerHours * 12; // 12 hours + + public static int ToSimuTicks(this TimeSpan ts) => (int)(ts.Ticks / TimeSpanTicksPerTick); + public static int TotalSeconds(this TimeSpan ts) => (int)(ts.Ticks / TimeSpan.TicksPerSecond); + public static int HoursNotExceed(this TimeSpan ts, int n) => Math.Min(n, (int)(ts.Ticks / TimeSpan.TicksPerHour)); + public static TimeSpan SimuTicksToTimeSpan(this int simuTicks) => TimeSpan.FromTicks(simuTicks * TimeSpanTicksPerTick); +} diff --git a/InfrastSim/TimeDriven/ControlCenter.cs b/InfrastSim/TimeDriven/ControlCenter.cs index ee4dc7e..ab62b6a 100644 --- a/InfrastSim/TimeDriven/ControlCenter.cs +++ b/InfrastSim/TimeDriven/ControlCenter.cs @@ -4,8 +4,8 @@ public class ControlCenter : FacilityBase { public override int PowerConsumes => 0; public override int AcceptOperatorNums => Level; - public override double MoodConsumeModifier => -WorkingOperatorsCount * 0.05; - public override double EffiencyModifier => 0.0; + public override int MoodConsumeModifier => -WorkingOperatorsCount * 5; + public override int EffiencyModifier => 0; public AggregateValue ExtraMoodModifier { get; } = new(); public override void Reset() { diff --git a/InfrastSim/TimeDriven/Crafting.cs b/InfrastSim/TimeDriven/Crafting.cs index db65ecf..bb1655d 100644 --- a/InfrastSim/TimeDriven/Crafting.cs +++ b/InfrastSim/TimeDriven/Crafting.cs @@ -10,7 +10,7 @@ public class Crafting : FacilityBase { public override bool IsWorking => false; - public override double MoodConsumeModifier => 0; + public override int MoodConsumeModifier => 0; - public override double EffiencyModifier => 0; + public override int EffiencyModifier => 0; } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Dormitory.cs b/InfrastSim/TimeDriven/Dormitory.cs index 277965f..942f0dc 100644 --- a/InfrastSim/TimeDriven/Dormitory.cs +++ b/InfrastSim/TimeDriven/Dormitory.cs @@ -13,23 +13,23 @@ public class Dormitory : FacilityBase { public override bool IsWorking => true; // force operators to calculate mood change public override int AcceptOperatorNums => 5; - public override double MoodConsumeModifier { + public override int MoodConsumeModifier { get { - return -(1 + 1.5 + 0.1 * Level); + return -(100 + 150 + 10 * Level); // 宿舍等级提供 1.6-2 每小时心情回复,其中100为抵消角色基础消耗100 } } public OperatorBase? Vip { get; private set; } - public double VipMoodModifier { get; private set; } - public double DormMoodModifier { get; private set; } - public void SetVipMoodModifier(double value) { + public int VipMoodModifier { get; private set; } + public int DormMoodModifier { get; private set; } + public void SetVipMoodModifier(int value) { VipMoodModifier = Math.Min(VipMoodModifier, value); } - public void SetDormMoodModifier(double value) { + public void SetDormMoodModifier(int value) { DormMoodModifier = Math.Min(DormMoodModifier, value); } - public override double EffiencyModifier => 0.0; + public override int EffiencyModifier => 0; public int Atmosphere => Level * 1000; public override void Reset() { @@ -66,7 +66,7 @@ public override void Resolve(Simulator simu) { simu.Delay((simu) => { foreach (var op in Operators) { - op.MoodConsumeRate.SetValue("dorm-atmosphere", -0.0004 * Atmosphere); + op.MoodConsumeRate.SetValue("dorm-atmosphere", (int)(-0.04 * Atmosphere)); op.MoodConsumeRate.SetValue("dorm-extra", DormMoodModifier); op.MoodConsumeRate.Disable("control-center"); op.MoodConsumeRate.Disable("control-center-extra"); diff --git a/InfrastSim/TimeDriven/FacilityBase.cs b/InfrastSim/TimeDriven/FacilityBase.cs index 9fe5f8b..1d580ab 100644 --- a/InfrastSim/TimeDriven/FacilityBase.cs +++ b/InfrastSim/TimeDriven/FacilityBase.cs @@ -89,9 +89,9 @@ public void SetLevel(int level) { } } - public abstract double MoodConsumeModifier { get; } - public abstract double EffiencyModifier { get; } - public double TotalEffiencyModifier => WorkingOperators.Sum(op => op.EfficiencyModifier) + EffiencyModifier; + public abstract int MoodConsumeModifier { get; } + public abstract int EffiencyModifier { get; } + public int TotalEffiencyModifier => WorkingOperators.Sum(op => op.EfficiencyModifier) + EffiencyModifier; public virtual void Reset() { foreach (var op in Operators) { @@ -162,7 +162,7 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { WriteDerivedContent(writer, detailed); if (detailed) { - writer.WriteNumber("base-efficiency", 1 + EffiencyModifier); + writer.WriteNumber("base-efficiency", (100 + EffiencyModifier) / 100.0); writer.WriteNumber("operators-efficiency", WorkingOperators.Sum(op => op.EfficiencyModifier)); } diff --git a/InfrastSim/TimeDriven/Helper.cs b/InfrastSim/TimeDriven/Helper.cs index 8c1eaae..7cce6c6 100644 --- a/InfrastSim/TimeDriven/Helper.cs +++ b/InfrastSim/TimeDriven/Helper.cs @@ -52,12 +52,12 @@ public static int GetRealGoldProductionLine(this Simulator simu) } public static int GetGoldProductionLine(this Simulator simu) { - return (int)simu.ExtraGoldProductionLine + simu.GetRealGoldProductionLine(); + return simu.ExtraGoldProductionLine + simu.GetRealGoldProductionLine(); } public static int PowerStationsCount(this Simulator simu) { - return (int)simu.ExtraPowerStation + simu.PowerStations.Count(); + return simu.ExtraPowerStation + simu.PowerStations.Count(); } public static bool IsProduceGold(this ManufacturingStation manufacturing) { return manufacturing.Product == Product.Gold; diff --git a/InfrastSim/TimeDriven/ManufacturingStation.cs b/InfrastSim/TimeDriven/ManufacturingStation.cs index 427217d..877d3d5 100644 --- a/InfrastSim/TimeDriven/ManufacturingStation.cs +++ b/InfrastSim/TimeDriven/ManufacturingStation.cs @@ -1,3 +1,4 @@ +using InfrastSim.TimeDriven.Enumerate; using System.Diagnostics; using System.Text.Json; @@ -12,13 +13,12 @@ public class ManufacturingStation : FacilityBase, IApplyDrones { _ => 0, }; public AggregateValue Capacity { get; private set; } = new AggregateValue(0, 1, 1000); - public int CapacityN => (int)Capacity; public int CapacityOccupied => Product == null ? 0 : ProductCount * Product.Volume; public int ProductCount { get; internal set; } = 0; - public bool CanStoreMore => Product != null && CapacityN - CapacityOccupied >= Product.Volume; + public bool CanStoreMore => Product != null && Capacity - CapacityOccupied >= Product.Volume; public Product? Product { get; private set; } - public double Progress { get; private set; } - public TimeSpan RemainsTime => Product == null ? TimeSpan.MaxValue : Product.ProduceTime * (1 - Progress); + public int Progress { get; private set; } + public int RemainTicks => (Product?.ProduceTicks ?? int.MaxValue) - Progress; public void ChangeProduct(Product newProduct) { if (newProduct != Product) { if (newProduct.RequiredLevel > Level) { @@ -32,18 +32,8 @@ public void ChangeProduct(Product newProduct) { } } - public override double MoodConsumeModifier { - get { - return Math.Min(0.0, -0.05 * (WorkingOperatorsCount - 1)); - } - } - public override double EffiencyModifier { - get { - return 0.01 * WorkingOperatorsCount; - } - } - - + public override int MoodConsumeModifier => Math.Min(0, -5 * (WorkingOperatorsCount - 1)); + public override int EffiencyModifier => WorkingOperatorsCount; public override int AcceptOperatorNums => Level; public override bool IsWorking => CanStoreMore && Operators.Any(); @@ -58,49 +48,40 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); } public override void QueryInterest(Simulator simu) { - var effiency = 1 + TotalEffiencyModifier + simu.GlobalManufacturingEfficiency; - var remains = RemainsTime / effiency; - simu.SetInterest(this, remains); + var efficiency = 100 + TotalEffiencyModifier + simu.GlobalManufacturingEfficiency; + var remainSeconds = (RemainTicks + efficiency - 1) / efficiency; + simu.SetInterest(this, remainSeconds); base.QueryInterest(simu); } public override void Update(Simulator simu, TimeElapsedInfo info) { if (IsWorking) { - var effiency = 1 + TotalEffiencyModifier + simu.GlobalManufacturingEfficiency; - var equivTime = info.TimeElapsed * effiency; - if (equivTime >= RemainsTime) { - var remains = equivTime - RemainsTime; - - ProductCount += 1; - if (CanStoreMore) { - Debug.Assert(Product != null); - Progress = remains / Product.ProduceTime; - } - } else { - Progress += equivTime / Product!.ProduceTime; - } + var efficiency = 100 + TotalEffiencyModifier + simu.GlobalManufacturingEfficiency; + var pendingProgress = info.TimeElapsed.TotalSeconds() * efficiency; + Progress += pendingProgress; + simu.AddManuProgress(pendingProgress); + ProductCount = Math.Min(Capacity, ProductCount + Progress / Product!.ProduceTicks); // IsWorking == true => product is not null + if (CanStoreMore) + Progress %= Product.ProduceTicks; + else + Progress = 0; } base.Update(simu, info); } - public int ApplyDrones(Simulator simu, int amount) { if (Product == null) return 0; - amount = Math.Min(amount, simu.Drones); - var time = TimeSpan.FromMinutes(3 * amount); + // 计算过程可能超出int上限,将第一个参数提升到long + var max = ((long)Product.ProduceTicks * (Capacity / Product.Volume - ProductCount) - Progress + TicksHelper.TicksPerDrone - 1) / TicksHelper.TicksPerDrone; + amount = Math.Min(amount, Math.Min((int)max, simu.Drones)); - while (CanStoreMore && time >= RemainsTime) { - time -= RemainsTime; + Progress += amount * TicksHelper.TicksPerDrone; + ProductCount += Progress / Product.ProduceTicks; + if (CanStoreMore) + Progress %= Product.ProduceTicks; + else Progress = 0; - ProductCount += 1; - } - if (CanStoreMore) { - Progress += time / Product.ProduceTime; - } else { - var remains = (int)Math.Floor(time / TimeSpan.FromMinutes(3)); - amount -= remains; - } simu.RemoveDrones(amount); return amount; } @@ -114,16 +95,13 @@ protected override void WriteDerivedContent(Utf8JsonWriter writer, bool detailed if (detailed) { if (Product != null) writer.WriteString("product", Product.Name); else writer.WriteNull("product"); - writer.WriteNumber("remains", RemainsTime.TotalSeconds); + writer.WriteNumber("remains", (RemainTicks + TicksHelper.TicksPerSecond - 1) / TicksHelper.TicksPerSecond); writer.WriteNumber("base-capacity", BaseCapacity); - writer.WriteNumber("capacity", CapacityN); + writer.WriteNumber("capacity", Capacity); writer.WriteItem("capacity-details", Capacity); } } protected override void ReadDerivedContent(JsonElement elem) { - if (elem.TryGetProperty("progress", out var progress)) { - Progress = progress.GetDouble(); - } if (elem.TryGetProperty("product-index", out var productIndex)) { var index = productIndex.GetInt32(); if (index >= 0 && index < Product.AllProducts.Length) { @@ -133,5 +111,12 @@ protected override void ReadDerivedContent(JsonElement elem) { if (elem.TryGetProperty("product-count", out var productCount)) { ProductCount = productCount.GetInt32(); } + if (elem.TryGetProperty("progress", out var progress)) { + if (progress.TryGetDouble(out var value)) { + if (Product != null) Progress = (int)(Product.ProduceTicks * (1 - value)); + } else { + Progress = progress.GetInt32(); + } + } } } diff --git a/InfrastSim/TimeDriven/Office.cs b/InfrastSim/TimeDriven/Office.cs index 2940292..637e643 100644 --- a/InfrastSim/TimeDriven/Office.cs +++ b/InfrastSim/TimeDriven/Office.cs @@ -3,8 +3,8 @@ public class Office : FacilityBase { public override FacilityType Type => FacilityType.Office; public override int AcceptOperatorNums => 1; - public override double MoodConsumeModifier => 0.0; - public override double EffiencyModifier => WorkingOperatorsCount * 0.05; + public override int MoodConsumeModifier => 0; + public override int EffiencyModifier => WorkingOperatorsCount * 5; public static readonly TimeSpan ProduceTime = TimeSpan.FromHours(12); } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/OperatorBase.cs b/InfrastSim/TimeDriven/OperatorBase.cs index dde3045..7f7ef5e 100644 --- a/InfrastSim/TimeDriven/OperatorBase.cs +++ b/InfrastSim/TimeDriven/OperatorBase.cs @@ -6,7 +6,7 @@ namespace InfrastSim.TimeDriven; public abstract class OperatorBase : ITimeDrivenObject, IJsonSerializable { public abstract string Name { get; } - public virtual string[] Groups => Array.Empty(); + public virtual string[] Groups => []; public bool HasGroup(string group) => Groups.Contains(group) || OperatorGroups.Groups.GetValueOrDefault(group)?.Contains(Name) == true; @@ -17,20 +17,13 @@ public bool HasGroup(string group) => public const int MaxTicks = 8640000; public const int TiredTicks = 50; public const int MinTicks = 0; - public const long TimeSpanTicksPerSimuTick = 100000L; static int MoodToTicks(double mood) { return (int)(mood / MaxMood * MaxTicks); } - static int TimeSpanToTicks(TimeSpan timeSpan) { - return (int)(timeSpan.Ticks / TimeSpanTicksPerSimuTick); - } - static TimeSpan TicksToTimeSpan(long ticks) { - return new TimeSpan((long)(ticks * TimeSpanTicksPerSimuTick)); - } public int Upgraded { get; set; } = 2; - public double Mood => MoodTicks / (double)MaxTicks * MaxMood; + public double Mood => (double)MoodTicks / MaxTicks * MaxMood; public int MoodTicks { get; private set; } = MaxTicks; public void SetMood(double mood) { MoodTicks = MoodToTicks(Math.Clamp(mood, MinMood, MaxMood)); @@ -38,17 +31,17 @@ public void SetMood(double mood) { public void SetMood(int mood) { MoodTicks = Math.Clamp(mood, MinTicks, MaxTicks); } - static readonly int[] DefaultThreshold = new int[] { 0 }; + static readonly int[] DefaultThreshold = [0]; public virtual int[] Thresholds => DefaultThreshold; - static readonly TimeSpan[] DefaultWorkingTimeThreshold = Array.Empty(); + static readonly TimeSpan[] DefaultWorkingTimeThreshold = []; public virtual TimeSpan[] WorkingTimeThresholds => DefaultWorkingTimeThreshold; public bool IsTired => MoodTicks <= TiredTicks; public bool IsExausted => MoodTicks == MinTicks; public bool IsFullOfEnergy => MoodTicks == MaxTicks; public virtual int DormVipPriority => 1; - public AggregateValue MoodConsumeRate { get; private set; } = new(1); - public AggregateValue EfficiencyModifier { get; private set; } = new(); + public AggregateValue MoodConsumeRate { get; private set; } = new(100, displayAsPercentage: true); + public AggregateValue EfficiencyModifier { get; private set; } = new(displayAsPercentage: true); public TimeSpan WorkingTime { get; internal set; } = TimeSpan.Zero; public bool LeaveFacility() { @@ -59,7 +52,7 @@ public bool LeaveFacility() { public virtual void Reset() { MoodConsumeRate.Clear(); EfficiencyModifier.Clear(); - EfficiencyModifier.MaxValue = double.MaxValue; + EfficiencyModifier.MaxValue = int.MaxValue; } public virtual void Resolve(Simulator simu) { @@ -68,7 +61,7 @@ public virtual void Resolve(Simulator simu) { public virtual void QueryInterest(Simulator simu) { Debug.Assert(Facility != null); if (Facility.IsWorking) { - var ticks = MaxTicks; // 距离最近检查点的 ticks,除以心情消耗率即为实际ticks + var seconds = MaxTicks / 100; // 距离最近检查点的秒数 if (MoodConsumeRate > 0) { //foreach (var threshold in Thresholds) { // if (Mood - threshold > Util.Epsilon) { @@ -79,30 +72,30 @@ public virtual void QueryInterest(Simulator simu) { // 尝试保持行为和方舟一致。 if (MoodTicks > TiredTicks) { - ticks = (int)((MoodTicks - TiredTicks) / MoodConsumeRate); + seconds = (MoodTicks - TiredTicks + MoodConsumeRate - 1) / MoodConsumeRate; } } else { if (MaxTicks > MoodTicks) { - ticks = (int)((MoodTicks - MaxTicks) / MoodConsumeRate); + seconds = (MoodTicks - MaxTicks - MoodConsumeRate + 1) / MoodConsumeRate; } } if (Facility is not Dormitory && !IsTired) { foreach (var threshold in WorkingTimeThresholds) { if (threshold > WorkingTime) { - ticks = Math.Min(ticks, TimeSpanToTicks(threshold - WorkingTime)); + seconds = Math.Min(seconds, (threshold - WorkingTime).TotalSeconds()); break; } } } - simu.SetInterest(this, TicksToTimeSpan(ticks)); + simu.SetInterest(this, seconds); // TEST REQUIRED: 该方法未经测试,可能有重大bug } } public virtual void Update(Simulator simu, TimeElapsedInfo info) { - Debug.Assert(Facility != null); - if (Facility.IsWorking) { // 如果 Update 被调用,则 Facility 必不为null - int consumes = (int)(TimeSpanToTicks(info.TimeElapsed) * MoodConsumeRate); + Debug.Assert(Facility != null); // 如果 Update 被调用,则 Facility 必不为null + if (Facility.IsWorking) { + int consumes = info.TimeElapsed.TotalSeconds() * MoodConsumeRate; MoodTicks = Math.Clamp(MoodTicks - consumes, TiredTicks, MaxTicks); WorkingTime += info.TimeElapsed; } @@ -169,8 +162,8 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { public OperatorBase Clone() { var clone = (OperatorBase)MemberwiseClone(); clone.Facility = null; - clone.MoodConsumeRate = new(1); // Important: this must keep with the constructor - clone.EfficiencyModifier = new(); + clone.MoodConsumeRate = new(100, displayAsPercentage: true); // Important: this must keep with the constructor + clone.EfficiencyModifier = new(displayAsPercentage: true); return clone; } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/OperatorSkillBuilder.cs b/InfrastSim/TimeDriven/OperatorSkillBuilder.cs index 15e9da2..2fcadfb 100644 --- a/InfrastSim/TimeDriven/OperatorSkillBuilder.cs +++ b/InfrastSim/TimeDriven/OperatorSkillBuilder.cs @@ -5,7 +5,7 @@ namespace InfrastSim.TimeDriven; internal class OperatorSkillBuilder { Expression? _resolveExpr; - List>> _actionGroup = new(); + List>> _actionGroup = []; readonly ParameterExpression _opParam = Expression.Parameter(typeof(OperatorBase), "op"); readonly ParameterExpression _simuParam = Expression.Parameter(typeof(Simulator), "simu"); @@ -59,19 +59,19 @@ public OperatorSkillBuilder WithGroupMemberInSameFacility(string group) { If((op, simu) => op.Facility != null && op.Facility.HasGroupMember(group)); return this; } - public OperatorSkillBuilder SetGlobalValueIfGreater(string name, string tag, double value) { + public OperatorSkillBuilder SetGlobalValueIfGreater(string name, string tag, int value) { Do((op, simu) => simu.GetGlobalValue(name).SetIfGreater(tag, value)); return this; } - public OperatorSkillBuilder SetValue(AggregateValue aggregateValue, string tag, double value) { + public OperatorSkillBuilder SetValue(AggregateValue aggregateValue, string tag, int value) { Do((op, simu) => aggregateValue.SetValue(tag, value)); return this; } - public OperatorSkillBuilder SetValueIfGreater(AggregateValue aggregateValue, string tag, double value) { + public OperatorSkillBuilder SetValueIfGreater(AggregateValue aggregateValue, string tag, int value) { Do((op, simu) => aggregateValue.SetIfGreater(tag, value)); return this; } - public OperatorSkillBuilder SetValueIfLesser(AggregateValue aggregateValue, string tag, double value) { + public OperatorSkillBuilder SetValueIfLesser(AggregateValue aggregateValue, string tag, int value) { Do((op, simu) => aggregateValue.SetIfLesser(tag, value)); return this; } diff --git a/InfrastSim/TimeDriven/Operators/12F.cs b/InfrastSim/TimeDriven/Operators/12F.cs index 09334fd..3b9a824 100644 --- a/InfrastSim/TimeDriven/Operators/12F.cs +++ b/InfrastSim/TimeDriven/Operators/12F.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Reception && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); } } } diff --git a/InfrastSim/TimeDriven/Operators/Almond.cs b/InfrastSim/TimeDriven/Operators/Almond.cs index d780f00..19bb32c 100644 --- a/InfrastSim/TimeDriven/Operators/Almond.cs +++ b/InfrastSim/TimeDriven/Operators/Almond.cs @@ -8,15 +8,15 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - MoodConsumeRate.SetValue(Name, 0.25); + MoodConsumeRate.SetValue(Name, 25); if (manufacturing.Product == Product.Gold) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); if (Upgraded >= 2) { var count = simu.GroupMemberCount("黑钢国际"); count = Math.Min(count, 3); - EfficiencyModifier.AddValue(Name, count * 0.02); - MoodConsumeRate.AddValue(Name, count * -0.15); + EfficiencyModifier.AddValue(Name, count * 2); + MoodConsumeRate.AddValue(Name, count * -15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Amiya.cs b/InfrastSim/TimeDriven/Operators/Amiya.cs index 4fe5e10..49ba00c 100644 --- a/InfrastSim/TimeDriven/Operators/Amiya.cs +++ b/InfrastSim/TimeDriven/Operators/Amiya.cs @@ -6,10 +6,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility?.Type == FacilityType.ControlCenter && !IsTired) { - simu.GlobalTradingEfficiency.SetIfGreater(0.07); + simu.GlobalTradingEfficiency.SetIfGreater(7); } if (Facility is Dormitory dorm && Upgraded >= 2) { - dorm.SetDormMoodModifier(-0.15); + dorm.SetDormMoodModifier(-15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Ansel.cs b/InfrastSim/TimeDriven/Operators/Ansel.cs index d5a2576..f072452 100644 --- a/InfrastSim/TimeDriven/Operators/Ansel.cs +++ b/InfrastSim/TimeDriven/Operators/Ansel.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.55); + dorm.SetVipMoodModifier(-55); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/Archetto.cs b/InfrastSim/TimeDriven/Operators/Archetto.cs index e6b7498..a3e8a58 100644 --- a/InfrastSim/TimeDriven/Operators/Archetto.cs +++ b/InfrastSim/TimeDriven/Operators/Archetto.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - var sum = simu.Dormitories.Sum(fac => fac?.Level ?? 0)* (Upgraded >= 2 ? 0.02 : 0.01); + var sum = simu.Dormitories.Sum(fac => fac?.Level ?? 0)* (Upgraded >= 2 ? 2 : 1); EfficiencyModifier.SetValue(Name, sum); } } diff --git a/InfrastSim/TimeDriven/Operators/Ashlock.cs b/InfrastSim/TimeDriven/Operators/Ashlock.cs index 0e9dccb..ff2df89 100644 --- a/InfrastSim/TimeDriven/Operators/Ashlock.cs +++ b/InfrastSim/TimeDriven/Operators/Ashlock.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 15); } } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Bassline.cs b/InfrastSim/TimeDriven/Operators/Bassline.cs index eb3c12a..0c96243 100644 --- a/InfrastSim/TimeDriven/Operators/Bassline.cs +++ b/InfrastSim/TimeDriven/Operators/Bassline.cs @@ -7,8 +7,8 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.3 : 0.1); + MoodConsumeRate.SetValue(Name, -25); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 30 : 10); if (Upgraded >= 2) { simu.Wushenggongming.SetValue(Name, 30); // FIXME: hardcoded } diff --git a/InfrastSim/TimeDriven/Operators/Bena.cs b/InfrastSim/TimeDriven/Operators/Bena.cs index d0edd18..074450c 100644 --- a/InfrastSim/TimeDriven/Operators/Bena.cs +++ b/InfrastSim/TimeDriven/Operators/Bena.cs @@ -6,14 +6,14 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, -0.2); - MoodConsumeRate.SetValue(Name, -0.25); + EfficiencyModifier.SetValue(Name, -20); + MoodConsumeRate.SetValue(Name, -25); manufacturing.Capacity.SetValue(Name, 17); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); trading.PreGoldOrderPending += args => - args.Priority4Gold.SetIfGreater(0.67 * Math.Min(1, WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(67 * Math.Min(1, WorkingTime.TotalHours / 3))); } } } diff --git a/InfrastSim/TimeDriven/Operators/Bibeak.cs b/InfrastSim/TimeDriven/Operators/Bibeak.cs index e75f3bd..82160af 100644 --- a/InfrastSim/TimeDriven/Operators/Bibeak.cs +++ b/InfrastSim/TimeDriven/Operators/Bibeak.cs @@ -7,16 +7,16 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); if (Upgraded < 2) { trading.PreGoldOrderPending += args => - args.Priority4Gold.SetIfGreater(0.67 * Math.Min(1, WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(67 * Math.Min(1, WorkingTime.TotalHours / 3))); } else { trading.PreGoldOrderPending += args => { if (WorkingTime < TimeSpan.FromHours(3)) { - args.Priority4Gold.SetIfGreater(3 * Math.Min(1, WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(300 * Math.Min(1, WorkingTime.TotalHours / 3))); } else { - args.Priority4Gold.SetIfGreater(1.5 + 2.5 * Math.Min(1, WorkingTime / TimeSpan.FromHours(5))); + args.Priority4Gold.SetIfGreater((int)(150 + 250 * Math.Min(1, WorkingTime.TotalHours / 5))); } }; } diff --git a/InfrastSim/TimeDriven/Operators/Bryophyta.cs b/InfrastSim/TimeDriven/Operators/Bryophyta.cs index 556fb2d..d2e47fa 100644 --- a/InfrastSim/TimeDriven/Operators/Bryophyta.cs +++ b/InfrastSim/TimeDriven/Operators/Bryophyta.cs @@ -10,10 +10,10 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing) { if (manufacturing.IsProduceGold()) { - EfficiencyModifier.SetValue(Name, 0.30); + EfficiencyModifier.SetValue(Name, 30); } if (Upgraded >= 2) { - EfficiencyModifier.AddValue(Name, 0.05 * manufacturing.GroupMemberCount("金属工艺")); + EfficiencyModifier.AddValue(Name, 5 * manufacturing.GroupMemberCount("金属工艺")); } } } diff --git a/InfrastSim/TimeDriven/Operators/Bubble.cs b/InfrastSim/TimeDriven/Operators/Bubble.cs index 56f6beb..3d220d8 100644 --- a/InfrastSim/TimeDriven/Operators/Bubble.cs +++ b/InfrastSim/TimeDriven/Operators/Bubble.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); manufacturing.Capacity.SetValue(Name, 10); if (Upgraded >= 1) { @@ -15,8 +15,8 @@ public override void Resolve(Simulator simu) { var op = simu.GetOperatorNoThrow(kvp.Key); if (op != null) { var factor = kvp.Value switch { - >= 17 => 0.03, - > 0 => 0.01, + >= 17 => 3, + > 0 => 1, _ => 0 }; op.EfficiencyModifier.SetValue(Name, kvp.Value * factor); diff --git a/InfrastSim/TimeDriven/Operators/Castle_3.cs b/InfrastSim/TimeDriven/Operators/Castle_3.cs index 5fd5767..ce0e018 100644 --- a/InfrastSim/TimeDriven/Operators/Castle_3.cs +++ b/InfrastSim/TimeDriven/Operators/Castle_3.cs @@ -9,11 +9,11 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Catapult.cs b/InfrastSim/TimeDriven/Operators/Catapult.cs index 49d1660..73c6bc1 100644 --- a/InfrastSim/TimeDriven/Operators/Catapult.cs +++ b/InfrastSim/TimeDriven/Operators/Catapult.cs @@ -6,8 +6,8 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.3); - MoodConsumeRate.SetValue(Name, -0.25); + EfficiencyModifier.SetValue(Name, 30); + MoodConsumeRate.SetValue(Name, -25); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/Cement.cs b/InfrastSim/TimeDriven/Operators/Cement.cs index b358b31..0285ea6 100644 --- a/InfrastSim/TimeDriven/Operators/Cement.cs +++ b/InfrastSim/TimeDriven/Operators/Cement.cs @@ -9,10 +9,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); if (Upgraded >= 2) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); manufacturing.Capacity.SetValue(Name, 10); } } diff --git a/InfrastSim/TimeDriven/Operators/Chestnut.cs b/InfrastSim/TimeDriven/Operators/Chestnut.cs index 360891c..13aba56 100644 --- a/InfrastSim/TimeDriven/Operators/Chestnut.cs +++ b/InfrastSim/TimeDriven/Operators/Chestnut.cs @@ -8,9 +8,9 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); if (Upgraded >= 1 && manufacturing.IsProduceOriginStone()) { - EfficiencyModifier.AddValue(Name, 0.3); + EfficiencyModifier.AddValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Chongyue.cs b/InfrastSim/TimeDriven/Operators/Chongyue.cs index 3b74cac..e5736aa 100644 --- a/InfrastSim/TimeDriven/Operators/Chongyue.cs +++ b/InfrastSim/TimeDriven/Operators/Chongyue.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility?.Type == FacilityType.ControlCenter && !IsTired) { - MoodConsumeRate.SetValue(Name, 0.5); + MoodConsumeRate.SetValue(Name, 50); var count = simu.GroupMemberCount("岁"); simu.Renjianyanhuo.SetValue(Name, Math.Min(count, 5) * 5); @@ -17,7 +17,7 @@ public override void Resolve(Simulator simu) { var ops = simu.OperatorsInFacility.Where(op => op.Facility is not Dormitory && op.Facility is not ControlCenter); - var amount = Math.Floor(simu.Renjianyanhuo / 20) * 0.05 + 0.05; + var amount = simu.Renjianyanhuo / 20 * 5 + 5; foreach (var op in ops) { op.MoodConsumeRate.SetIfLesser("control-center-extra", amount); diff --git a/InfrastSim/TimeDriven/Operators/Cliffheart.cs b/InfrastSim/TimeDriven/Operators/Cliffheart.cs index 3124e11..8ec2c93 100644 --- a/InfrastSim/TimeDriven/Operators/Cliffheart.cs +++ b/InfrastSim/TimeDriven/Operators/Cliffheart.cs @@ -9,11 +9,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.25); - MoodConsumeRate.SetValue(Name, -0.5); + dorm.SetVipMoodModifier(-25); + MoodConsumeRate.SetValue(Name, -50); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); trading.Capacity.SetValue(Name, Upgraded >= 2 ? 4 : 2); } } diff --git a/InfrastSim/TimeDriven/Operators/Coldshot.cs b/InfrastSim/TimeDriven/Operators/Coldshot.cs index ed57b08..9e9085c 100644 --- a/InfrastSim/TimeDriven/Operators/Coldshot.cs +++ b/InfrastSim/TimeDriven/Operators/Coldshot.cs @@ -6,15 +6,15 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter center && !IsTired) { - center.ExtraMoodModifier.SetValue(Name, -0.05); + center.ExtraMoodModifier.SetValue(Name, -5); } if (Facility is Dormitory dorm && Upgraded >= 2) { // FIXME: 冰酿自己是否为反嘲讽? var count = dorm.Operators.Where(op => !op.IsFullOfEnergy).Count(); if (count == 1) { - dorm.SetVipMoodModifier(-0.8); + dorm.SetVipMoodModifier(-80); } else if (count > 1) { - var amount = -0.8 / count; + var amount = -80 / count; dorm.SetDormMoodModifier(amount); } } diff --git a/InfrastSim/TimeDriven/Operators/Conviction.cs b/InfrastSim/TimeDriven/Operators/Conviction.cs index f0bd8e4..171c3c3 100644 --- a/InfrastSim/TimeDriven/Operators/Conviction.cs +++ b/InfrastSim/TimeDriven/Operators/Conviction.cs @@ -7,11 +7,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.7); + dorm.SetVipMoodModifier(-70); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, 0.35); + EfficiencyModifier.SetValue(Name, 35); } } } diff --git a/InfrastSim/TimeDriven/Operators/Czerny.cs b/InfrastSim/TimeDriven/Operators/Czerny.cs index 574ff6e..1c75039 100644 --- a/InfrastSim/TimeDriven/Operators/Czerny.cs +++ b/InfrastSim/TimeDriven/Operators/Czerny.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.65); + dorm.SetVipMoodModifier(-65); simu.Xiaojie.AddValue(Name, dorm.Level); if (Upgraded >= 2) { simu.Ganzhixinxi.AddValue(Name, simu.Xiaojie); diff --git a/InfrastSim/TimeDriven/Operators/Degenbrecher.cs b/InfrastSim/TimeDriven/Operators/Degenbrecher.cs index ac4883f..f2a3e73 100644 --- a/InfrastSim/TimeDriven/Operators/Degenbrecher.cs +++ b/InfrastSim/TimeDriven/Operators/Degenbrecher.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.2); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 20); trading.Capacity.SetValue(Name, Upgraded >= 2 ? -6 : -2); if (Upgraded >= 2) { @@ -18,7 +18,7 @@ public override void Resolve(Simulator simu) { .EnumerateValues() .Where(kvp => kvp.Key != "base") .Sum(kvp => kvp.Value); - EfficiencyModifier.AddValue(Name, Math.Clamp((int)cap / 5 * 0.25, 0.0, 1.0)); + EfficiencyModifier.AddValue(Name, Math.Clamp(cap / 5 * 25, 0, 100)); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Delphine.cs b/InfrastSim/TimeDriven/Operators/Delphine.cs index 645b947..8174e30 100644 --- a/InfrastSim/TimeDriven/Operators/Delphine.cs +++ b/InfrastSim/TimeDriven/Operators/Delphine.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { if (Facility?.Type == FacilityType.ControlCenter && !IsTired && Upgraded >= 2) { var ops = simu.OperatorsInFacility.Where(op => op.Facility is TradingStation && op.Groups.Contains("格拉斯哥帮")); foreach (var op in ops) { - op.EfficiencyModifier.SetValue(Name, 0.1); + op.EfficiencyModifier.SetValue(Name, 10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Dorothy.cs b/InfrastSim/TimeDriven/Operators/Dorothy.cs index a6cfdc3..2fa3221 100644 --- a/InfrastSim/TimeDriven/Operators/Dorothy.cs +++ b/InfrastSim/TimeDriven/Operators/Dorothy.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { var count = manufacturing.GroupMemberCount("莱茵科技制造"); - EfficiencyModifier.SetValue(Name, 0.05 * count + (Upgraded >= 2 ? 0.25 : 0)); + EfficiencyModifier.SetValue(Name, 5 * count + (Upgraded >= 2 ? 25 : 0)); } } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Durin.cs b/InfrastSim/TimeDriven/Operators/Durin.cs index 72b035a..d3f798e 100644 --- a/InfrastSim/TimeDriven/Operators/Durin.cs +++ b/InfrastSim/TimeDriven/Operators/Durin.cs @@ -9,8 +9,8 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - MoodConsumeRate.AddValue(Name, 0.1); - dorm.SetDormMoodModifier(-0.25); + MoodConsumeRate.AddValue(Name, 10); + dorm.SetDormMoodModifier(-25); } } } diff --git a/InfrastSim/TimeDriven/Operators/Dusk.cs b/InfrastSim/TimeDriven/Operators/Dusk.cs index 7c47404..8437ebd 100644 --- a/InfrastSim/TimeDriven/Operators/Dusk.cs +++ b/InfrastSim/TimeDriven/Operators/Dusk.cs @@ -10,10 +10,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter center && !IsTired) { - center.ExtraMoodModifier.SetValue(Name, -0.05); - MoodConsumeRate.SetValue(Name, 0.5); + center.ExtraMoodModifier.SetValue(Name, -5); + MoodConsumeRate.SetValue(Name, 50); - if (MoodTicks >= 12 * 360000) { + if (MoodTicks >= MaxTicks / 2) { simu.Ganzhixinxi.SetValue(Name, 10); } else { simu.Renjianyanhuo.SetValue(Name, 15); diff --git a/InfrastSim/TimeDriven/Operators/Earthspirit.cs b/InfrastSim/TimeDriven/Operators/Earthspirit.cs index e81855b..3e895dc 100644 --- a/InfrastSim/TimeDriven/Operators/Earthspirit.cs +++ b/InfrastSim/TimeDriven/Operators/Earthspirit.cs @@ -6,14 +6,14 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 1 ? 0.45 : 0.3); + EfficiencyModifier.SetValue(Name, Upgraded >= 1 ? 45 : 30); if (Upgraded >= 1) { - MoodConsumeRate.SetValue(Name, 2); + MoodConsumeRate.SetValue(Name, 200); } } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceOriginStone()) { - EfficiencyModifier.SetValue(Name, 0.35); + EfficiencyModifier.SetValue(Name, 35); } } } diff --git a/InfrastSim/TimeDriven/Operators/Ebenholz.cs b/InfrastSim/TimeDriven/Operators/Ebenholz.cs index b874b99..ce2c046 100644 --- a/InfrastSim/TimeDriven/Operators/Ebenholz.cs +++ b/InfrastSim/TimeDriven/Operators/Ebenholz.cs @@ -14,7 +14,7 @@ public override void Resolve(Simulator simu) { }, Priority.PropConversion); simu.Delay(simu => { - EfficiencyModifier.SetValue(Name, (int)simu.Wushenggongming / (Upgraded >= 2 ? 2 : 4) * 0.01); + EfficiencyModifier.SetValue(Name, simu.Wushenggongming / (Upgraded >= 2 ? 2 : 4)); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Eunectes.cs b/InfrastSim/TimeDriven/Operators/Eunectes.cs index b298afc..207ab82 100644 --- a/InfrastSim/TimeDriven/Operators/Eunectes.cs +++ b/InfrastSim/TimeDriven/Operators/Eunectes.cs @@ -19,7 +19,7 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MaxValue = 0; } } - EfficiencyModifier.SetValue(Name, (Upgraded >= 2 ? 0.1 : 0.05) * simu.PowerStationsCount()); + EfficiencyModifier.SetValue(Name, (Upgraded >= 2 ? 10 : 5) * simu.PowerStationsCount()); }, Priority.AccordingToFacilityAmount); } } diff --git a/InfrastSim/TimeDriven/Operators/ExecutorTheExFoedere.cs b/InfrastSim/TimeDriven/Operators/ExecutorTheExFoedere.cs index 14a8597..c9687a0 100644 --- a/InfrastSim/TimeDriven/Operators/ExecutorTheExFoedere.cs +++ b/InfrastSim/TimeDriven/Operators/ExecutorTheExFoedere.cs @@ -7,7 +7,7 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.3 : 0.2); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 30 : 20); if (Upgraded >= 2) { manufacturing.Capacity.SetValue(Name, 4); } diff --git a/InfrastSim/TimeDriven/Operators/FEater.cs b/InfrastSim/TimeDriven/Operators/FEater.cs index b434b42..3ff2a9b 100644 --- a/InfrastSim/TimeDriven/Operators/FEater.cs +++ b/InfrastSim/TimeDriven/Operators/FEater.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.35 : 0.3); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 35 : 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Fang.cs b/InfrastSim/TimeDriven/Operators/Fang.cs index 3a550e8..4137f5f 100644 --- a/InfrastSim/TimeDriven/Operators/Fang.cs +++ b/InfrastSim/TimeDriven/Operators/Fang.cs @@ -15,11 +15,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - var time = Math.Min(5, Math.Floor(WorkingTime / TimeSpan.FromHours(1))); - EfficiencyModifier.SetValue(Name, 0.2 + time * 0.01); + var time = Math.Min(5, (int)WorkingTime.TotalHours); + EfficiencyModifier.SetValue(Name, 20 + time); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 1) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Fartooth.cs b/InfrastSim/TimeDriven/Operators/Fartooth.cs index a2c9396..8d59c01 100644 --- a/InfrastSim/TimeDriven/Operators/Fartooth.cs +++ b/InfrastSim/TimeDriven/Operators/Fartooth.cs @@ -9,11 +9,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - MoodConsumeRate.SetValue(Name, -0.55); - dorm.SetDormMoodModifier(-0.1); + MoodConsumeRate.SetValue(Name, -55); + dorm.SetDormMoodModifier(-10); } if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 15); } } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Fiammetta.cs b/InfrastSim/TimeDriven/Operators/Fiammetta.cs index 4fc895c..e6fa417 100644 --- a/InfrastSim/TimeDriven/Operators/Fiammetta.cs +++ b/InfrastSim/TimeDriven/Operators/Fiammetta.cs @@ -25,8 +25,8 @@ public override void Resolve(Simulator simu) { MoodConsumeRate.MaxValue = -2; TryExchange(dorm); } else { - MoodConsumeRate.MinValue = double.MinValue; - MoodConsumeRate.MaxValue = double.MaxValue; + MoodConsumeRate.MinValue = int.MinValue; + MoodConsumeRate.MaxValue = int.MaxValue; } } } diff --git a/InfrastSim/TimeDriven/Operators/Flametail.cs b/InfrastSim/TimeDriven/Operators/Flametail.cs index e482bc4..f72707d 100644 --- a/InfrastSim/TimeDriven/Operators/Flametail.cs +++ b/InfrastSim/TimeDriven/Operators/Flametail.cs @@ -9,17 +9,17 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter control && !IsTired) { - control.ExtraMoodModifier.SetValue(Name, -0.05); + control.ExtraMoodModifier.SetValue(Name, -5); if (Upgraded >= 2) { foreach (var op in simu.ManufacturingStations.SelectMany(t => t.WorkingOperators)) { if (op.HasGroup("红松骑士团")) { var manufacturing = (ManufacturingStation)op.Facility!; if (manufacturing.IsProduceCombatRecord()) { - op.EfficiencyModifier.SetValue(Name, 0.1); + op.EfficiencyModifier.SetValue(Name, 10); } if (manufacturing.IsProduceGold()) { - op.EfficiencyModifier.SetValue(Name, -0.1); + op.EfficiencyModifier.SetValue(Name, -10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Forstleaf.cs b/InfrastSim/TimeDriven/Operators/Forstleaf.cs index b52f06c..2fc4a7d 100644 --- a/InfrastSim/TimeDriven/Operators/Forstleaf.cs +++ b/InfrastSim/TimeDriven/Operators/Forstleaf.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - MoodConsumeRate.SetValue(Name, -0.7); + MoodConsumeRate.SetValue(Name, -70); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Gnosis.cs b/InfrastSim/TimeDriven/Operators/Gnosis.cs index a25fed6..4630a88 100644 --- a/InfrastSim/TimeDriven/Operators/Gnosis.cs +++ b/InfrastSim/TimeDriven/Operators/Gnosis.cs @@ -10,12 +10,12 @@ public override void Resolve(Simulator simu) { if (Facility is ControlCenter control && !IsTired) { var amount = control.GroupMemberCount("喀兰贸易"); - control.ExtraMoodModifier.SetValue(Name, amount * -0.05); + control.ExtraMoodModifier.SetValue(Name, amount * -5); if (Upgraded >= 2) { foreach (var op in simu.TradingStations.SelectMany(t => t.WorkingOperators)) { if (op.HasGroup("喀兰贸易")) { - op.EfficiencyModifier.SetValue(Name, -0.15); + op.EfficiencyModifier.SetValue(Name, -15); ((TradingStation)op.Facility!).Capacity.AddValue(Name, 6); } } diff --git a/InfrastSim/TimeDriven/Operators/Goldenglow.cs b/InfrastSim/TimeDriven/Operators/Goldenglow.cs index 9fc6b49..0a33cd1 100644 --- a/InfrastSim/TimeDriven/Operators/Goldenglow.cs +++ b/InfrastSim/TimeDriven/Operators/Goldenglow.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.2 : 0.1); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 20 : 10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Gravel.cs b/InfrastSim/TimeDriven/Operators/Gravel.cs index 71197f5..8ace6a5 100644 --- a/InfrastSim/TimeDriven/Operators/Gravel.cs +++ b/InfrastSim/TimeDriven/Operators/Gravel.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceGold()) { - EfficiencyModifier.SetValue(Name, 0.35); + EfficiencyModifier.SetValue(Name, 35); } } } diff --git a/InfrastSim/TimeDriven/Operators/Greyy.cs b/InfrastSim/TimeDriven/Operators/Greyy.cs index db2fbc0..46dc9d7 100644 --- a/InfrastSim/TimeDriven/Operators/Greyy.cs +++ b/InfrastSim/TimeDriven/Operators/Greyy.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/GreyyTheLightningbearer.cs b/InfrastSim/TimeDriven/Operators/GreyyTheLightningbearer.cs index 1bbd1d9..e1bb08e 100644 --- a/InfrastSim/TimeDriven/Operators/GreyyTheLightningbearer.cs +++ b/InfrastSim/TimeDriven/Operators/GreyyTheLightningbearer.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation power && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); // FIXME: 无人机上限 + EfficiencyModifier.SetValue(Name, 20); // FIXME: 无人机上限 if (!simu.PowerStations.Any( fac => fac.HasGroupMember("作业平台") && fac.WorkingOperatorsCount > 0)) { simu.ExtraPowerStation.SetValue(Name, 1); diff --git a/InfrastSim/TimeDriven/Operators/Haze.cs b/InfrastSim/TimeDriven/Operators/Haze.cs index 66d7032..f7848ac 100644 --- a/InfrastSim/TimeDriven/Operators/Haze.cs +++ b/InfrastSim/TimeDriven/Operators/Haze.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && manufacturing.IsProduceGold() && !IsTired) { - EfficiencyModifier.SetValue(0.30); + EfficiencyModifier.SetValue(30); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 1) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Hibiscus.cs b/InfrastSim/TimeDriven/Operators/Hibiscus.cs index 2e807b2..5ed74bb 100644 --- a/InfrastSim/TimeDriven/Operators/Hibiscus.cs +++ b/InfrastSim/TimeDriven/Operators/Hibiscus.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.55); + dorm.SetVipMoodModifier(-55); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/Hoederer.cs b/InfrastSim/TimeDriven/Operators/Hoederer.cs index 0612ebc..87c7788 100644 --- a/InfrastSim/TimeDriven/Operators/Hoederer.cs +++ b/InfrastSim/TimeDriven/Operators/Hoederer.cs @@ -6,15 +6,15 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); if (simu.OperatorsInFacility.Any(op => op.Name == "伊内丝")) { - EfficiencyModifier.AddValue(Name, 0.05); + EfficiencyModifier.AddValue(Name, 5); } if (Upgraded >= 2) { - EfficiencyModifier.AddValue(Name, 0.05); + EfficiencyModifier.AddValue(Name, 5); if (simu.OperatorsInFacility.Any(op => op.Name == "W")) { - EfficiencyModifier.AddValue(Name, 0.05); + EfficiencyModifier.AddValue(Name, 5); } } } diff --git a/InfrastSim/TimeDriven/Operators/Honeyberry.cs b/InfrastSim/TimeDriven/Operators/Honeyberry.cs index 2a88a6a..7a81d59 100644 --- a/InfrastSim/TimeDriven/Operators/Honeyberry.cs +++ b/InfrastSim/TimeDriven/Operators/Honeyberry.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { // TODO: missing skill 1 if (Facility is Dormitory dorm && Upgraded >= 2) { - dorm.SetVipMoodModifier(-0.7); + dorm.SetVipMoodModifier(-70); } } } diff --git a/InfrastSim/TimeDriven/Operators/Iris.cs b/InfrastSim/TimeDriven/Operators/Iris.cs index 22b2369..58fedae 100644 --- a/InfrastSim/TimeDriven/Operators/Iris.cs +++ b/InfrastSim/TimeDriven/Operators/Iris.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetDormMoodModifier(-0.1); + dorm.SetDormMoodModifier(-10); simu.Mengjing.AddValue(Name, dorm.Level); if (Upgraded >= 2) { simu.Ganzhixinxi.AddValue(Name, simu.Mengjing); diff --git a/InfrastSim/TimeDriven/Operators/Jaye.cs b/InfrastSim/TimeDriven/Operators/Jaye.cs index dd769f5..8a01f03 100644 --- a/InfrastSim/TimeDriven/Operators/Jaye.cs +++ b/InfrastSim/TimeDriven/Operators/Jaye.cs @@ -10,14 +10,14 @@ public override void Resolve(Simulator simu) { if (Upgraded == 0) { simu.Delay(simu => { var diff = trading.Capacity - trading.OrderCount; - EfficiencyModifier.AddValue(Name, diff * 0.04); + EfficiencyModifier.AddValue(Name, diff * 4); }); } else { // FIXME: 孑的技能和不同干员的交互仍然需要重点关注 simu.Delay(simu => { var total = trading.Operators.Sum(op => op.EfficiencyModifier); - trading.Capacity.SetValue(Name, -Math.Floor((total + Util.Epsilon) / 0.1)); - EfficiencyModifier.SetValue(Name, trading.Capacity * 0.04); + trading.Capacity.SetValue(Name, -(total / 10)); + EfficiencyModifier.SetValue(Name, trading.Capacity * 4); }, Priority.Jaye); } } diff --git a/InfrastSim/TimeDriven/Operators/Jessica.cs b/InfrastSim/TimeDriven/Operators/Jessica.cs index 0e2528c..bab95e7 100644 --- a/InfrastSim/TimeDriven/Operators/Jessica.cs +++ b/InfrastSim/TimeDriven/Operators/Jessica.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/JessicaTheLiberated.cs b/InfrastSim/TimeDriven/Operators/JessicaTheLiberated.cs index 1a86252..a9b8897 100644 --- a/InfrastSim/TimeDriven/Operators/JessicaTheLiberated.cs +++ b/InfrastSim/TimeDriven/Operators/JessicaTheLiberated.cs @@ -8,15 +8,15 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); trading.Capacity.SetValue(Name, 4); } if (Facility?.Type == FacilityType.ControlCenter && !IsTired && Upgraded >= 2) { - MoodConsumeRate.SetValue(Name, 0.5); + MoodConsumeRate.SetValue(Name, 50); var ops = simu.ManufacturingStations.SelectMany(manufacturing => manufacturing.Operators); foreach (var op in ops.Where(op => op.HasGroup("黑钢国际"))) { - op.EfficiencyModifier.SetValue(Name, 0.05); + op.EfficiencyModifier.SetValue(Name, 5); } } } diff --git a/InfrastSim/TimeDriven/Operators/Jieyun.cs b/InfrastSim/TimeDriven/Operators/Jieyun.cs index 4732962..78ff57f 100644 --- a/InfrastSim/TimeDriven/Operators/Jieyun.cs +++ b/InfrastSim/TimeDriven/Operators/Jieyun.cs @@ -8,10 +8,10 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { simu.Delay(simu => { - simu.Wushujiejing.SetValue(Name, (int)simu.Renjianyanhuo / 5); + simu.Wushujiejing.SetValue(Name, simu.Renjianyanhuo / 5); }, Priority.PropConversion); simu.Delay(simu => { - EfficiencyModifier.SetValue(Name, simu.Wushujiejing * (Upgraded >= 2 ? 0.02 : 0.01)); + EfficiencyModifier.SetValue(Name, simu.Wushujiejing * (Upgraded >= 2 ? 2 : 1)); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Kaltsit.cs b/InfrastSim/TimeDriven/Operators/Kaltsit.cs index 7d66b3e..d41bd62 100644 --- a/InfrastSim/TimeDriven/Operators/Kaltsit.cs +++ b/InfrastSim/TimeDriven/Operators/Kaltsit.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { // TODO: missing skill 1 if (Facility?.Type == FacilityType.ControlCenter && !IsTired && Upgraded >= 2) { - simu.GlobalManufacturingEfficiency.SetIfGreater(0.02); + simu.GlobalManufacturingEfficiency.SetIfGreater(2); } } } diff --git a/InfrastSim/TimeDriven/Operators/Kirara.cs b/InfrastSim/TimeDriven/Operators/Kirara.cs index 50871d9..35f48ac 100644 --- a/InfrastSim/TimeDriven/Operators/Kirara.cs +++ b/InfrastSim/TimeDriven/Operators/Kirara.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.05); + EfficiencyModifier.SetValue(Name, 5); simu.ExtraGoldProductionLine.SetValue( Name, simu.GetRealGoldProductionLine() / (Upgraded >= 2 ? 2 : 4) * 2); diff --git a/InfrastSim/TimeDriven/Operators/KirinRYato.cs b/InfrastSim/TimeDriven/Operators/KirinRYato.cs index 49b1b82..6b8fc5d 100644 --- a/InfrastSim/TimeDriven/Operators/KirinRYato.cs +++ b/InfrastSim/TimeDriven/Operators/KirinRYato.cs @@ -8,12 +8,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility?.Type == FacilityType.ControlCenter && !IsTired) { - MoodConsumeRate.SetValue(Name, 0.5); + MoodConsumeRate.SetValue(Name, 50); simu.SilverVine.SetValue(Name, 8); if (Upgraded >= 2) { if (Facility.GroupMemberCount("怪物猎人小队") >= 2) { - simu.GlobalManufacturingEfficiency.SetIfGreater(0.02); + simu.GlobalManufacturingEfficiency.SetIfGreater(2); } } } diff --git a/InfrastSim/TimeDriven/Operators/Kroos.cs b/InfrastSim/TimeDriven/Operators/Kroos.cs index 3c7c634..f529bda 100644 --- a/InfrastSim/TimeDriven/Operators/Kroos.cs +++ b/InfrastSim/TimeDriven/Operators/Kroos.cs @@ -15,11 +15,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - var time = Math.Min(5, Math.Floor(WorkingTime / TimeSpan.FromHours(1))); - EfficiencyModifier.SetValue(Name, 0.15 + time * 0.02); + EfficiencyModifier.SetValue(Name, 15 + WorkingTime.HoursNotExceed(5) * 2); } if (Facility is Dormitory dorm && Upgraded >= 1) { - MoodConsumeRate.AddValue(Name, -0.7); + MoodConsumeRate.AddValue(Name, -70); } } } diff --git a/InfrastSim/TimeDriven/Operators/Lancet_2.cs b/InfrastSim/TimeDriven/Operators/Lancet_2.cs index ba2da79..9702336 100644 --- a/InfrastSim/TimeDriven/Operators/Lancet_2.cs +++ b/InfrastSim/TimeDriven/Operators/Lancet_2.cs @@ -9,10 +9,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.65); + dorm.SetVipMoodModifier(-65); } if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Lava.cs b/InfrastSim/TimeDriven/Operators/Lava.cs index 1ea86bf..7b01c65 100644 --- a/InfrastSim/TimeDriven/Operators/Lava.cs +++ b/InfrastSim/TimeDriven/Operators/Lava.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceOriginStone()) { - EfficiencyModifier.SetValue(Name, 0.35); + EfficiencyModifier.SetValue(Name, 35); } } } diff --git a/InfrastSim/TimeDriven/Operators/Liskarm.cs b/InfrastSim/TimeDriven/Operators/Liskarm.cs index cedddca..4927bd5 100644 --- a/InfrastSim/TimeDriven/Operators/Liskarm.cs +++ b/InfrastSim/TimeDriven/Operators/Liskarm.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation power && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.2 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 20 : 15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Lumen.cs b/InfrastSim/TimeDriven/Operators/Lumen.cs index 5d0a0fb..3d3032c 100644 --- a/InfrastSim/TimeDriven/Operators/Lumen.cs +++ b/InfrastSim/TimeDriven/Operators/Lumen.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { if (Facility is Dormitory dorm) { simu.Delay(simu => { foreach (var op in dorm.Operators) { - var amount = simu.PowerStationsCount() * -0.05 + (Upgraded >= 2 ? -0.15 : -0.1); + var amount = simu.PowerStationsCount() * -5 + (Upgraded >= 2 ? -15 : -10); op.MoodConsumeRate.SetIfLesser("dorm-extra", amount); } }); diff --git a/InfrastSim/TimeDriven/Operators/Matterhorn.cs b/InfrastSim/TimeDriven/Operators/Matterhorn.cs index 4c76969..43e24c1 100644 --- a/InfrastSim/TimeDriven/Operators/Matterhorn.cs +++ b/InfrastSim/TimeDriven/Operators/Matterhorn.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); trading.Capacity.SetValue(Name, 2); } diff --git a/InfrastSim/TimeDriven/Operators/Mayer.cs b/InfrastSim/TimeDriven/Operators/Mayer.cs index e252a94..2d3dd4e 100644 --- a/InfrastSim/TimeDriven/Operators/Mayer.cs +++ b/InfrastSim/TimeDriven/Operators/Mayer.cs @@ -11,7 +11,7 @@ public override void Resolve(Simulator simu) { // TODO: missing skill 1 if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 2) { - EfficiencyModifier.SetValue(0.3); + EfficiencyModifier.SetValue(30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Melantha.cs b/InfrastSim/TimeDriven/Operators/Melantha.cs index 84efb0c..b492535 100644 --- a/InfrastSim/TimeDriven/Operators/Melantha.cs +++ b/InfrastSim/TimeDriven/Operators/Melantha.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); trading.Capacity.SetValue(Name, 1); } diff --git a/InfrastSim/TimeDriven/Operators/Midnight.cs b/InfrastSim/TimeDriven/Operators/Midnight.cs index 3b9d003..efde7ca 100644 --- a/InfrastSim/TimeDriven/Operators/Midnight.cs +++ b/InfrastSim/TimeDriven/Operators/Midnight.cs @@ -6,12 +6,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.3); - MoodConsumeRate.SetValue(Name, -0.25); + EfficiencyModifier.SetValue(Name, 30); + MoodConsumeRate.SetValue(Name, -25); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceOriginStone()) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Minimalist.cs b/InfrastSim/TimeDriven/Operators/Minimalist.cs index 809143f..5995b50 100644 --- a/InfrastSim/TimeDriven/Operators/Minimalist.cs +++ b/InfrastSim/TimeDriven/Operators/Minimalist.cs @@ -12,7 +12,7 @@ public override void Resolve(Simulator simu) { var amount = simu.Facilities.Sum(fac => fac?.Level ?? 0); simu.Gongchengjiqiren.SetValue(Name, Math.Min(64, amount)); - EfficiencyModifier.SetValue(Name, (int)simu.Gongchengjiqiren / (Upgraded >= 2 ? 8 : 16) * 0.05); + EfficiencyModifier.SetValue(Name, simu.Gongchengjiqiren / (Upgraded >= 2 ? 8 : 16) * 5); } } } diff --git a/InfrastSim/TimeDriven/Operators/Mizuki.cs b/InfrastSim/TimeDriven/Operators/Mizuki.cs index 4934cc3..e507c44 100644 --- a/InfrastSim/TimeDriven/Operators/Mizuki.cs +++ b/InfrastSim/TimeDriven/Operators/Mizuki.cs @@ -10,10 +10,10 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { var count = manufacturing.GroupMemberCount("标准化"); - EfficiencyModifier.SetValue(Name, count * 0.05); + EfficiencyModifier.SetValue(Name, count * 5); if (Upgraded >= 2) { - EfficiencyModifier.AddValue(Name, 0.25); + EfficiencyModifier.AddValue(Name, 25); } } } diff --git a/InfrastSim/TimeDriven/Operators/Morgan.cs b/InfrastSim/TimeDriven/Operators/Morgan.cs index 4b98427..71ddf8d 100644 --- a/InfrastSim/TimeDriven/Operators/Morgan.cs +++ b/InfrastSim/TimeDriven/Operators/Morgan.cs @@ -10,17 +10,17 @@ public override void Resolve(Simulator simu) { if (Facility is Dormitory dorm) { var siege = dorm.FindOp("推进之王"); if (siege != null) { - var amount = siege.Upgraded >= 2 ? -0.2 : -0.15; + var amount = siege.Upgraded >= 2 ? -20 : -15; simu.Delay(simu => { foreach (var op in dorm.GroupMembers("格拉斯哥帮")) { - op.MoodConsumeRate.SetIfLesser("dorm-extra", amount + -0.3); // FIXME? 和冰酿的交互 + op.MoodConsumeRate.SetIfLesser("dorm-extra", amount + -30); // FIXME? 和冰酿的交互 } }); } } if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { - var amount = trading.GroupMemberCount("格拉斯哥帮") * 0.2 - + (trading.FindOp("推进之王") != null ? 0.35 : 0); + var amount = trading.GroupMemberCount("格拉斯哥帮") * 20 + + (trading.FindOp("推进之王") != null ? 35 : 0); EfficiencyModifier.SetValue(Name, amount); } } diff --git a/InfrastSim/TimeDriven/Operators/Mousse.cs b/InfrastSim/TimeDriven/Operators/Mousse.cs index 3943a73..8a7702a 100644 --- a/InfrastSim/TimeDriven/Operators/Mousse.cs +++ b/InfrastSim/TimeDriven/Operators/Mousse.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } if (Facility is Dormitory dorm && Upgraded >= 1) { - dorm.SetVipMoodModifier(-0.3); - MoodConsumeRate.SetValue(Name, -0.3); + dorm.SetVipMoodModifier(-30); + MoodConsumeRate.SetValue(Name, -30); } } } diff --git a/InfrastSim/TimeDriven/Operators/MrNothing.cs b/InfrastSim/TimeDriven/Operators/MrNothing.cs index 2fffba2..770feaf 100644 --- a/InfrastSim/TimeDriven/Operators/MrNothing.cs +++ b/InfrastSim/TimeDriven/Operators/MrNothing.cs @@ -7,10 +7,10 @@ public override void Resolve(Simulator simu) { if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { simu.Delay(simu => { - EfficiencyModifier.SetValue(Name, simu.Renjianyanhuo * 0.01); + EfficiencyModifier.SetValue(Name, simu.Renjianyanhuo); }); simu.Renjianyanhuo.SetValue(Name, - simu.Dormitories.Sum(dorm => dorm == null ? 0 :dorm.Operators.Count())); + simu.Dormitories.Sum(dorm => dorm == null ? 0 : dorm.Operators.Count())); } } } diff --git a/InfrastSim/TimeDriven/Operators/Muelsyse.cs b/InfrastSim/TimeDriven/Operators/Muelsyse.cs index 63fdbc9..f483ab3 100644 --- a/InfrastSim/TimeDriven/Operators/Muelsyse.cs +++ b/InfrastSim/TimeDriven/Operators/Muelsyse.cs @@ -8,12 +8,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - MoodConsumeRate.SetValue(Name, -0.55); - dorm.SetDormMoodModifier(-0.1); + MoodConsumeRate.SetValue(Name, -55); + dorm.SetDormMoodModifier(-10); } if (Facility is PowerStation && !IsTired) { var amount = simu.GroupMemberCount("莱茵生命") - 1; - EfficiencyModifier.SetValue(Name, 0.1 + Math.Min(0.15, 0.03 * amount)); + EfficiencyModifier.SetValue(Name, 10 + Math.Min(15, 3 * amount)); } } } diff --git a/InfrastSim/TimeDriven/Operators/Mulberry.cs b/InfrastSim/TimeDriven/Operators/Mulberry.cs index f72c99a..0db41e8 100644 --- a/InfrastSim/TimeDriven/Operators/Mulberry.cs +++ b/InfrastSim/TimeDriven/Operators/Mulberry.cs @@ -7,8 +7,8 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); - EfficiencyModifier.SetValue(Name, Upgraded >= 1 ? 0.2 : 0.1); + MoodConsumeRate.SetValue(Name, -25); + EfficiencyModifier.SetValue(Name, Upgraded >= 1 ? 20 : 10); if (Upgraded >= 2) { simu.Renjianyanhuo.SetValue(Name, 20); // FIXME: hardcoded } diff --git a/InfrastSim/TimeDriven/Operators/Myrtle.cs b/InfrastSim/TimeDriven/Operators/Myrtle.cs index c8489d5..390d722 100644 --- a/InfrastSim/TimeDriven/Operators/Myrtle.cs +++ b/InfrastSim/TimeDriven/Operators/Myrtle.cs @@ -10,11 +10,11 @@ public override void Resolve(Simulator simu) { if (Facility is TradingStation trading && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); trading.Capacity.SetValue(Name, 5); } if (Facility is Dormitory dorm && Upgraded >= 1) { - dorm.SetDormMoodModifier(-0.15); + dorm.SetDormMoodModifier(-15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Nightingale.cs b/InfrastSim/TimeDriven/Operators/Nightingale.cs index bde9721..34f615e 100644 --- a/InfrastSim/TimeDriven/Operators/Nightingale.cs +++ b/InfrastSim/TimeDriven/Operators/Nightingale.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetDormMoodModifier(Upgraded >= 2 ? -0.2 : -0.1); + dorm.SetDormMoodModifier(Upgraded >= 2 ? -20 : -10); } } } diff --git a/InfrastSim/TimeDriven/Operators/NoirCorne.cs b/InfrastSim/TimeDriven/Operators/NoirCorne.cs index 0b18810..765c04a 100644 --- a/InfrastSim/TimeDriven/Operators/NoirCorne.cs +++ b/InfrastSim/TimeDriven/Operators/NoirCorne.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); manufacturing.Capacity.SetValue(Name, 10); } if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.1); + EfficiencyModifier.SetValue(Name, 10); trading.Capacity.SetValue(Name, 2); } } diff --git a/InfrastSim/TimeDriven/Operators/Orchid.cs b/InfrastSim/TimeDriven/Operators/Orchid.cs index ef25508..7796222 100644 --- a/InfrastSim/TimeDriven/Operators/Orchid.cs +++ b/InfrastSim/TimeDriven/Operators/Orchid.cs @@ -6,10 +6,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.4); + EfficiencyModifier.SetValue(Name, 40); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 1) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); trading.Capacity.SetValue(Name, 1); } } diff --git a/InfrastSim/TimeDriven/Operators/Pallas.cs b/InfrastSim/TimeDriven/Operators/Pallas.cs index 872b40c..26bd6d2 100644 --- a/InfrastSim/TimeDriven/Operators/Pallas.cs +++ b/InfrastSim/TimeDriven/Operators/Pallas.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); manufacturing.Capacity.SetValue(Name, 8); if (Upgraded >= 2 && manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); } } } diff --git a/InfrastSim/TimeDriven/Operators/Passenger.cs b/InfrastSim/TimeDriven/Operators/Passenger.cs index e36a69d..a020b9a 100644 --- a/InfrastSim/TimeDriven/Operators/Passenger.cs +++ b/InfrastSim/TimeDriven/Operators/Passenger.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { if (Facility is PowerStation && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.15 : 0.1); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 15 : 10); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 2) { @@ -19,7 +19,7 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MaxValue = 0; } } - EfficiencyModifier.SetValue(Name, 0.05 * simu.PowerStationsCount()); + EfficiencyModifier.SetValue(Name, 5 * simu.PowerStationsCount()); }, Priority.AccordingToFacilityAmount); } } diff --git a/InfrastSim/TimeDriven/Operators/Perfumer.cs b/InfrastSim/TimeDriven/Operators/Perfumer.cs index 5a53dd7..8dc2ca1 100644 --- a/InfrastSim/TimeDriven/Operators/Perfumer.cs +++ b/InfrastSim/TimeDriven/Operators/Perfumer.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { // TODO: missing skill 1 if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); } } } diff --git a/InfrastSim/TimeDriven/Operators/Podenco.cs b/InfrastSim/TimeDriven/Operators/Podenco.cs index 1af84d2..4e11ebe 100644 --- a/InfrastSim/TimeDriven/Operators/Podenco.cs +++ b/InfrastSim/TimeDriven/Operators/Podenco.cs @@ -7,10 +7,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(Upgraded >= 1 ? -0.65 : -0.55); + dorm.SetVipMoodModifier(Upgraded >= 1 ? -65 : -55); if (Upgraded >= 1) { - dorm.SetDormMoodModifier(-0.15); + dorm.SetDormMoodModifier(-15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Popukar.cs b/InfrastSim/TimeDriven/Operators/Popukar.cs index 97b279a..2c6aa6e 100644 --- a/InfrastSim/TimeDriven/Operators/Popukar.cs +++ b/InfrastSim/TimeDriven/Operators/Popukar.cs @@ -6,13 +6,13 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); manufacturing.Capacity.SetValue(Name, -12); - MoodConsumeRate.SetValue(Name, 0.25); + MoodConsumeRate.SetValue(Name, 25); } if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.4); - MoodConsumeRate.SetValue(Name, -0.2); + dorm.SetVipMoodModifier(-40); + MoodConsumeRate.SetValue(Name, -20); } } } diff --git a/InfrastSim/TimeDriven/Operators/Ptilopsis.cs b/InfrastSim/TimeDriven/Operators/Ptilopsis.cs index 8fda6e0..20d0bdc 100644 --- a/InfrastSim/TimeDriven/Operators/Ptilopsis.cs +++ b/InfrastSim/TimeDriven/Operators/Ptilopsis.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 15); } } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Purestream.cs b/InfrastSim/TimeDriven/Operators/Purestream.cs index 904dfe1..ce5b7d9 100644 --- a/InfrastSim/TimeDriven/Operators/Purestream.cs +++ b/InfrastSim/TimeDriven/Operators/Purestream.cs @@ -8,12 +8,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is PowerStation) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.Product == Product.Gold) { simu.Delay(simu => { - EfficiencyModifier.SetValue(Name, simu.TradingStations.Count() * 0.2); + EfficiencyModifier.SetValue(Name, simu.TradingStations.Count() * 20); }, Priority.AccordingToFacilityAmount); } } diff --git a/InfrastSim/TimeDriven/Operators/Rangers.cs b/InfrastSim/TimeDriven/Operators/Rangers.cs index 2882671..df66b88 100644 --- a/InfrastSim/TimeDriven/Operators/Rangers.cs +++ b/InfrastSim/TimeDriven/Operators/Rangers.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/RathalosSNoirCorne.cs b/InfrastSim/TimeDriven/Operators/RathalosSNoirCorne.cs index f6ed902..0903b92 100644 --- a/InfrastSim/TimeDriven/Operators/RathalosSNoirCorne.cs +++ b/InfrastSim/TimeDriven/Operators/RathalosSNoirCorne.cs @@ -12,7 +12,7 @@ public override void Resolve(Simulator simu) { simu.SilverVine.SetValue(Name, 2 * count); if (Upgraded >= 2 && Facility.GroupMemberCount("怪物猎人小队") >= 2) { - simu.GlobalTradingEfficiency.SetIfGreater(0.07); + simu.GlobalTradingEfficiency.SetIfGreater(7); } } } diff --git a/InfrastSim/TimeDriven/Operators/Rosmontis.cs b/InfrastSim/TimeDriven/Operators/Rosmontis.cs index b8b40da..e4c85ea 100644 --- a/InfrastSim/TimeDriven/Operators/Rosmontis.cs +++ b/InfrastSim/TimeDriven/Operators/Rosmontis.cs @@ -14,7 +14,7 @@ public override void Resolve(Simulator simu) { }, Priority.PropConversion); simu.Delay(simu => { - EfficiencyModifier.SetValue(Name, (int)simu.Siweilianhuan / (Upgraded >= 2 ? 1 : 2) * 0.01); + EfficiencyModifier.SetValue(Name, simu.Siweilianhuan / (Upgraded >= 2 ? 1 : 2)); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Saileach.cs b/InfrastSim/TimeDriven/Operators/Saileach.cs index 575b714..46a2d80 100644 --- a/InfrastSim/TimeDriven/Operators/Saileach.cs +++ b/InfrastSim/TimeDriven/Operators/Saileach.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(-0.7); + dorm.SetVipMoodModifier(-70); } } } diff --git a/InfrastSim/TimeDriven/Operators/Scene.cs b/InfrastSim/TimeDriven/Operators/Scene.cs index b7c7b15..b0f8cd5 100644 --- a/InfrastSim/TimeDriven/Operators/Scene.cs +++ b/InfrastSim/TimeDriven/Operators/Scene.cs @@ -17,8 +17,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - var time = Math.Min(5, Math.Floor(WorkingTime / TimeSpan.FromHours(1))); - EfficiencyModifier.SetValue(Name, 0.15 + time * 0.02); + EfficiencyModifier.SetValue(Name, 15 + WorkingTime.HoursNotExceed(5) * 2); if (Upgraded >= 2) { if (manufacturing.IsProduceCombatRecord()) { diff --git a/InfrastSim/TimeDriven/Operators/Shamare.cs b/InfrastSim/TimeDriven/Operators/Shamare.cs index fada339..5fbcb1c 100644 --- a/InfrastSim/TimeDriven/Operators/Shamare.cs +++ b/InfrastSim/TimeDriven/Operators/Shamare.cs @@ -7,9 +7,9 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); trading.PreGoldOrderPending += args => - args.Priority4Gold.SetIfGreater(0.67 * Math.Min(1, WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(67 * Math.Min(1, WorkingTime.TotalHours / 3))); if (Upgraded >= 2) { simu.Delay(simu => { @@ -18,9 +18,9 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MinValue = 0; op.EfficiencyModifier.MaxValue = 0; } - op.MoodConsumeRate.AddValue(Name, 0.25); + op.MoodConsumeRate.AddValue(Name, 25); } - EfficiencyModifier.SetValue(Name, (trading.Operators.Count() - 1) * 0.45); + EfficiencyModifier.SetValue(Name, (trading.Operators.Count() - 1) * 45); }, Priority.Shamare); } } diff --git a/InfrastSim/TimeDriven/Operators/Shining.cs b/InfrastSim/TimeDriven/Operators/Shining.cs index 31d8257..6be83c5 100644 --- a/InfrastSim/TimeDriven/Operators/Shining.cs +++ b/InfrastSim/TimeDriven/Operators/Shining.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetVipMoodModifier(Upgraded >= 2 ? -0.75 : -0.55); + dorm.SetVipMoodModifier(Upgraded >= 2 ? -75 : -55); } } } diff --git a/InfrastSim/TimeDriven/Operators/ShiraYuki.cs b/InfrastSim/TimeDriven/Operators/ShiraYuki.cs index 15353ba..2880191 100644 --- a/InfrastSim/TimeDriven/Operators/ShiraYuki.cs +++ b/InfrastSim/TimeDriven/Operators/ShiraYuki.cs @@ -6,11 +6,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Reception && !IsTired) { - EfficiencyModifier.SetValue(0.2); + EfficiencyModifier.SetValue(20); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceCombatRecord()) { - EfficiencyModifier.SetValue(0.3); + EfficiencyModifier.SetValue(30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Siege.cs b/InfrastSim/TimeDriven/Operators/Siege.cs index b9ec553..d7f5a9b 100644 --- a/InfrastSim/TimeDriven/Operators/Siege.cs +++ b/InfrastSim/TimeDriven/Operators/Siege.cs @@ -8,7 +8,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetDormMoodModifier(Upgraded >= 2 ? -0.2 : -0.15); + dorm.SetDormMoodModifier(Upgraded >= 2 ? -20 : -15); } } } diff --git a/InfrastSim/TimeDriven/Operators/Silence.cs b/InfrastSim/TimeDriven/Operators/Silence.cs index 64fdc19..3c12fa2 100644 --- a/InfrastSim/TimeDriven/Operators/Silence.cs +++ b/InfrastSim/TimeDriven/Operators/Silence.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 15); } } } diff --git a/InfrastSim/TimeDriven/Operators/SilenceTheParadigmatic.cs b/InfrastSim/TimeDriven/Operators/SilenceTheParadigmatic.cs index ac7f921..5949049 100644 --- a/InfrastSim/TimeDriven/Operators/SilenceTheParadigmatic.cs +++ b/InfrastSim/TimeDriven/Operators/SilenceTheParadigmatic.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 2) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/SilverAsh.cs b/InfrastSim/TimeDriven/Operators/SilverAsh.cs index c5637be..2655b4c 100644 --- a/InfrastSim/TimeDriven/Operators/SilverAsh.cs +++ b/InfrastSim/TimeDriven/Operators/SilverAsh.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.2 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 20: 15); trading.Capacity.SetValue(Name, Upgraded >= 2 ? 4 : 2); } } diff --git a/InfrastSim/TimeDriven/Operators/Spot.cs b/InfrastSim/TimeDriven/Operators/Spot.cs index 11862cf..f5b0de5 100644 --- a/InfrastSim/TimeDriven/Operators/Spot.cs +++ b/InfrastSim/TimeDriven/Operators/Spot.cs @@ -12,7 +12,7 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { if (manufacturing.IsProduceGold()) { - EfficiencyModifier.SetValue(Name, 0.30); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git a/InfrastSim/TimeDriven/Operators/Steward.cs b/InfrastSim/TimeDriven/Operators/Steward.cs index ac664f1..6941bad 100644 --- a/InfrastSim/TimeDriven/Operators/Steward.cs +++ b/InfrastSim/TimeDriven/Operators/Steward.cs @@ -8,11 +8,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); trading.Capacity.SetValue(Name, 5); } if (Facility is ManufacturingStation manufacturing && !IsTired && Upgraded >= 1) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); } } } diff --git a/InfrastSim/TimeDriven/Operators/Swire.cs b/InfrastSim/TimeDriven/Operators/Swire.cs index 73e755d..ca7417b 100644 --- a/InfrastSim/TimeDriven/Operators/Swire.cs +++ b/InfrastSim/TimeDriven/Operators/Swire.cs @@ -7,7 +7,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility?.Type == FacilityType.ControlCenter && !IsTired) { - simu.GlobalTradingEfficiency.SetIfGreater(0.07); + simu.GlobalTradingEfficiency.SetIfGreater(7); } // TODO: missing skill 2 diff --git a/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs b/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs index 3c1971e..ce791a5 100644 --- a/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs +++ b/InfrastSim/TimeDriven/Operators/SwireTheElegantWit.cs @@ -9,12 +9,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); if (Upgraded >= 2) { simu.Delay(simu => { var diff = trading.Capacity - trading.BaseCapacity; - EfficiencyModifier.AddValue(Name, diff * 0.04); + EfficiencyModifier.AddValue(Name, diff * 4); }, Priority.Swire); } } diff --git a/InfrastSim/TimeDriven/Operators/Tequila.cs b/InfrastSim/TimeDriven/Operators/Tequila.cs index 33f0962..0a85280 100644 --- a/InfrastSim/TimeDriven/Operators/Tequila.cs +++ b/InfrastSim/TimeDriven/Operators/Tequila.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - MoodConsumeRate.AddValue(Name, -0.25); + MoodConsumeRate.AddValue(Name, -25); trading.OnPending += OnPending; } } diff --git a/InfrastSim/TimeDriven/Operators/TerraResearchCommission.cs b/InfrastSim/TimeDriven/Operators/TerraResearchCommission.cs index 4ab52d3..dbc2e17 100644 --- a/InfrastSim/TimeDriven/Operators/TerraResearchCommission.cs +++ b/InfrastSim/TimeDriven/Operators/TerraResearchCommission.cs @@ -9,11 +9,11 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { manufacturing.Capacity.SetValue(Name, 8); - EfficiencyModifier.SetValue(Name, 0.05 + simu.SilverVine * 0.01); + EfficiencyModifier.SetValue(Name, 5 + simu.SilverVine); } if (Facility is TradingStation trading && !IsTired) { trading.Capacity.SetValue(Name, 2); - EfficiencyModifier.SetValue(Name, 0.05 + simu.SilverVine * 0.03); + EfficiencyModifier.SetValue(Name, 5 + simu.SilverVine * 3); } } } diff --git a/InfrastSim/TimeDriven/Operators/Tuye.cs b/InfrastSim/TimeDriven/Operators/Tuye.cs index fc91115..fb07a6b 100644 --- a/InfrastSim/TimeDriven/Operators/Tuye.cs +++ b/InfrastSim/TimeDriven/Operators/Tuye.cs @@ -17,7 +17,7 @@ public override void Resolve(Simulator simu) { } EfficiencyModifier.SetValue( - Name, productLines / (Upgraded >= 2 ? 2 : 4) * 0.15 + 0.05); + Name, productLines / (Upgraded >= 2 ? 2 : 4) * 15 + 5); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Vanilla.cs b/InfrastSim/TimeDriven/Operators/Vanilla.cs index a957133..bea4000 100644 --- a/InfrastSim/TimeDriven/Operators/Vanilla.cs +++ b/InfrastSim/TimeDriven/Operators/Vanilla.cs @@ -8,11 +8,11 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.25); + EfficiencyModifier.SetValue(Name, 25); } if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); } } } diff --git a/InfrastSim/TimeDriven/Operators/Vendela.cs b/InfrastSim/TimeDriven/Operators/Vendela.cs index 88c0450..53ce625 100644 --- a/InfrastSim/TimeDriven/Operators/Vendela.cs +++ b/InfrastSim/TimeDriven/Operators/Vendela.cs @@ -6,12 +6,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Dormitory dorm) { - dorm.SetDormMoodModifier(-0.15); + dorm.SetDormMoodModifier(-15); if (Upgraded >= 2) { foreach (var op in Facility.Operators) { if (op.MoodTicks <= 18 * 360000) { - op.MoodConsumeRate.SetIfLesser("芬芳疗养beta", -0.1); + op.MoodConsumeRate.SetIfLesser("芬芳疗养beta", -10); } } } diff --git a/InfrastSim/TimeDriven/Operators/Vermeil.cs b/InfrastSim/TimeDriven/Operators/Vermeil.cs index 5be8eda..d111ca2 100644 --- a/InfrastSim/TimeDriven/Operators/Vermeil.cs +++ b/InfrastSim/TimeDriven/Operators/Vermeil.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - MoodConsumeRate.SetValue(Name, -0.25); + MoodConsumeRate.SetValue(Name, -25); manufacturing.Capacity.SetValue(Name, 8); if (Upgraded >= 1) { @@ -14,7 +14,7 @@ public override void Resolve(Simulator simu) { if (op != null && op.Upgraded >= 1) return; // 泡泡优先生效 simu.Delay(simu => { - var amount = 0.02 * (manufacturing.Capacity - manufacturing.BaseCapacity); + var amount = 2 * (manufacturing.Capacity - manufacturing.BaseCapacity); EfficiencyModifier.SetValue(Name, Math.Max(0, amount)); }); } diff --git a/InfrastSim/TimeDriven/Operators/Vigil.cs b/InfrastSim/TimeDriven/Operators/Vigil.cs index 6421c83..3fcec6b 100644 --- a/InfrastSim/TimeDriven/Operators/Vigil.cs +++ b/InfrastSim/TimeDriven/Operators/Vigil.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { // TODO: missing skill 1 if (Facility is TradingStation trading && !IsTired && Upgraded >= 2) { - EfficiencyModifier.SetValue(Name, 0.25 + simu.Reception.Level * 0.05); + EfficiencyModifier.SetValue(Name, 25 + simu.Reception.Level * 5); } } } diff --git a/InfrastSim/TimeDriven/Operators/Virtuosa.cs b/InfrastSim/TimeDriven/Operators/Virtuosa.cs index 6eeb8a1..020e320 100644 --- a/InfrastSim/TimeDriven/Operators/Virtuosa.cs +++ b/InfrastSim/TimeDriven/Operators/Virtuosa.cs @@ -10,7 +10,7 @@ public override void Resolve(Simulator simu) { if (Upgraded >= 2) { simu.Delay(simu => { - dorm.SetDormMoodModifier(-0.2 - (int)simu.Wushenggongming / 5 * 0.01); + dorm.SetDormMoodModifier(-20 + -simu.Wushenggongming / 5); }); } } diff --git a/InfrastSim/TimeDriven/Operators/Viviana.cs b/InfrastSim/TimeDriven/Operators/Viviana.cs index 3b7fa19..a67320b 100644 --- a/InfrastSim/TimeDriven/Operators/Viviana.cs +++ b/InfrastSim/TimeDriven/Operators/Viviana.cs @@ -7,13 +7,13 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ControlCenter control && !IsTired) { - control.ExtraMoodModifier.SetValue(Name, -0.05); + control.ExtraMoodModifier.SetValue(Name, -5); if (Upgraded >= 2) { var ops = simu.ManufacturingStations.SelectMany(fac => fac.WorkingOperators); foreach (var op in ops) { if (op.HasGroup("骑士")) { - op.EfficiencyModifier.AddValue(Name, 0.07); + op.EfficiencyModifier.AddValue(Name, 7); } } } diff --git a/InfrastSim/TimeDriven/Operators/Vulcan.cs b/InfrastSim/TimeDriven/Operators/Vulcan.cs index 2d769f0..282a20a 100644 --- a/InfrastSim/TimeDriven/Operators/Vulcan.cs +++ b/InfrastSim/TimeDriven/Operators/Vulcan.cs @@ -6,8 +6,8 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, -0.05); - MoodConsumeRate.SetValue(Name, Upgraded >= 2 ? -0.25 : -0.15); + EfficiencyModifier.SetValue(Name, -5); + MoodConsumeRate.SetValue(Name, Upgraded >= 2 ? -25 : -15); manufacturing.Capacity.SetValue(Name, Upgraded >= 2 ? 19 : 16); } } diff --git a/InfrastSim/TimeDriven/Operators/WaaiFu.cs b/InfrastSim/TimeDriven/Operators/WaaiFu.cs index a3b5dff..82105aa 100644 --- a/InfrastSim/TimeDriven/Operators/WaaiFu.cs +++ b/InfrastSim/TimeDriven/Operators/WaaiFu.cs @@ -9,19 +9,20 @@ public override void Resolve(Simulator simu) { if (Facility is ManufacturingStation manufacturing && !IsTired) { simu.Delay(simu => { var names = manufacturing.Operators.Select(op => op.Name); + var bonus_eff = 0; foreach (var op in manufacturing.Operators) { if (op == this) continue; - var eff = 0.0; + var eff = 0; foreach (var name in names) { op.MoodConsumeRate.Disable(name); eff += op.EfficiencyModifier.GetValue(name); } - if (Upgraded >= 2) { - EfficiencyModifier.AddValue(Name, Math.Max(0, Util.Align(eff, 0.05))); - } + bonus_eff += eff / 5 * 5; + } + if (Upgraded >= 2) { + EfficiencyModifier.SetValue(Name, Math.Min(40, bonus_eff)); } - EfficiencyModifier.SetIfLesser(Name, 0.4); }, Priority.WaaiFu); } } diff --git a/InfrastSim/TimeDriven/Operators/Weedy.cs b/InfrastSim/TimeDriven/Operators/Weedy.cs index 703f7e3..e8a3b4e 100644 --- a/InfrastSim/TimeDriven/Operators/Weedy.cs +++ b/InfrastSim/TimeDriven/Operators/Weedy.cs @@ -14,7 +14,7 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MaxValue = 0; } } - EfficiencyModifier.SetValue(Name, (Upgraded >= 2 ? 0.15 : 0.1) * simu.PowerStationsCount()); + EfficiencyModifier.SetValue(Name, (Upgraded >= 2 ? 15 : 10) * simu.PowerStationsCount()); }, Priority.AccordingToFacilityAmount); } } diff --git a/InfrastSim/TimeDriven/Operators/Whisperain.cs b/InfrastSim/TimeDriven/Operators/Whisperain.cs index c65c850..bb6c8f8 100644 --- a/InfrastSim/TimeDriven/Operators/Whisperain.cs +++ b/InfrastSim/TimeDriven/Operators/Whisperain.cs @@ -7,7 +7,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is Office office && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.2); + EfficiencyModifier.SetValue(Name, 20); simu.Jiyisuipian.SetValue(Name, 20); // FIXME: hardcoded if (Upgraded >= 2) { diff --git a/InfrastSim/TimeDriven/Operators/WildMane.cs b/InfrastSim/TimeDriven/Operators/WildMane.cs index eb8ae22..f7c8b08 100644 --- a/InfrastSim/TimeDriven/Operators/WildMane.cs +++ b/InfrastSim/TimeDriven/Operators/WildMane.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 0.25 : 0.15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 25 : 15); } } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Operators/Windflit.cs b/InfrastSim/TimeDriven/Operators/Windflit.cs index 1bf074d..1145f0d 100644 --- a/InfrastSim/TimeDriven/Operators/Windflit.cs +++ b/InfrastSim/TimeDriven/Operators/Windflit.cs @@ -16,7 +16,7 @@ public override void Resolve(Simulator simu) { op.EfficiencyModifier.MaxValue = 0; } } - EfficiencyModifier.SetValue(Name, 0.05 * simu.PowerStationsCount()); + EfficiencyModifier.SetValue(Name, 5 * simu.PowerStationsCount()); }, Priority.AccordingToFacilityAmount); } } diff --git a/InfrastSim/TimeDriven/Operators/Yato.cs b/InfrastSim/TimeDriven/Operators/Yato.cs index 4fda051..4cc49f6 100644 --- a/InfrastSim/TimeDriven/Operators/Yato.cs +++ b/InfrastSim/TimeDriven/Operators/Yato.cs @@ -6,10 +6,10 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } if (Facility is ManufacturingStation manufacturing && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.15); + EfficiencyModifier.SetValue(Name, 15); } } } diff --git "a/InfrastSim/TimeDriven/Operators/\320\223\321\203\320\274.cs" "b/InfrastSim/TimeDriven/Operators/\320\223\321\203\320\274.cs" index 0ea388d..92e7482 100644 --- "a/InfrastSim/TimeDriven/Operators/\320\223\321\203\320\274.cs" +++ "b/InfrastSim/TimeDriven/Operators/\320\223\321\203\320\274.cs" @@ -6,12 +6,12 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, 0.3); - MoodConsumeRate.SetValue(Name, -0.25); + EfficiencyModifier.SetValue(Name, 30); + MoodConsumeRate.SetValue(Name, -25); } if (Facility is Dormitory dorm && Upgraded >= 1) { - dorm.SetVipMoodModifier(-0.35); - MoodConsumeRate.SetValue(Name, -0.35); + dorm.SetVipMoodModifier(-35); + MoodConsumeRate.SetValue(Name, -35); } } } diff --git "a/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" "b/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" index eb408df..88665f4 100644 --- "a/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" +++ "b/InfrastSim/TimeDriven/Operators/\320\233\320\265\321\202\320\276.cs" @@ -11,7 +11,7 @@ public override void Resolve(Simulator simu) { if (manufacturing.IsProduceCombatRecord() && simu.IsOpInFacility("古米", FacilityType.Trading)) { - EfficiencyModifier.SetValue(Name, 0.3); + EfficiencyModifier.SetValue(Name, 30); } } } diff --git "a/InfrastSim/TimeDriven/Operators/\320\237\320\276\320\267\321\221\320\274\320\272\320\260.cs" "b/InfrastSim/TimeDriven/Operators/\320\237\320\276\320\267\321\221\320\274\320\272\320\260.cs" index 1fa57da..e1010d9 100644 --- "a/InfrastSim/TimeDriven/Operators/\320\237\320\276\320\267\321\221\320\274\320\272\320\260.cs" +++ "b/InfrastSim/TimeDriven/Operators/\320\237\320\276\320\267\321\221\320\274\320\272\320\260.cs" @@ -16,7 +16,7 @@ public override void Resolve(Simulator simu) { productLines -= simu.GetRealGoldProductionLine() / (kirara.Upgraded >= 2 ? 2 : 4) * 2; } - EfficiencyModifier.SetValue(Name, productLines * 0.05); + EfficiencyModifier.SetValue(Name, productLines * 5); }); if (Upgraded >= 2) { diff --git a/InfrastSim/TimeDriven/PowerStation.cs b/InfrastSim/TimeDriven/PowerStation.cs index ba5375a..e314b89 100644 --- a/InfrastSim/TimeDriven/PowerStation.cs +++ b/InfrastSim/TimeDriven/PowerStation.cs @@ -9,6 +9,6 @@ public class PowerStation : FacilityBase { }; public override int AcceptOperatorNums => 1; - public override double MoodConsumeModifier => 0; - public override double EffiencyModifier => WorkingOperatorsCount * 0.05; + public override int MoodConsumeModifier => 0; + public override int EffiencyModifier => WorkingOperatorsCount * 5; } diff --git a/InfrastSim/TimeDriven/Priority.cs b/InfrastSim/TimeDriven/Priority.cs index 71b9dbf..0f28659 100644 --- a/InfrastSim/TimeDriven/Priority.cs +++ b/InfrastSim/TimeDriven/Priority.cs @@ -1,5 +1,5 @@ namespace InfrastSim.TimeDriven; -internal static class Priority { +internal static partial class Priority { public const int PropConversion = 20; public const int Common = 100; public const int WaaiFu = 110; diff --git a/InfrastSim/TimeDriven/Reception.cs b/InfrastSim/TimeDriven/Reception.cs index 709fd98..e3d38af 100644 --- a/InfrastSim/TimeDriven/Reception.cs +++ b/InfrastSim/TimeDriven/Reception.cs @@ -3,6 +3,6 @@ public class Reception : FacilityBase { public override FacilityType Type => FacilityType.Reception; public override int AcceptOperatorNums => 2; - public override double MoodConsumeModifier => 0; // TODO - public override double EffiencyModifier => 0; // TODO + public override int MoodConsumeModifier => 0; // TODO + public override int EffiencyModifier => 0; // TODO } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 521c0ab..6433ccd 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -1,5 +1,6 @@ using RandomEx; using System.Collections.Frozen; +using System.Diagnostics; using System.Text; using System.Text.Json; @@ -22,7 +23,7 @@ public Simulator() { public Simulator(in JsonElement elem) { if (elem.TryGetProperty("time", out JsonElement timeElem) && timeElem.TryGetDateTime(out var now)) { - Now = now; + Now = Round(now); } if (elem.TryGetProperty("random", out JsonElement randomElem)) { @@ -32,27 +33,27 @@ public Simulator(in JsonElement elem) { } if (elem.TryGetProperty("drones", out JsonElement dronesElem)) { - _drones = dronesElem.GetDouble(); + _drones = dronesElem.GetInt32(); } if (elem.TryGetProperty("refresh", out JsonElement refreshElem)) { - _refresh = refreshElem.GetDouble(); + _refresh = refreshElem.GetInt32(); } - if (elem.TryGetProperty("total-manu-product", out JsonElement totManuProdElem)) { - _totalManuProduct = totManuProdElem.GetDouble(); + if (elem.TryGetProperty("total-manu-progress", out JsonElement totManuProgElem)) { + _totalManuProgress = totManuProgElem.GetInt64(); } - if (elem.TryGetProperty("total-trad-product", out JsonElement totTradProdElem)) { - _totalTradProduct = totTradProdElem.GetDouble(); + if (elem.TryGetProperty("total-trad-progress", out JsonElement totTradProgElem)) { + _totalTradProgress = totTradProgElem.GetInt64(); } - if (elem.TryGetProperty("total-office-product", out JsonElement totOfficeProdElem)) { - _totalOfficeProduct = totOfficeProdElem.GetDouble(); + if (elem.TryGetProperty("total-office-progress", out JsonElement totOfficeProgElem)) { + _totalOfficeProgress = totOfficeProgElem.GetInt64(); } - if (elem.TryGetProperty("total-drones-product", out JsonElement totDronesProdElem)) { - _totalDronesProduct = totDronesProdElem.GetDouble(); + if (elem.TryGetProperty("total-drones-progress", out JsonElement totDronesProgElem)) { + _totalDronesProgress = totDronesProgElem.GetInt64(); } if (elem.TryGetProperty("materials", out JsonElement materialsElem)) { @@ -118,14 +119,15 @@ public Simulator(in JsonElement elem) { } public DateTime Now { get; private set; } + public static DateTime Round(DateTime original) => new(original.Year, original.Month, original.Day, original.Hour, original.Minute, original.Second); + public XoshiroRandom Random { get; set; } ITimeDrivenObject? _interestSource; TimeSpan _nextInterest; - static readonly TimeSpan MinSpan = TimeSpan.FromSeconds(2); - internal void SetInterest(ITimeDrivenObject o, TimeSpan span) { - if (span < _nextInterest) { + internal void SetInterest(ITimeDrivenObject o, int seconds) { + if (seconds * TimeSpan.TicksPerSecond < _nextInterest.Ticks) { _interestSource = o; - _nextInterest = span; + _nextInterest = TimeSpan.FromSeconds(seconds); } } public void Resolve() { @@ -154,28 +156,22 @@ void SimulateImpl(TimeSpan span) { foreach (var facility in Facilities) { facility?.Update(this, info); } - AddDrones(DronesEfficiency * (info.TimeElapsed / TimeSpan.FromMinutes(6))); - _refresh += OfficeEfficiency * (info.TimeElapsed / TimeSpan.FromHours(12)); - _totalOfficeProduct += OfficeEfficiency * (info.TimeElapsed.Ticks / 100000); + ProduceDrones(DronesEfficiency * info.TimeElapsed.TotalSeconds()); + ProduceRefresh(OfficeEfficiency * info.TimeElapsed.TotalSeconds()); Now += span; } public void SimulateUntil(DateTime dateTime) { + dateTime = Round(dateTime); while (Now < dateTime) { Resolve(); QueryInterest(); var span = dateTime - Now; - - if (span < MinSpan) { - SimulateImpl(span); - return; - } - if (_nextInterest < span) span = _nextInterest; - SimulateImpl(span + MinSpan); + SimulateImpl(span); } } - internal FrozenDictionary Operators; + internal FrozenDictionary Operators { get; set; } internal OperatorBase GetOperator(string name) { return Operators.GetValueOrDefault(name) ?? throw new KeyNotFoundException($"未知的干员名称 {name}"); } @@ -204,12 +200,8 @@ public Crafting Crafting { get => (Crafting)Facilities[4]!; private set => Facilities[4] = value; } - public ArraySegment Dormitories { - get => new(Facilities, 5, 4); - } - public ArraySegment ModifiableFacilities { - get => new(Facilities, 9, 9); - } + public ArraySegment Dormitories => new(Facilities, 5, 4); + public ArraySegment ModifiableFacilities => new(Facilities, 9, 9); internal FacilityBase?[] Facilities { get; } = new FacilityBase?[18]; public IEnumerable PowerStations @@ -219,9 +211,9 @@ public IEnumerable TradingStations public IEnumerable ManufacturingStations => ModifiableFacilities.Select(fac => fac as ManufacturingStation).Where(fac => fac != null); public IEnumerable OperatorsInFacility - => Facilities.SelectMany(fac => fac?.Operators ?? Enumerable.Empty()); + => Facilities.SelectMany(fac => fac?.Operators ?? []); public IEnumerable WorkingOperators - => Facilities.SelectMany(fac => fac?.WorkingOperators ?? Enumerable.Empty()); + => Facilities.SelectMany(fac => fac?.WorkingOperators ?? []); #endregion public int TotalPowerConsume => @@ -233,26 +225,27 @@ public IEnumerable WorkingOperators ModifiableFacilities .Where(fac => fac is PowerStation) .Sum(fac => -fac!.PowerConsumes); - public double NextDroneTimeInSeconds => - (Math.Ceiling(_drones) - _drones) * 360 / DronesEfficiency; + public double NextDroneTimeInSeconds => (TicksHelper.TicksToProduceDrone - _droneProgress) / DronesEfficiency; // 这两个参数本来应该由脚本执行器维护,为了方便直接实现到模拟器类 // 更好的做法是模拟器实现一种扩展方法来管理这些额外的变量的生命周期 - public string SelectedFacilityString { get; set; } + public string SelectedFacilityString { get; set; } = string.Empty; public FacilityBase? SelectedFacilityCache { get; set; } - double _drones; - double _refresh; - double _totalManuProduct; - double _totalTradProduct; - double _totalOfficeProduct; - double _totalDronesProduct; + int _drones; + int _droneProgress; + int _refresh; + int _refreshProgress; + long _totalManuProgress; + long _totalTradProgress; + long _totalOfficeProgress; + long _totalDronesProgress; - Dictionary _materials = new(); - Dictionary _globalValues = new(); - SortedDictionary> _delayActions = new(); + Dictionary _materials = []; + Dictionary _globalValues = []; + SortedDictionary> _delayActions = []; public void Delay(Action action, int priority = 100) { if (_delayActions.ContainsKey(priority)) { @@ -261,12 +254,31 @@ public void Delay(Action action, int priority = 100) { _delayActions[priority] = action; } } - public int Drones => (int)Math.Floor(_drones); - public void AddDrones(double amount) { + public int Drones => _drones; + public void AddDrones(int amount) { _drones = Math.Min(200, _drones + amount); - _totalDronesProduct += amount; - } - internal void RemoveDrones(int amount) => _drones -= Math.Min(Drones, amount); + } + public void ProduceDrones(int progress) { + _droneProgress += progress; + _drones += _droneProgress / TicksHelper.TicksToProduceDrone; + if (_drones >= 200) { + _drones = 200; + _droneProgress = 0; + } else { + _droneProgress %= TicksHelper.TicksToProduceDrone; + } + _totalDronesProgress += progress; + } + public void ProduceRefresh(int progress) { + _refreshProgress += progress; + _refresh += _refreshProgress / TicksHelper.TicksToProduceDrone; + _refreshProgress %= TicksHelper.TicksToProduceDrone; + _totalOfficeProgress += progress; + } + internal void RemoveDrones(int amount) { + _drones -= amount; + Debug.Assert(_drones >= 0); + } internal void RemoveMaterial(Material mat) { _materials[mat.Name] = _materials.GetValueOrDefault(mat.Name) - mat.Count; } @@ -279,19 +291,16 @@ internal void AddMaterial(Material mat) { internal void AddMaterial(string name, int amount) { _materials[name] = _materials.GetValueOrDefault(name) + amount; } - internal void AddManuProduct(double amount) { - _totalManuProduct += amount; - } - internal void AddTradProduct(double amount) { - _totalTradProduct += amount; + internal void AddManuProgress(int progress) { + _totalManuProgress += progress; } - internal void AddOfficeProduct(double amount) { - _totalOfficeProduct += amount; + internal void AddTradProgress(int progress) { + _totalTradProgress += progress; } public AggregateValue GetGlobalValue(string name) { if (!_globalValues.ContainsKey(name)) { - _globalValues.Add(name, new(min: 0.0)); + _globalValues.Add(name, new(min: 0)); } return _globalValues[name]; } @@ -317,22 +326,22 @@ public AggregateValue GetGlobalValue(string name) { #region 全局效率 public AggregateValue GlobalManufacturingEfficiency => GetGlobalValue("全局制造站效率"); public AggregateValue GlobalTradingEfficiency => GetGlobalValue("全局贸易站效率"); - public double DronesEfficiency => 1 + PowerStations.Sum(power => power.TotalEffiencyModifier); - public double OfficeEfficiency => (Office.WorkingOperators.Any() ? 1 : 0) + Office.TotalEffiencyModifier; - public double ManufacturingEfficiency { + public int DronesEfficiency => 100 + PowerStations.Sum(power => power.TotalEffiencyModifier); + public int OfficeEfficiency => (Office.WorkingOperators.Any() ? 100 : 0) + Office.TotalEffiencyModifier; + public int ManufacturingEfficiency { get { var workingFacilities = ManufacturingStations.Where(fac => fac.Operators.Any()); var count = workingFacilities.Count(); var eff = workingFacilities.Sum(fac => fac.TotalEffiencyModifier); - return count * (1 + GlobalManufacturingEfficiency) + eff; + return count * (100 + GlobalManufacturingEfficiency) + eff; } } - public double TradingEfficiency { + public int TradingEfficiency { get { var workingFacilities = TradingStations.Where(fac => fac.Operators.Any()); var count = workingFacilities.Count(); var eff = workingFacilities.Sum(fac => fac.TotalEffiencyModifier); - return count * (1 + GlobalTradingEfficiency) + eff; + return count * (100 + GlobalTradingEfficiency) + eff; } } #endregion @@ -352,10 +361,10 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { Random.ToJson(writer); writer.WriteNumber("drones", _drones); writer.WriteNumber("refresh", _refresh); - writer.WriteNumber("total-manu-product", _totalManuProduct); - writer.WriteNumber("total-trad-product", _totalTradProduct); - writer.WriteNumber("total-office-product", _totalOfficeProduct); - writer.WriteNumber("total-drones-product", _totalDronesProduct); + writer.WriteNumber("total-manu-product", _totalManuProgress); + writer.WriteNumber("total-trad-product", _totalTradProgress); + writer.WriteNumber("total-office-product", _totalOfficeProgress); + writer.WriteNumber("total-drones-product", _totalDronesProgress); if (detailed) { writer.WriteNumber("drones-efficiency", DronesEfficiency); writer.WriteNumber("office-efficiency", OfficeEfficiency); diff --git a/InfrastSim/TimeDriven/Skills.cs b/InfrastSim/TimeDriven/Skills.cs index b038cca..6c71eb9 100644 --- a/InfrastSim/TimeDriven/Skills.cs +++ b/InfrastSim/TimeDriven/Skills.cs @@ -3,7 +3,7 @@ internal static class Skills { public static void 裁缝Alpha(OperatorBase op, Simulator simu) { if (op.Facility is TradingStation trading && !op.IsTired) { trading.PreGoldOrderPending += args => - args.Priority4Gold.SetIfGreater(0.67 * Math.Min(1, op.WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(67 * Math.Min(1, op.WorkingTime.TotalHours / 3))); } } @@ -11,9 +11,9 @@ public static void 裁缝Beta(OperatorBase op, Simulator simu) { if (op.Facility is TradingStation trading && !op.IsTired) { trading.PreGoldOrderPending += args => { if (op.WorkingTime < TimeSpan.FromHours(3)) { - args.Priority4Gold.SetIfGreater(3 * Math.Min(1, op.WorkingTime / TimeSpan.FromHours(3))); + args.Priority4Gold.SetIfGreater((int)(300 * Math.Min(1, op.WorkingTime.TotalHours / 3))); } else { - args.Priority4Gold.SetIfGreater(1.5 + 2.5 * Math.Min(1, op.WorkingTime / TimeSpan.FromHours(5))); + args.Priority4Gold.SetIfGreater((int)(150 + 250 * Math.Min(1, op.WorkingTime.TotalHours / 5))); } }; } diff --git a/InfrastSim/TimeDriven/TradingStation.cs b/InfrastSim/TimeDriven/TradingStation.cs index b858499..8188ee8 100644 --- a/InfrastSim/TimeDriven/TradingStation.cs +++ b/InfrastSim/TimeDriven/TradingStation.cs @@ -12,7 +12,6 @@ public class TradingStation : FacilityBase, IApplyDrones { _ => 0, }; public AggregateValue Capacity { get; private set; } = new AggregateValue(0, 1, 64); - public int CapacityN => (int)Capacity; Order?[] _orders = new Order[64]; public IEnumerable Orders => _orders.Where(o => o != null); @@ -23,19 +22,19 @@ public enum OrderStrategy { } public OrderStrategy Strategy { get; set; } = OrderStrategy.Gold; public Order? CurrentOrder { get; set; } - public double Progress { get; private set; } - public TimeSpan RemainsTime => (CurrentOrder?.ProduceTime ?? TimeSpan.MaxValue) * (1 - Progress); + public int Progress { get; private set; } + public int RemainTicks => (CurrentOrder?.ProduceTicks ?? int.MaxValue) - Progress; public event Action? PreGoldOrderPending; public event Action? OnPending; public bool PendingNewOrder(XoshiroRandom random) { - if (CapacityN == OrderCount) return false; + if (Capacity == OrderCount) return false; Order order; if (Strategy == OrderStrategy.Gold) { var args = Level switch { - 1 => new GoldOrderPendingArgs(new(1), new(max: 0), new(max: 0)), - 2 => new GoldOrderPendingArgs(new(0.6), new(0.4), new(max: 0)), - 3 => new GoldOrderPendingArgs(new(0.3), new(0.5), new(0.2)), + 1 => new GoldOrderPendingArgs(new(100), new(max: 0), new(max: 0)), + 2 => new GoldOrderPendingArgs(new(60), new(40), new(max: 0)), + 3 => new GoldOrderPendingArgs(new(30), new(50), new(20)), _ => throw new NotImplementedException() }; PreGoldOrderPending?.Invoke(args); @@ -75,19 +74,10 @@ public void RemoveAllOrder() { } - public override double MoodConsumeModifier { - get { - return Math.Min(0.0, -0.05 * (WorkingOperatorsCount - 1)); - } - } - public override double EffiencyModifier { - get { - return 0.01 * WorkingOperatorsCount; - } - } - + public override int MoodConsumeModifier => Math.Min(0, -5 * (WorkingOperatorsCount - 1)); + public override int EffiencyModifier => WorkingOperatorsCount; public override int AcceptOperatorNums => Level; - public override bool IsWorking => CapacityN > OrderCount && Operators.Any(); + public override bool IsWorking => Capacity > OrderCount && Operators.Any(); public override void Reset() { base.Reset(); @@ -102,9 +92,9 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); } public override void QueryInterest(Simulator simu) { - var effiency = 1 + TotalEffiencyModifier + simu.GlobalTradingEfficiency; - var remains = RemainsTime / effiency; - simu.SetInterest(this, remains); + var efficiency = 100 + TotalEffiencyModifier + simu.GlobalTradingEfficiency; + var remainSeconds = (RemainTicks + efficiency - 1) / efficiency; + simu.SetInterest(this, remainSeconds); base.QueryInterest(simu); } @@ -116,18 +106,16 @@ public override void Update(Simulator simu, TimeElapsedInfo info) { } } Debug.Assert(CurrentOrder != null); - var effiency = 1 + TotalEffiencyModifier + simu.GlobalTradingEfficiency; - var equivTime = info.TimeElapsed * effiency; - if (equivTime >= RemainsTime) { - var remains = equivTime - RemainsTime; + var efficiency = 100 + TotalEffiencyModifier + simu.GlobalTradingEfficiency; + var pendingProgress = info.TimeElapsed.TotalSeconds() * efficiency; + simu.AddTradProgress(pendingProgress); + if (pendingProgress >= RemainTicks) { + pendingProgress -= RemainTicks; InsertCurrentOrder(); - if (PendingNewOrder(simu.Random)) { - Progress += remains / CurrentOrder.ProduceTime; - } - } else { - Progress += equivTime / CurrentOrder.ProduceTime; + PendingNewOrder(simu.Random); } + Progress += pendingProgress; } base.Update(simu, info); @@ -136,15 +124,15 @@ public override void Update(Simulator simu, TimeElapsedInfo info) { public int ApplyDrones(Simulator simu, int amount) { if (CurrentOrder == null) return 0; - int max = (int)Math.Ceiling(RemainsTime / TimeSpan.FromMinutes(3)); - amount = ((int[]) [amount, simu.Drones, max]).Min(); - var time = TimeSpan.FromMinutes(3 * amount); + var max = (RemainTicks + TicksHelper.TicksPerDrone - 1) / TicksHelper.TicksPerDrone; + amount = Math.Min(Math.Min(amount, simu.Drones), max); + var pendingProgress = amount * TicksHelper.TicksPerDrone; - if (time >= RemainsTime) { + if (pendingProgress >= RemainTicks) { InsertCurrentOrder(); PendingNewOrder(simu.Random); } else { - Progress += time / CurrentOrder.ProduceTime; + Progress += amount * TicksHelper.TicksPerDrone; } simu.RemoveDrones(amount); return amount; @@ -163,14 +151,14 @@ protected override void WriteDerivedContent(Utf8JsonWriter writer, bool detailed writer.WriteEndArray(); if (detailed) { - writer.WriteNumber("remains", RemainsTime.TotalSeconds); + writer.WriteNumber("remains", (RemainTicks + TicksHelper.TicksPerSecond - 1) / TicksHelper.TicksPerSecond); writer.WriteNumber("base-capacity", BaseCapacity); - writer.WriteNumber("capacity", CapacityN); + writer.WriteNumber("capacity", Capacity); writer.WriteItem("capacity-details", Capacity); var args = Level switch { - 1 => new GoldOrderPendingArgs(new(1), new(max: 0), new(max: 0)), - 2 => new GoldOrderPendingArgs(new(0.6), new(0.4), new(max: 0)), - 3 => new GoldOrderPendingArgs(new(0.3), new(0.5), new(0.2)), + 1 => new GoldOrderPendingArgs(new(100), new(max: 0), new(max: 0)), + 2 => new GoldOrderPendingArgs(new(60), new(40), new(max: 0)), + 3 => new GoldOrderPendingArgs(new(30), new(50), new(20)), _ => throw new NotImplementedException() }; PreGoldOrderPending?.Invoke(args); @@ -183,9 +171,6 @@ protected override void WriteDerivedContent(Utf8JsonWriter writer, bool detailed } } protected override void ReadDerivedContent(JsonElement elem) { - if (elem.TryGetProperty("progress", out var progress)) { - Progress = progress.GetDouble(); - } if (elem.TryGetProperty("strategy", out var strategy)) { Strategy = strategy.GetString() switch { "Gold" => OrderStrategy.Gold, @@ -196,7 +181,6 @@ protected override void ReadDerivedContent(JsonElement elem) { if (elem.TryGetProperty("current-order", out var currentOrder)) { CurrentOrder = Order.FromJson(currentOrder); } - if (elem.TryGetProperty("orders", out var orders)) { foreach (var orderElem in orders.EnumerateArray()) { var order = Order.FromJson(orderElem); @@ -204,5 +188,12 @@ protected override void ReadDerivedContent(JsonElement elem) { _orders[index] = order; } } + if (elem.TryGetProperty("progress", out var progress)) { + if (progress.TryGetDouble(out var value)) { + if (CurrentOrder != null) Progress = (int)(CurrentOrder.ProduceTicks * (1 - value)); + } else { + Progress = progress.GetInt32(); + } + } } } diff --git a/InfrastSim/TimeDriven/Training.cs b/InfrastSim/TimeDriven/Training.cs index deea028..14ec30f 100644 --- a/InfrastSim/TimeDriven/Training.cs +++ b/InfrastSim/TimeDriven/Training.cs @@ -3,8 +3,8 @@ public class Training : FacilityBase { public override FacilityType Type => FacilityType.Training; public override int AcceptOperatorNums => 2; - public override double MoodConsumeModifier => 0.0; - public override double EffiencyModifier => 0.05 * WorkingOperatorsCount; + public override int MoodConsumeModifier => 0; + public override int EffiencyModifier => WorkingOperatorsCount * 5; public override bool IsWorking => _operators[0] != null && IsTraining; public bool IsTraining { get; internal set; } = false; } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs b/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs index b776ac2..1672a5c 100644 --- a/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs +++ b/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs @@ -13,12 +13,13 @@ public static JsonNode RewriteSimulator(Simulator simu, JsonNode node) { globalProperties.Add(prop.Item1, (int)prop.Item2); } node["global_properties"] = globalProperties; - var facilities = new JsonObject(); - facilities["controlCenter"] = RewriteFacility(node["control-center"]!); - facilities["office"] = RewriteFacility(node["office"]!); - facilities["recpetionRoom"] = RewriteFacility(node["reception"]!); - facilities["training"] = RewriteFacility(node["training"]!); - facilities["crafting"] = RewriteFacility(node["crafting"]!); + var facilities = new JsonObject { + ["controlCenter"] = RewriteFacility(node["control-center"]!), + ["office"] = RewriteFacility(node["office"]!), + ["recpetionRoom"] = RewriteFacility(node["reception"]!), + ["training"] = RewriteFacility(node["training"]!), + ["crafting"] = RewriteFacility(node["crafting"]!) + }; for (int i = 0; i < 4; i++) { var fac = node["dormitories"]![i]; if (fac != null) { diff --git a/InfrastSimSourceGenerator/GlobalSuppressions.cs b/InfrastSimSourceGenerator/GlobalSuppressions.cs new file mode 100644 index 0000000..e7c563d --- /dev/null +++ b/InfrastSimSourceGenerator/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; +[assembly: SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1036:指定分析器禁止的 API 强制设置", Justification = "<挂起>", Scope = "type", Target = "~T:InfrastSimSourceGenerator.ScriptSourceGenerator")] +[assembly: SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1036:指定分析器禁止的 API 强制设置", Justification = "<挂起>", Scope = "type", Target = "~T:InfrastSimSourceGenerator.OperatorGroupsSourceGenerator")] diff --git a/InfrastSimSourceGenerator/InfrastSimSourceGenerator.csproj b/InfrastSimSourceGenerator/InfrastSimSourceGenerator.csproj index 0f47663..9aa322c 100644 --- a/InfrastSimSourceGenerator/InfrastSimSourceGenerator.csproj +++ b/InfrastSimSourceGenerator/InfrastSimSourceGenerator.csproj @@ -3,6 +3,7 @@ netstandard2.0 latest + true From db0c06383c2abbc99449a04dfed8e1b8a1464342 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 16:57:48 +0800 Subject: [PATCH 29/39] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/FacilityBase.cs | 2 +- InfrastSim/TimeDriven/ManufacturingStation.cs | 2 +- InfrastSim/TimeDriven/Simulator.cs | 16 ++++++++-------- InfrastSim/TimeDriven/TradingStation.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/InfrastSim/TimeDriven/FacilityBase.cs b/InfrastSim/TimeDriven/FacilityBase.cs index 1d580ab..1e5f62f 100644 --- a/InfrastSim/TimeDriven/FacilityBase.cs +++ b/InfrastSim/TimeDriven/FacilityBase.cs @@ -163,7 +163,7 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { if (detailed) { writer.WriteNumber("base-efficiency", (100 + EffiencyModifier) / 100.0); - writer.WriteNumber("operators-efficiency", WorkingOperators.Sum(op => op.EfficiencyModifier)); + writer.WriteNumber("operators-efficiency", WorkingOperators.Sum(op => op.EfficiencyModifier) / 100.0); } writer.WriteEndObject(); diff --git a/InfrastSim/TimeDriven/ManufacturingStation.cs b/InfrastSim/TimeDriven/ManufacturingStation.cs index 877d3d5..e0a86ad 100644 --- a/InfrastSim/TimeDriven/ManufacturingStation.cs +++ b/InfrastSim/TimeDriven/ManufacturingStation.cs @@ -89,8 +89,8 @@ public int ApplyDrones(Simulator simu, int amount) { protected override void WriteDerivedContent(Utf8JsonWriter writer, bool detailed = false) { writer.WriteNumber("product-index", Array.IndexOf(Product.AllProducts, Product)); - writer.WriteNumber("progress", Progress); writer.WriteNumber("product-count", ProductCount); + writer.WriteNumber("progress", Progress); if (detailed) { if (Product != null) writer.WriteString("product", Product.Name); diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 6433ccd..2aea543 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -361,15 +361,15 @@ public void ToJson(Utf8JsonWriter writer, bool detailed = false) { Random.ToJson(writer); writer.WriteNumber("drones", _drones); writer.WriteNumber("refresh", _refresh); - writer.WriteNumber("total-manu-product", _totalManuProgress); - writer.WriteNumber("total-trad-product", _totalTradProgress); - writer.WriteNumber("total-office-product", _totalOfficeProgress); - writer.WriteNumber("total-drones-product", _totalDronesProgress); + writer.WriteNumber("total-manu-progress", _totalManuProgress); + writer.WriteNumber("total-trad-progress", _totalTradProgress); + writer.WriteNumber("total-office-progress", _totalOfficeProgress); + writer.WriteNumber("total-drones-progress", _totalDronesProgress); if (detailed) { - writer.WriteNumber("drones-efficiency", DronesEfficiency); - writer.WriteNumber("office-efficiency", OfficeEfficiency); - writer.WriteNumber("manufacturing-efficiency", ManufacturingEfficiency); - writer.WriteNumber("trading-efficiency", TradingEfficiency); + writer.WriteNumber("drones-efficiency", DronesEfficiency / 100.0); + writer.WriteNumber("office-efficiency", OfficeEfficiency / 100.0); + writer.WriteNumber("manufacturing-efficiency", ManufacturingEfficiency / 100.0); + writer.WriteNumber("trading-efficiency", TradingEfficiency / 100.0); } writer.WritePropertyName("operators"); diff --git a/InfrastSim/TimeDriven/TradingStation.cs b/InfrastSim/TimeDriven/TradingStation.cs index 8188ee8..34e209a 100644 --- a/InfrastSim/TimeDriven/TradingStation.cs +++ b/InfrastSim/TimeDriven/TradingStation.cs @@ -140,9 +140,9 @@ public int ApplyDrones(Simulator simu, int amount) { protected override void WriteDerivedContent(Utf8JsonWriter writer, bool detailed = false) { + writer.WriteString("strategy", Strategy.ToString()); writer.WriteItem("current-order", CurrentOrder, detailed); writer.WriteNumber("progress", Progress); ; - writer.WriteString("strategy", Strategy.ToString()); writer.WritePropertyName("orders"); writer.WriteStartArray(); foreach (var order in Orders) { From 7dc96bf5cb313f77cd18fe1cb336f11b9a5e940d Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 17:01:02 +0800 Subject: [PATCH 30/39] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Enumerate/Efficiency.cs | 8 ++++---- InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/InfrastSim/TimeDriven/Enumerate/Efficiency.cs b/InfrastSim/TimeDriven/Enumerate/Efficiency.cs index 4cda874..b649264 100644 --- a/InfrastSim/TimeDriven/Enumerate/Efficiency.cs +++ b/InfrastSim/TimeDriven/Enumerate/Efficiency.cs @@ -1,5 +1,5 @@ namespace InfrastSim.TimeDriven.Enumerate; -public record struct Efficiency(double TradEff, double ManuEff, double PowerEff) { +public record struct Efficiency(int TradEff, int ManuEff, int PowerEff) { public static Efficiency operator -(Efficiency a, Efficiency b) { return new Efficiency(a.TradEff - b.TradEff, a.ManuEff - b.ManuEff, a.PowerEff - b.PowerEff); } @@ -7,15 +7,15 @@ public record struct Efficiency(double TradEff, double ManuEff, double PowerEff) return new Efficiency(a.TradEff + b.TradEff, a.ManuEff + b.ManuEff, a.PowerEff + b.PowerEff); } - public readonly double GetScore() { + public readonly int GetScore() { return TradEff * 5 + ManuEff * 6 + PowerEff * 3; } public readonly bool IsZero() { - return Util.Equals(0, TradEff) && Util.Equals(0, ManuEff) && Util.Equals(0, PowerEff); + return TradEff == 0 && ManuEff == 0 && PowerEff == 0; } public readonly bool IsPositive() { - return !(TradEff < -Util.Epsilon || ManuEff < -Util.Epsilon || PowerEff < -Util.Epsilon || IsZero()); + return TradEff >= 0 && ManuEff >= 0 && PowerEff >= 0 && !IsZero(); } } \ No newline at end of file diff --git a/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs b/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs index 60638a0..f831aac 100644 --- a/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs +++ b/InfrastSim/TimeDriven/Enumerate/EnumerateHelper.cs @@ -30,15 +30,15 @@ public static void Enumerate(JsonDocument json, Utf8JsonWriter writer) { writer.WritePropertyName("eff"); writer.WriteStartObject(); - writer.WriteNumber("manu_eff", r.eff.ManuEff); - writer.WriteNumber("trad_eff", r.eff.TradEff); - writer.WriteNumber("power_eff", r.eff.PowerEff); + writer.WriteNumber("manu_eff", r.eff.ManuEff / 100.0); + writer.WriteNumber("trad_eff", r.eff.TradEff / 100.0); + writer.WriteNumber("power_eff", r.eff.PowerEff / 100.0); writer.WriteEndObject(); writer.WritePropertyName("extra_eff"); writer.WriteStartObject(); - writer.WriteNumber("manu_eff", r.extra_eff.ManuEff); - writer.WriteNumber("trad_eff", r.extra_eff.TradEff); - writer.WriteNumber("power_eff", r.extra_eff.PowerEff); + writer.WriteNumber("manu_eff", r.extra_eff.ManuEff / 100.0); + writer.WriteNumber("trad_eff", r.extra_eff.TradEff / 100.0); + writer.WriteNumber("power_eff", r.extra_eff.PowerEff / 100.0); writer.WriteEndObject(); writer.WriteEndObject(); } From 65fb305cd29645407c134794262b47aa6054501e Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 17:16:04 +0800 Subject: [PATCH 31/39] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/Algorithms/Combination.cs | 12 ++++-------- InfrastSim/EventDriven/EventSourceBase.cs | 2 +- InfrastSim/EventDriven/IEventSource.cs | 3 +-- InfrastSim/EventDriven/OperatorBase.cs | 6 ++---- InfrastSim/FacilityType.cs | 8 +------- InfrastSim/GoldOrderPendingArgs.cs | 3 +-- InfrastSim/ISimulator.cs | 3 +-- InfrastSim/Order.cs | 2 -- InfrastSim/OrderPendingArgs.cs | 2 +- InfrastSim/Product.cs | 2 +- InfrastSim/Script/Parser.cs | 3 +-- InfrastSim/TimeDriven/Helper.cs | 18 ++++++------------ InfrastSim/TimeDriven/ManufacturingStation.cs | 2 -- InfrastSim/TimeDriven/OperatorBase.cs | 1 - InfrastSim/TimeDriven/OperatorSkillBuilder.cs | 1 - InfrastSim/TimeDriven/Operators/Archetto.cs | 2 +- InfrastSim/TimeDriven/Operators/Proviso.cs | 2 +- InfrastSim/TimeDriven/Operators/SilverAsh.cs | 2 +- InfrastSim/TimeDriven/Priority.cs | 2 +- InfrastSim/TimeDriven/Skills.cs | 2 +- InfrastSim/TimeDriven/WebHelper/Helper.cs | 6 ++---- InfrastSim/Util.cs | 3 +-- InfrastSimExports/Facility.cs | 8 +------- InfrastSimServer/Program.cs | 6 ++---- InfrastSimServer/SimulatorService.cs | 2 +- .../OperatorGroupsSourceGenerator.cs | 3 +-- .../OperatorInstancesSourceGenerator.cs | 1 - .../ScriptSourceGenerator.cs | 6 +++--- InfrastSimTest/ScriptTest.cs | 2 +- InfrastSimTest/SimulatorService.cs | 4 +--- InfrastSimTest/SimulatorTest.cs | 1 - InfrastSimWasm/SimulatorService.cs | 1 - RandomEx/XoshiroRandom.cs | 2 +- 33 files changed, 39 insertions(+), 84 deletions(-) diff --git a/InfrastSim/Algorithms/Combination.cs b/InfrastSim/Algorithms/Combination.cs index 56d2f8c..9da245c 100644 --- a/InfrastSim/Algorithms/Combination.cs +++ b/InfrastSim/Algorithms/Combination.cs @@ -18,8 +18,8 @@ public Combination(IList values, int n) { T[] arr; int cur; int p; - public int N { get; } - public int M { get; } + public int N { get; } // 组合长度 + public int M { get; } // 组合可选项数 public IEnumerable? Enumerate() { while (cur > 0 && M - p < N - cur) { @@ -49,14 +49,10 @@ public IEnumerable> ToEnumerable() { } } - class Enumerator : IEnumerator?> { - Combination _combination; + class Enumerator(Combination combination) : IEnumerator?> { + Combination _combination = combination; IEnumerable? _cur = null; - public Enumerator(Combination combination) { - _combination = combination; - } - public IEnumerable? Current => _cur; object? IEnumerator.Current => _cur; diff --git a/InfrastSim/EventDriven/EventSourceBase.cs b/InfrastSim/EventDriven/EventSourceBase.cs index 7e15c2d..84f565c 100644 --- a/InfrastSim/EventDriven/EventSourceBase.cs +++ b/InfrastSim/EventDriven/EventSourceBase.cs @@ -14,6 +14,6 @@ public void NotifyUpdate() { } public void AddTrigger(EventTrigger trigger) { - + } } diff --git a/InfrastSim/EventDriven/IEventSource.cs b/InfrastSim/EventDriven/IEventSource.cs index fa9c5ed..25a357c 100644 --- a/InfrastSim/EventDriven/IEventSource.cs +++ b/InfrastSim/EventDriven/IEventSource.cs @@ -1,7 +1,6 @@ namespace InfrastSim.EventDriven; -internal interface IEventSource -{ +internal interface IEventSource { DateTime TriggerTime { get; } event Action? TriggerTimeChanged; diff --git a/InfrastSim/EventDriven/OperatorBase.cs b/InfrastSim/EventDriven/OperatorBase.cs index 07d265f..004ee76 100644 --- a/InfrastSim/EventDriven/OperatorBase.cs +++ b/InfrastSim/EventDriven/OperatorBase.cs @@ -1,7 +1,6 @@ namespace InfrastSim.EventDriven; -internal abstract class OperatorBase : IEventSource -{ +internal abstract class OperatorBase : IEventSource { public double Mood { get; private set; } public AggregateValue MoodConsumeRate { get; private set; } = new(100); @@ -13,8 +12,7 @@ public void NotifyTimeElapsed(TimeElapsedInfo info) { throw new NotImplementedException(); } - public void NotifyUpdate() - { + public void NotifyUpdate() { throw new NotImplementedException(); } } diff --git a/InfrastSim/FacilityType.cs b/InfrastSim/FacilityType.cs index 9df8429..a7fc7f8 100644 --- a/InfrastSim/FacilityType.cs +++ b/InfrastSim/FacilityType.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace InfrastSim; +namespace InfrastSim; public enum FacilityType { ControlCenter, // 控制中枢 Manufacturing, // 制造站 diff --git a/InfrastSim/GoldOrderPendingArgs.cs b/InfrastSim/GoldOrderPendingArgs.cs index bd1aad8..e5fa7b9 100644 --- a/InfrastSim/GoldOrderPendingArgs.cs +++ b/InfrastSim/GoldOrderPendingArgs.cs @@ -1,7 +1,6 @@ namespace InfrastSim; public class GoldOrderPendingArgs { - public GoldOrderPendingArgs(AggregateValue priority2Gold, AggregateValue priority3Gold, AggregateValue priority4Gold) - { + public GoldOrderPendingArgs(AggregateValue priority2Gold, AggregateValue priority3Gold, AggregateValue priority4Gold) { Priority2Gold = priority2Gold ?? throw new ArgumentNullException(nameof(priority2Gold)); Priority3Gold = priority3Gold ?? throw new ArgumentNullException(nameof(priority3Gold)); Priority4Gold = priority4Gold ?? throw new ArgumentNullException(nameof(priority4Gold)); diff --git a/InfrastSim/ISimulator.cs b/InfrastSim/ISimulator.cs index 4427fb4..2c4c1a1 100644 --- a/InfrastSim/ISimulator.cs +++ b/InfrastSim/ISimulator.cs @@ -1,6 +1,5 @@ namespace InfrastSim; -public interface ISimulator -{ +public interface ISimulator { DateTime Now { get; } } \ No newline at end of file diff --git a/InfrastSim/Order.cs b/InfrastSim/Order.cs index 41cf41e..a8176ba 100644 --- a/InfrastSim/Order.cs +++ b/InfrastSim/Order.cs @@ -1,5 +1,3 @@ -using InfrastSim.TimeDriven; -using System.Reflection.Emit; using System.Text.Json; namespace InfrastSim; diff --git a/InfrastSim/OrderPendingArgs.cs b/InfrastSim/OrderPendingArgs.cs index 92628f3..6a1f2af 100644 --- a/InfrastSim/OrderPendingArgs.cs +++ b/InfrastSim/OrderPendingArgs.cs @@ -1,4 +1,4 @@ -namespace InfrastSim; +namespace InfrastSim; public class OrderPendingArgs { public OrderPendingArgs(Order order) { CurrentOrder = OriginOrder = order ?? throw new ArgumentNullException(nameof(order)); diff --git a/InfrastSim/Product.cs b/InfrastSim/Product.cs index 631d98c..8bff354 100644 --- a/InfrastSim/Product.cs +++ b/InfrastSim/Product.cs @@ -15,5 +15,5 @@ public record Product( ), ]; - public readonly static Product[] AllProducts = [..CombatRecords, Gold, ..StoneFragment]; + public readonly static Product[] AllProducts = [.. CombatRecords, Gold, .. StoneFragment]; } \ No newline at end of file diff --git a/InfrastSim/Script/Parser.cs b/InfrastSim/Script/Parser.cs index e74bd08..316ad6e 100644 --- a/InfrastSim/Script/Parser.cs +++ b/InfrastSim/Script/Parser.cs @@ -88,6 +88,5 @@ internal class Parameter(string value) { } internal class ParseException(string message, int line, int col) - : Exception($"Parse error at line {line + 1}, column {col + 1}: {message}") -{ + : Exception($"Parse error at line {line + 1}, column {col + 1}: {message}") { } diff --git a/InfrastSim/TimeDriven/Helper.cs b/InfrastSim/TimeDriven/Helper.cs index 7cce6c6..0797f51 100644 --- a/InfrastSim/TimeDriven/Helper.cs +++ b/InfrastSim/TimeDriven/Helper.cs @@ -8,8 +8,7 @@ public static bool VisibleToLookupSkill(this OperatorBase op) { return !op.IsExausted; } } - public static OperatorBase? FindOp(this FacilityBase facility, string opName) - { + public static OperatorBase? FindOp(this FacilityBase facility, string opName) { return facility.Operators.Where(op => op.Name == opName).FirstOrDefault(); } /// @@ -33,30 +32,25 @@ public static IEnumerable GroupMembers(this FacilityBase facility, /// /// 适用于 设施中是否有xxx组干员, 考虑红脸 /// - public static bool HasGroupMember(this FacilityBase facility, string group) - { + public static bool HasGroupMember(this FacilityBase facility, string group) { return facility.GroupMembers(group).Any(); } /// /// 适用于 设施中xxx组干员的数量, 考虑红脸 /// - public static int GroupMemberCount(this FacilityBase facility, string group) - { + public static int GroupMemberCount(this FacilityBase facility, string group) { return facility.GroupMembers(group).Count(); } - public static int GetRealGoldProductionLine(this Simulator simu) - { + public static int GetRealGoldProductionLine(this Simulator simu) { return simu.ModifiableFacilities .Where(fac => fac is ManufacturingStation manufacturing && manufacturing.Product == Product.Gold).Count(); } - public static int GetGoldProductionLine(this Simulator simu) - { + public static int GetGoldProductionLine(this Simulator simu) { return simu.ExtraGoldProductionLine + simu.GetRealGoldProductionLine(); } - public static int PowerStationsCount(this Simulator simu) - { + public static int PowerStationsCount(this Simulator simu) { return simu.ExtraPowerStation + simu.PowerStations.Count(); } public static bool IsProduceGold(this ManufacturingStation manufacturing) { diff --git a/InfrastSim/TimeDriven/ManufacturingStation.cs b/InfrastSim/TimeDriven/ManufacturingStation.cs index e0a86ad..52eaef8 100644 --- a/InfrastSim/TimeDriven/ManufacturingStation.cs +++ b/InfrastSim/TimeDriven/ManufacturingStation.cs @@ -1,5 +1,3 @@ -using InfrastSim.TimeDriven.Enumerate; -using System.Diagnostics; using System.Text.Json; namespace InfrastSim.TimeDriven; diff --git a/InfrastSim/TimeDriven/OperatorBase.cs b/InfrastSim/TimeDriven/OperatorBase.cs index 7f7ef5e..519884c 100644 --- a/InfrastSim/TimeDriven/OperatorBase.cs +++ b/InfrastSim/TimeDriven/OperatorBase.cs @@ -1,4 +1,3 @@ -using InfrastSim.TimeDriven.Operators; using System.Diagnostics; using System.Text; using System.Text.Json; diff --git a/InfrastSim/TimeDriven/OperatorSkillBuilder.cs b/InfrastSim/TimeDriven/OperatorSkillBuilder.cs index 2fcadfb..00f0e8e 100644 --- a/InfrastSim/TimeDriven/OperatorSkillBuilder.cs +++ b/InfrastSim/TimeDriven/OperatorSkillBuilder.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.Linq.Expressions; namespace InfrastSim.TimeDriven; diff --git a/InfrastSim/TimeDriven/Operators/Archetto.cs b/InfrastSim/TimeDriven/Operators/Archetto.cs index a3e8a58..c46d038 100644 --- a/InfrastSim/TimeDriven/Operators/Archetto.cs +++ b/InfrastSim/TimeDriven/Operators/Archetto.cs @@ -6,7 +6,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - var sum = simu.Dormitories.Sum(fac => fac?.Level ?? 0)* (Upgraded >= 2 ? 2 : 1); + var sum = simu.Dormitories.Sum(fac => fac?.Level ?? 0) * (Upgraded >= 2 ? 2 : 1); EfficiencyModifier.SetValue(Name, sum); } } diff --git a/InfrastSim/TimeDriven/Operators/Proviso.cs b/InfrastSim/TimeDriven/Operators/Proviso.cs index bd6e288..03be907 100644 --- a/InfrastSim/TimeDriven/Operators/Proviso.cs +++ b/InfrastSim/TimeDriven/Operators/Proviso.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven.Operators; +namespace InfrastSim.TimeDriven.Operators; internal class Proviso : OperatorBase { public override string Name => "但书"; diff --git a/InfrastSim/TimeDriven/Operators/SilverAsh.cs b/InfrastSim/TimeDriven/Operators/SilverAsh.cs index 2655b4c..721a96c 100644 --- a/InfrastSim/TimeDriven/Operators/SilverAsh.cs +++ b/InfrastSim/TimeDriven/Operators/SilverAsh.cs @@ -9,7 +9,7 @@ public override void Resolve(Simulator simu) { base.Resolve(simu); if (Facility is TradingStation trading && !IsTired) { - EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 20: 15); + EfficiencyModifier.SetValue(Name, Upgraded >= 2 ? 20 : 15); trading.Capacity.SetValue(Name, Upgraded >= 2 ? 4 : 2); } } diff --git a/InfrastSim/TimeDriven/Priority.cs b/InfrastSim/TimeDriven/Priority.cs index 0f28659..9e54d91 100644 --- a/InfrastSim/TimeDriven/Priority.cs +++ b/InfrastSim/TimeDriven/Priority.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven; +namespace InfrastSim.TimeDriven; internal static partial class Priority { public const int PropConversion = 20; public const int Common = 100; diff --git a/InfrastSim/TimeDriven/Skills.cs b/InfrastSim/TimeDriven/Skills.cs index 6c71eb9..cf05abf 100644 --- a/InfrastSim/TimeDriven/Skills.cs +++ b/InfrastSim/TimeDriven/Skills.cs @@ -1,4 +1,4 @@ -namespace InfrastSim.TimeDriven; +namespace InfrastSim.TimeDriven; internal static class Skills { public static void 裁缝Alpha(OperatorBase op, Simulator simu) { if (op.Facility is TradingStation trading && !op.IsTired) { diff --git a/InfrastSim/TimeDriven/WebHelper/Helper.cs b/InfrastSim/TimeDriven/WebHelper/Helper.cs index 47e6323..e21f193 100644 --- a/InfrastSim/TimeDriven/WebHelper/Helper.cs +++ b/InfrastSim/TimeDriven/WebHelper/Helper.cs @@ -1,8 +1,6 @@ -using InfrastSim.Script; using InfrastSim.Localization; -using System.Linq; +using InfrastSim.Script; using System.Text.Json; -using System.Text.Json.Nodes; using System.Text.RegularExpressions; namespace InfrastSim.TimeDriven.WebHelper; @@ -177,7 +175,7 @@ public static void SetFacilityState(this Simulator simu, string fac, JsonElement "Manufacturing" => new ManufacturingStation(), "Power" => new PowerStation(), _ => throw new ArgumentException("未知或不受支持的设施类型") - }; + }; simu.Facilities[index]?.RemoveAll(); simu.Facilities[index] = new_fac; } diff --git a/InfrastSim/Util.cs b/InfrastSim/Util.cs index 2239371..e9b2205 100644 --- a/InfrastSim/Util.cs +++ b/InfrastSim/Util.cs @@ -1,5 +1,5 @@ -using System.Text.Json; using System.Text; +using System.Text.Json; namespace InfrastSim; @@ -30,4 +30,3 @@ public static string ToJson(this IJsonSerializable serializable, bool detailed = return Encoding.UTF8.GetString(ms.ToArray()) ?? string.Empty; } } - \ No newline at end of file diff --git a/InfrastSimExports/Facility.cs b/InfrastSimExports/Facility.cs index a1e0b4e..bf9066b 100644 --- a/InfrastSimExports/Facility.cs +++ b/InfrastSimExports/Facility.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace InfrastSim.CDLL; +namespace InfrastSim.CDLL; public enum Facility { ControlCenter, Office, diff --git a/InfrastSimServer/Program.cs b/InfrastSimServer/Program.cs index 544372d..a47a963 100644 --- a/InfrastSimServer/Program.cs +++ b/InfrastSimServer/Program.cs @@ -28,10 +28,8 @@ public static void Main(string[] args) { app.UseAuthorization(); - app.UseExceptionHandler(appError => - { - appError.Run(async context => - { + app.UseExceptionHandler(appError => { + appError.Run(async context => { context.Response.StatusCode = 500; var exception = context.Features.Get(); if (exception != null) { diff --git a/InfrastSimServer/SimulatorService.cs b/InfrastSimServer/SimulatorService.cs index 59e283f..e831daa 100644 --- a/InfrastSimServer/SimulatorService.cs +++ b/InfrastSimServer/SimulatorService.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Text.Json.Nodes; -namespace InfrastSimServer; +namespace InfrastSimServer; public sealed class SimulatorService : IDisposable { //public static readonly SimulatorService Instance = new(); diff --git a/InfrastSimSourceGenerator/OperatorGroupsSourceGenerator.cs b/InfrastSimSourceGenerator/OperatorGroupsSourceGenerator.cs index 7367ca0..bb7b937 100644 --- a/InfrastSimSourceGenerator/OperatorGroupsSourceGenerator.cs +++ b/InfrastSimSourceGenerator/OperatorGroupsSourceGenerator.cs @@ -3,11 +3,10 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Text; -namespace InfrastSimSourceGenerator; +namespace InfrastSimSourceGenerator; [Generator] public class OperatorGroupsSourceGenerator : ISourceGenerator { diff --git a/InfrastSimSourceGenerator/OperatorInstancesSourceGenerator.cs b/InfrastSimSourceGenerator/OperatorInstancesSourceGenerator.cs index d9d3977..c59239f 100644 --- a/InfrastSimSourceGenerator/OperatorInstancesSourceGenerator.cs +++ b/InfrastSimSourceGenerator/OperatorInstancesSourceGenerator.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -using System.Diagnostics; using System.Linq; using System.Text; diff --git a/InfrastSimSourceGenerator/ScriptSourceGenerator.cs b/InfrastSimSourceGenerator/ScriptSourceGenerator.cs index 927f9f6..44e52ee 100644 --- a/InfrastSimSourceGenerator/ScriptSourceGenerator.cs +++ b/InfrastSimSourceGenerator/ScriptSourceGenerator.cs @@ -1,9 +1,9 @@ +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis; -using System.Text; -using System.Linq; using System.Collections.Generic; +using System.Linq; +using System.Text; namespace InfrastSimSourceGenerator; diff --git a/InfrastSimTest/ScriptTest.cs b/InfrastSimTest/ScriptTest.cs index 0805032..2370816 100644 --- a/InfrastSimTest/ScriptTest.cs +++ b/InfrastSimTest/ScriptTest.cs @@ -1,7 +1,7 @@ using InfrastSim.Script; using InfrastSim.TimeDriven.WebHelper; -namespace InfrastSimTest; +namespace InfrastSimTest; [TestClass] public class ScriptTest { [TestMethod] diff --git a/InfrastSimTest/SimulatorService.cs b/InfrastSimTest/SimulatorService.cs index 0ffe696..357831c 100644 --- a/InfrastSimTest/SimulatorService.cs +++ b/InfrastSimTest/SimulatorService.cs @@ -1,8 +1,6 @@ using InfrastSim.TimeDriven; using InfrastSim.TimeDriven.WebHelper; using System.Collections.Concurrent; -using System.Runtime.InteropServices.JavaScript; -using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; @@ -30,7 +28,7 @@ public static int CreateWithData(string json, bool newRandom = false) { var doc = JsonDocument.Parse(json); var id = Interlocked.Increment(ref SimuId); var simu = Simus[id] = new Simulator(doc.RootElement); - if (newRandom) simu.Random = new (); + if (newRandom) simu.Random = new(); return id; } diff --git a/InfrastSimTest/SimulatorTest.cs b/InfrastSimTest/SimulatorTest.cs index c51500a..ff64f43 100644 --- a/InfrastSimTest/SimulatorTest.cs +++ b/InfrastSimTest/SimulatorTest.cs @@ -1,5 +1,4 @@ using InfrastSim.TimeDriven.Enumerate; -using InfrastSim.TimeDriven.WebHelper; using InfrastSim.Wasm; using System.Text; using System.Text.Json; diff --git a/InfrastSimWasm/SimulatorService.cs b/InfrastSimWasm/SimulatorService.cs index af359e2..369a30c 100644 --- a/InfrastSimWasm/SimulatorService.cs +++ b/InfrastSimWasm/SimulatorService.cs @@ -1,4 +1,3 @@ -using InfrastSim.Localization; using InfrastSim.TimeDriven; using InfrastSim.TimeDriven.Enumerate; using InfrastSim.TimeDriven.WebHelper; diff --git a/RandomEx/XoshiroRandom.cs b/RandomEx/XoshiroRandom.cs index b02c140..72c727c 100644 --- a/RandomEx/XoshiroRandom.cs +++ b/RandomEx/XoshiroRandom.cs @@ -1,9 +1,9 @@ using System.Diagnostics; using System.Numerics; -using System.Text.Json; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; +using System.Text.Json; namespace RandomEx { /// From 2c3b35cce1911e175d1ec61ff81e0cb0e1c607c3 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 17:27:04 +0800 Subject: [PATCH 32/39] =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs b/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs index c211362..6a2d2d1 100644 --- a/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs +++ b/InfrastSim/TimeDriven/Enumerate/EnumerateContext.cs @@ -144,14 +144,14 @@ public Frame(OpEnumData[] comb, Efficiency base_eff, int ucnt) { uset[op.uid] = true; } } - public Frame FromComb(OpEnumData[] new_comb, Efficiency base_eff) { + public Frame FromComb(OpEnumData[] new_comb, Efficiency base_eff, int gid) { var op = new_comb[^1]; BitArray new_uset = new(uset); new_uset[op.uid] = true; return new Frame { comb = new_comb, base_eff = base_eff, - gid = new_comb.Length << 24 | (gid & 0xffffff) * op.prime % MOD, + gid = gid, init_size = init_size, uset = new_uset }; @@ -185,11 +185,12 @@ IEnumerable ProcessFrame(Simulator simu, Frame frame) { foreach (var op in ops) { if (frame.uset[op.uid]) continue; // 处理干员表中有同一干员的不同位置 - OpEnumData[] next_comb = [.. frame.comb, op]; - var gid = GetGroupId(next_comb); + var gid = (frame.comb.Length + 1 << 24) | (frame.gid & 0xffffff) * op.prime % MOD; if (!results.TryAdd(gid, default)) { continue; } + + OpEnumData[] next_comb = [.. frame.comb, op]; Efficiency eff; try { // 检验组合是否能被基建容纳,如果可以,则计算其效率 eff = TestMany(simu, next_comb); @@ -208,7 +209,7 @@ IEnumerable ProcessFrame(Simulator simu, Frame frame) { tot_extra_eff -= opd.SingleEfficiency; } results[gid] = new(next_comb, frame.init_size, eff, tot_extra_eff); - if (next_comb.Length < max_size) yield return frame.FromComb(next_comb, eff); + if (next_comb.Length < max_size) yield return frame.FromComb(next_comb, eff, gid); } } } From aa68861b6d92812b296705fda124e59941c1323a Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 17:46:02 +0800 Subject: [PATCH 33/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0Todo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/AggregateValue.cs | 8 +++++--- README.md | 18 +++++------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/InfrastSim/AggregateValue.cs b/InfrastSim/AggregateValue.cs index 680a705..7abd932 100644 --- a/InfrastSim/AggregateValue.cs +++ b/InfrastSim/AggregateValue.cs @@ -69,9 +69,11 @@ public void Remove(string name) { } public void Clear() { _disables.Clear(); - foreach (var key in _additionValues.Keys) { // BENCHMARK REQUIRED: use Clear() or manually set value to 0? - _additionValues[key] = 0; - } + // BENCHMARK REQUIRED: use Clear() or manually set value to 0? + _additionValues.Clear(); + //foreach (var key in _additionValues.Keys) { + // _additionValues[key] = 0; + //} _upToDate = true; _value = _baseValue; } diff --git a/README.md b/README.md index e4c984a..9f7090a 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,13 @@ ## InfrastSim 一个简单的明日方舟基建模拟库和服务器实现 +支持跨语言调用: C DLL, HTTP(S) 服务器, wasm +易于编辑修改、扩展 ### TODO list -- [x] ~~Simulator 的 Json 序列化/反序列化~~ - -- [x] ~~HTTP 服务器~~ - -- [x] ~~服务器请求返回详细信息~~ - -- [ ] 为会客室、加工站、办公室、训练室实现正确的心情状态功能 - -- [ ] 服务器为请求实现队列 - -- [ ] 实现事件查询机制,运行运行到特定事件(优先级下调) - -- [ ] 服务器验算电力、设施等级等参数(优先级下调) + - [ ] 重构SourceGenerator对于干员的部分,使得干员可以使用属性声明甚至实现简单完全自动生成 + - [ ] 优化执行流程,实现'编译模式',该模式生成的代码可以通过编译器优化最大限度移除对字符串字面量的依赖 + - [ ] 更进一步,移除AggerateValue中对于字典的依赖 \ No newline at end of file From 2b6bad94187c1b79e2a8fa6b04680fd59a44ddfd Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Sat, 23 Mar 2024 17:53:42 +0800 Subject: [PATCH 34/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f7090a..f0a223c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,6 @@ ### TODO list - - [ ] 重构SourceGenerator对于干员的部分,使得干员可以使用属性声明甚至实现简单完全自动生成 + - [ ] 重构SourceGenerator对于干员的部分,使得干员可以使用属性声明甚至实现简单干员完全自动生成 - [ ] 优化执行流程,实现'编译模式',该模式生成的代码可以通过编译器优化最大限度移除对字符串字面量的依赖 - [ ] 更进一步,移除AggerateValue中对于字典的依赖 \ No newline at end of file From 7dcc51050b1f19637fb94ce7368e850b1efec3ab Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 28 Mar 2024 09:33:10 +0800 Subject: [PATCH 35/39] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8=E6=A8=A1=E6=8B=9F=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Simulator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 2aea543..9f25f9b 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -119,7 +119,8 @@ public Simulator(in JsonElement elem) { } public DateTime Now { get; private set; } - public static DateTime Round(DateTime original) => new(original.Year, original.Month, original.Day, original.Hour, original.Minute, original.Second); + public static DateTime Round(DateTime original) + => new(original.Year, original.Month, original.Day, original.Hour, original.Minute, original.Second, DateTimeKind.Utc); public XoshiroRandom Random { get; set; } ITimeDrivenObject? _interestSource; From df8248c4d4a0d453877401aa7e000563d8c00753 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 28 Mar 2024 09:38:54 +0800 Subject: [PATCH 36/39] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8=E6=97=A0=E6=B3=95=E6=A8=A1=E6=8B=9F?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Simulator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 9f25f9b..33fdf27 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -7,7 +7,7 @@ namespace InfrastSim.TimeDriven; public class Simulator : ISimulator, IJsonSerializable { public Simulator() { - Now = DateTime.UtcNow; + Now = Round(DateTime.UtcNow); Random = new XoshiroRandom(); Facilities[0] = ControlCenter = new(); Facilities[1] = Office = new(); From f069efc932465d96dafacddcf87dccfc06329428 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 28 Mar 2024 10:40:00 +0800 Subject: [PATCH 37/39] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E4=B8=AD=E7=9A=84=E4=B8=80=E4=B8=AAbug?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E8=A7=A3=E5=86=B3=E6=A8=A1=E6=8B=9F=E5=99=A8?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TicksHelper.cs | 1 + InfrastSim/TimeDriven/ManufacturingStation.cs | 4 ++-- InfrastSim/TimeDriven/Simulator.cs | 2 ++ InfrastSim/TimeDriven/TradingStation.cs | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/InfrastSim/TicksHelper.cs b/InfrastSim/TicksHelper.cs index 1ff3978..6d5e579 100644 --- a/InfrastSim/TicksHelper.cs +++ b/InfrastSim/TicksHelper.cs @@ -7,6 +7,7 @@ internal static class TicksHelper { public const int TicksPerDrone = TicksPerMinute * 3; // 3 minute public const int TicksToProduceDrone = TicksPerMinute * 6; // 6 minute public const int TicksToProducerefresh = TicksPerHours * 12; // 12 hours + public const int UnreachableTicks = int.MaxValue >> 1; // to avoid overflow public static int ToSimuTicks(this TimeSpan ts) => (int)(ts.Ticks / TimeSpanTicksPerTick); public static int TotalSeconds(this TimeSpan ts) => (int)(ts.Ticks / TimeSpan.TicksPerSecond); diff --git a/InfrastSim/TimeDriven/ManufacturingStation.cs b/InfrastSim/TimeDriven/ManufacturingStation.cs index 52eaef8..4e3d586 100644 --- a/InfrastSim/TimeDriven/ManufacturingStation.cs +++ b/InfrastSim/TimeDriven/ManufacturingStation.cs @@ -16,7 +16,7 @@ public class ManufacturingStation : FacilityBase, IApplyDrones { public bool CanStoreMore => Product != null && Capacity - CapacityOccupied >= Product.Volume; public Product? Product { get; private set; } public int Progress { get; private set; } - public int RemainTicks => (Product?.ProduceTicks ?? int.MaxValue) - Progress; + public int RemainTicks => (Product?.ProduceTicks ?? TicksHelper.UnreachableTicks) - Progress; public void ChangeProduct(Product newProduct) { if (newProduct != Product) { if (newProduct.RequiredLevel > Level) { @@ -111,7 +111,7 @@ protected override void ReadDerivedContent(JsonElement elem) { } if (elem.TryGetProperty("progress", out var progress)) { if (progress.TryGetDouble(out var value)) { - if (Product != null) Progress = (int)(Product.ProduceTicks * (1 - value)); + if (Product != null) Progress = (int)(Product.ProduceTicks * value); } else { Progress = progress.GetInt32(); } diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 33fdf27..34a0847 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -126,6 +126,7 @@ public static DateTime Round(DateTime original) ITimeDrivenObject? _interestSource; TimeSpan _nextInterest; internal void SetInterest(ITimeDrivenObject o, int seconds) { + Debug.Assert(seconds > 0); if (seconds * TimeSpan.TicksPerSecond < _nextInterest.Ticks) { _interestSource = o; _nextInterest = TimeSpan.FromSeconds(seconds); @@ -153,6 +154,7 @@ void QueryInterest() { } } void SimulateImpl(TimeSpan span) { + Debug.Assert(span.Ticks > 0); var info = new TimeElapsedInfo(Now, Now + span, span); foreach (var facility in Facilities) { facility?.Update(this, info); diff --git a/InfrastSim/TimeDriven/TradingStation.cs b/InfrastSim/TimeDriven/TradingStation.cs index 34e209a..f2dbb77 100644 --- a/InfrastSim/TimeDriven/TradingStation.cs +++ b/InfrastSim/TimeDriven/TradingStation.cs @@ -23,7 +23,7 @@ public enum OrderStrategy { public OrderStrategy Strategy { get; set; } = OrderStrategy.Gold; public Order? CurrentOrder { get; set; } public int Progress { get; private set; } - public int RemainTicks => (CurrentOrder?.ProduceTicks ?? int.MaxValue) - Progress; + public int RemainTicks => (CurrentOrder?.ProduceTicks ?? TicksHelper.UnreachableTicks) - Progress; public event Action? PreGoldOrderPending; public event Action? OnPending; public bool PendingNewOrder(XoshiroRandom random) { @@ -190,7 +190,7 @@ protected override void ReadDerivedContent(JsonElement elem) { } if (elem.TryGetProperty("progress", out var progress)) { if (progress.TryGetDouble(out var value)) { - if (CurrentOrder != null) Progress = (int)(CurrentOrder.ProduceTicks * (1 - value)); + if (CurrentOrder != null) Progress = (int)(CurrentOrder.ProduceTicks * value); } else { Progress = progress.GetInt32(); } From 5399fc2431e297ff8ce3ea5e8e249ac299906f54 Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Thu, 28 Mar 2024 17:54:42 +0800 Subject: [PATCH 38/39] =?UTF-8?q?CDLL=E6=B7=BB=E5=8A=A0ExecuteScript?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSimExports/SimulatorService.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/InfrastSimExports/SimulatorService.cs b/InfrastSimExports/SimulatorService.cs index 4b472ec..def6134 100644 --- a/InfrastSimExports/SimulatorService.cs +++ b/InfrastSimExports/SimulatorService.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Text.Json; using System.Text.Json.Nodes; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace InfrastSim.CDLL; public static class SimulatorService { @@ -219,4 +220,11 @@ public static IntPtr EnumerateGroup(IntPtr data) { EnumerateSharedGCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return EnumerateSharedGCHandle.AddrOfPinnedObject(); } + + [UnmanagedCallersOnly(EntryPoint = "ExecuteScript")] + public static void ExecuteScript(int id, IntPtr pScript) { + var simu = GetSimulator(id); + var script = Marshal.PtrToStringUTF8(pScript) ?? string.Empty; + Helper.ExecuteScript(simu, script); + } } From 03e0fb34dcdda8028d262f31999d816ced2e01fb Mon Sep 17 00:00:00 2001 From: Funny-ppt <1763341376@qq.com> Date: Fri, 29 Mar 2024 18:14:51 +0800 Subject: [PATCH 39/39] =?UTF-8?q?=E9=80=82=E9=85=8Dmower=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- InfrastSim/TimeDriven/Simulator.cs | 10 ----- .../TimeDriven/WebHelper/MowerHelper.cs | 37 +++++++++++-------- InfrastSimTest/SimulatorService.cs | 9 ++++- InfrastSimTest/SimulatorTest.cs | 1 + 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/InfrastSim/TimeDriven/Simulator.cs b/InfrastSim/TimeDriven/Simulator.cs index 34a0847..ef7ad2d 100644 --- a/InfrastSim/TimeDriven/Simulator.cs +++ b/InfrastSim/TimeDriven/Simulator.cs @@ -438,14 +438,4 @@ public Simulator Clone() { using var doc = JsonDocument.Parse(ms); return new Simulator(doc.RootElement); } - - /// - /// 该方法仅供测试使用: - /// 如果没有干员访问这两个属性,在Resolve中就不会产生,但Update中制造站和贸易站始终会访问这两个值, - /// 进而导致出现默认的值,使得序列化、反序列化结果不一致(尽管没有任何影响) - /// - public void EnsurePropExists() { - var p1 = GlobalManufacturingEfficiency; - var p2 = GlobalTradingEfficiency; - } } diff --git a/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs b/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs index 1672a5c..83e05c3 100644 --- a/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs +++ b/InfrastSim/TimeDriven/WebHelper/MowerHelper.cs @@ -14,11 +14,11 @@ public static JsonNode RewriteSimulator(Simulator simu, JsonNode node) { } node["global_properties"] = globalProperties; var facilities = new JsonObject { - ["controlCenter"] = RewriteFacility(node["control-center"]!), - ["office"] = RewriteFacility(node["office"]!), - ["recpetionRoom"] = RewriteFacility(node["reception"]!), - ["training"] = RewriteFacility(node["training"]!), - ["crafting"] = RewriteFacility(node["crafting"]!) + ["controlCenter"] = RewriteFacility(node["control-center"]!, simu), + ["office"] = RewriteFacility(node["office"]!, simu), + ["recpetionRoom"] = RewriteFacility(node["reception"]!, simu), + ["training"] = RewriteFacility(node["training"]!, simu), + ["crafting"] = RewriteFacility(node["crafting"]!, simu) }; for (int i = 0; i < 4; i++) { var fac = node["dormitories"]![i]; @@ -40,7 +40,7 @@ public static JsonNode RewriteSimulator(Simulator simu, JsonNode node) { newfac = RewriteManufacturing(fac, simu); break; case "Power": - newfac = RewritePower(fac); + newfac = RewritePower(fac, simu); break; default: break; @@ -51,7 +51,7 @@ public static JsonNode RewriteSimulator(Simulator simu, JsonNode node) { node["facilities"] = facilities; var operators = new JsonArray(); foreach (var op in node["operators"]!.AsArray()) { - operators.Add(RewriteOperator(op)); + operators.Add(RewriteOperator(op, simu)); } node["operators-mower"] = operators; return node; @@ -74,15 +74,22 @@ public static JsonObject RewriteOrder(JsonNode order, double timeRemain = 0) { newOrder["time_remain"] = (long)timeRemain; return newOrder; } - public static JsonObject? RewriteOperator(JsonNode? op) { + public static JsonObject? RewriteOperator(JsonNode? op, Simulator simu) { if (op == null) return null; + var name = op["name"]!.ToString(); + var simuOp = simu.GetOperator(name); + var newop = new JsonObject { ["name"] = op["name"]!.DeepClone(), ["morale"] = op["mood"]!.DeepClone(), ["efficiency"] = op["efficiency"]!.DeepClone() + ["is_working"] = simuOp.Facility != null && simuOp.Facility is not Dormitory }; + if (simuOp.Facility != null) { + newop["facility-index"] = Array.IndexOf(simu.Facilities, simuOp.Facility); + } if (op["mood"]!.GetValue() > 1e-9) { newop["time"] = op["working-time-seconds"]!.DeepClone(); } else { @@ -99,10 +106,10 @@ public static JsonObject RewriteOrder(JsonNode order, double timeRemain = 0) { return newop; } - public static JsonObject RewriteFacility(JsonNode fac) { + public static JsonObject RewriteFacility(JsonNode fac, Simulator simu) { var ops = new JsonArray(); foreach (var op in fac["operators"]!.AsArray()) { - ops.Add(RewriteOperator(op!)); + ops.Add(RewriteOperator(op!, simu)); } var newfac = new JsonObject { @@ -115,13 +122,13 @@ public static JsonObject RewriteFacility(JsonNode fac) { return newfac; } public static JsonObject RewriteDormitory(JsonNode fac, Simulator simu, int id) { - var newfac = RewriteFacility(fac); + var newfac = RewriteFacility(fac, simu); newfac["name"] = $"宿舍{id + 1}"; newfac["vip"] = simu.GetVipName(id); return newfac; } public static JsonObject RewriteManufacturing(JsonNode fac, Simulator simu) { - var newfac = RewriteFacility(fac); + var newfac = RewriteFacility(fac, simu); newfac["name"] = "制造站"; newfac["base_capacity"] = fac["base-capacity"]!.DeepClone(); @@ -144,7 +151,7 @@ public static JsonObject RewriteTrading(JsonNode fac, Simulator simu) { var cur_order = fac["current-order"]; if (cur_order != null) orders.Add(RewriteOrder(cur_order, fac["remains"]!.GetValue())); - var newfac = RewriteFacility(fac); + var newfac = RewriteFacility(fac, simu); newfac["name"] = "贸易站"; newfac["base_order_limit"] = fac["base-capacity"]!.DeepClone(); newfac["order_limit"] = fac["capacity"]!.DeepClone(); @@ -159,10 +166,10 @@ public static JsonObject RewriteTrading(JsonNode fac, Simulator simu) { return newfac; } - public static JsonObject RewritePower(JsonNode fac) { + public static JsonObject RewritePower(JsonNode fac, Simulator simu) { var ops = new JsonArray(); foreach (var op in fac["operators"]!.AsArray()) { - ops.Add(RewriteOperator(op!)); + ops.Add(RewriteOperator(op!, simu)); } var base_eff = fac["base-efficiency"]!.GetValue() - 1; var newfac = new JsonObject { diff --git a/InfrastSimTest/SimulatorService.cs b/InfrastSimTest/SimulatorService.cs index 357831c..b8bde9e 100644 --- a/InfrastSimTest/SimulatorService.cs +++ b/InfrastSimTest/SimulatorService.cs @@ -11,6 +11,13 @@ public static class SimulatorService { private static int SimuId = 0; private static ConcurrentDictionary Simus = new(); + static void EnsurePropExists(Simulator simu) { + /// 如果没有干员访问这两个属性,在Resolve中就不会产生,但Update中制造站和贸易站始终会访问这两个值, + /// 进而导致出现默认的值,使得序列化、反序列化结果不一致(尽管没有任何影响) + var p1 = simu.GlobalManufacturingEfficiency; + var p2 = simu.GlobalTradingEfficiency; + } + static Simulator GetSimulator(int id) { if (!Simus.TryGetValue(id, out var simulator)) { throw new KeyNotFoundException(); @@ -45,7 +52,7 @@ public static bool Destory(int id) { public static string GetData(int id, bool detailed = true) { var simu = GetSimulator(id); - simu.EnsurePropExists(); + EnsurePropExists(simu); simu.Resolve(); using var ms = new MemoryStream(); using var writer = new Utf8JsonWriter(ms); diff --git a/InfrastSimTest/SimulatorTest.cs b/InfrastSimTest/SimulatorTest.cs index ff64f43..cda38af 100644 --- a/InfrastSimTest/SimulatorTest.cs +++ b/InfrastSimTest/SimulatorTest.cs @@ -1,3 +1,4 @@ +using InfrastSim.TimeDriven; using InfrastSim.TimeDriven.Enumerate; using InfrastSim.Wasm; using System.Text;