diff --git a/Characters/ColdBlue.cs b/Characters/ColdBlue.cs deleted file mode 100644 index 13a6853..0000000 --- a/Characters/ColdBlue.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class ColdBlue : Character - { - public ColdBlue() : base() - { - Name = "Cold Blue"; - FirstName = "冷蓝"; - FirstRoleType = RoleType.Guardian; - STR = 9; - AGI = 3; - INT = 3; - } - } -} diff --git a/Characters/DokyoMayor.cs b/Characters/DokyoMayor.cs deleted file mode 100644 index c7a3aaf..0000000 --- a/Characters/DokyoMayor.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class DokyoMayor : Character - { - public DokyoMayor() : base() - { - Name = "Dokyo Mayor"; - FirstName = "铎京市长"; - FirstRoleType = RoleType.Core; - STR = 4; - AGI = 9; - INT = 1; - } - } -} diff --git a/Characters/Kirayinna.cs b/Characters/Kirayinna.cs deleted file mode 100644 index 481f551..0000000 --- a/Characters/Kirayinna.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class Kirayinna : Character - { - public Kirayinna() : base() - { - Name = "Kirayinna"; - FirstName = "清香"; - FirstRoleType = RoleType.Assistant; - STR = 3; - AGI = 2; - INT = 10; - } - } -} diff --git a/Characters/MagicGirl.cs b/Characters/MagicGirl.cs deleted file mode 100644 index e6f40ba..0000000 --- a/Characters/MagicGirl.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class MagicGirl : Character - { - public MagicGirl() : base() - { - Name = "Magic Girl"; - FirstName = "魔法少女"; - FirstRoleType = RoleType.Core; - STR = 3; - AGI = 8; - INT = 4; - } - } -} diff --git a/Characters/NanGanYu.cs b/Characters/NanGanYu.cs deleted file mode 100644 index 1614439..0000000 --- a/Characters/NanGanYu.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class NanGanYu : Character - { - public NanGanYu() : base() - { - Name = "NanGanYu"; - FirstName = "男甘雨"; - FirstRoleType = RoleType.Logistics; - STR = 4; - AGI = 2; - INT = 9; - } - } -} diff --git a/Characters/NiuNan.cs b/Characters/NiuNan.cs deleted file mode 100644 index 914e951..0000000 --- a/Characters/NiuNan.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class NiuNan : Character - { - public NiuNan() : base() - { - Name = "NiuNan"; - FirstName = "牛腩"; - FirstRoleType = RoleType.Logistics; - STR = 0; - AGI = 0; - INT = 15; - } - } -} diff --git a/Characters/Oshima.cs b/Characters/Oshima.cs deleted file mode 100644 index d0404e8..0000000 --- a/Characters/Oshima.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class Oshima : Character - { - public Oshima() : base() - { - Name = "Oshima"; - FirstName = "大島シヤ"; - FirstRoleType = RoleType.Vanguard; - STR = 15; - AGI = 5; - INT = 0; - } - } -} diff --git a/Characters/QWQAQW.cs b/Characters/QWQAQW.cs deleted file mode 100644 index 5e7f0f0..0000000 --- a/Characters/QWQAQW.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class QWQAQW : Character - { - public QWQAQW() : base() - { - Name = "QWQAQW"; - FirstName = "脑婆"; - FirstRoleType = RoleType.Core; - STR = 3; - AGI = 10; - INT = 2; - } - } -} diff --git a/Characters/ThomasYang.cs b/Characters/ThomasYang.cs deleted file mode 100644 index 6428f9e..0000000 --- a/Characters/ThomasYang.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class ThomasYang : Character - { - public ThomasYang() : base() - { - Name = "Thomas Yang"; - FirstName = "吖养"; - FirstRoleType = RoleType.Guardian; - STR = 8; - AGI = 1; - INT = 6; - } - } -} diff --git a/Characters/ZzxToT.cs b/Characters/ZzxToT.cs deleted file mode 100644 index bfe92c5..0000000 --- a/Characters/ZzxToT.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class ZzxToT : Character - { - public ZzxToT() : base() - { - Name = "ZzxToT"; - FirstName = "趣多多"; - FirstRoleType = RoleType.Core; - STR = 7; - AGI = 7; - INT = 1; - } - } -} diff --git a/Characters/dddovo.cs b/Characters/dddovo.cs deleted file mode 100644 index 8653321..0000000 --- a/Characters/dddovo.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Milimoe.FunGame.Core.Entity; -using Milimoe.FunGame.Core.Library.Constant; - -namespace Milimoe.FunGame.GameMode.OfficialStandard.Characters -{ - public class dddovo : Character - { - public dddovo() : base() - { - Name = "dddovo"; - FirstName = "绿拱门"; - FirstRoleType = RoleType.Core; - STR = 5; - AGI = 10; - INT = 0; - } - } -} diff --git a/OshimaCustomizedMode.sln b/OshimaCustomizedMode.sln deleted file mode 100644 index 3efef0b..0000000 --- a/OshimaCustomizedMode.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.8.34330.188 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OshimaCustomizedMode", "OshimaCustomizedMode.csproj", "{497E99F9-7EA4-498C-90C5-B5751B47B2BE}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B3F190BD-B445-4D80-99D7-5D2B59D038CA} - EndGlobalSection -EndGlobal diff --git a/OshimaGameModule.sln b/OshimaGameModule.sln new file mode 100644 index 0000000..f4103b8 --- /dev/null +++ b/OshimaGameModule.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OshimaModules", "OshimaModules\OshimaModules.csproj", "{497E99F9-7EA4-498C-90C5-B5751B47B2BE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OshimaMaps", "OshimaMaps\OshimaMaps.csproj", "{27847422-7671-4DF8-95EC-975A2E2F5631}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OshimaModes", "OshimaModes\OshimaModes.csproj", "{74922E11-458E-4A91-8D11-BEC9F7758EEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OshimaServers", "OshimaServers\OshimaServers.csproj", "{E8C696E0-96E4-45C3-8CB4-A02145179590}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {497E99F9-7EA4-498C-90C5-B5751B47B2BE}.Release|Any CPU.Build.0 = Release|Any CPU + {27847422-7671-4DF8-95EC-975A2E2F5631}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27847422-7671-4DF8-95EC-975A2E2F5631}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27847422-7671-4DF8-95EC-975A2E2F5631}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27847422-7671-4DF8-95EC-975A2E2F5631}.Release|Any CPU.Build.0 = Release|Any CPU + {74922E11-458E-4A91-8D11-BEC9F7758EEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74922E11-458E-4A91-8D11-BEC9F7758EEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74922E11-458E-4A91-8D11-BEC9F7758EEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74922E11-458E-4A91-8D11-BEC9F7758EEB}.Release|Any CPU.Build.0 = Release|Any CPU + {E8C696E0-96E4-45C3-8CB4-A02145179590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8C696E0-96E4-45C3-8CB4-A02145179590}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8C696E0-96E4-45C3-8CB4-A02145179590}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8C696E0-96E4-45C3-8CB4-A02145179590}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B3F190BD-B445-4D80-99D7-5D2B59D038CA} + EndGlobalSection +EndGlobal diff --git a/OshimaMaps/FastAutoMap.cs b/OshimaMaps/FastAutoMap.cs new file mode 100644 index 0000000..40a9ef7 --- /dev/null +++ b/OshimaMaps/FastAutoMap.cs @@ -0,0 +1,24 @@ +using Milimoe.FunGame.Core.Library.Common.Addon; +using Oshima.FunGame.OshimaModules; + +namespace Oshima.FunGame.OshimaMaps +{ + public class FastAutoMap : GameMap + { + public override string Name => OshimaGameModuleConstant.FastAutoMap; + + public override string Description => OshimaGameModuleConstant.Description; + + public override string Version => OshimaGameModuleConstant.Version; + + public override string Author => OshimaGameModuleConstant.Author; + + public override float Length => 6; + + public override float Width => 6; + + public override float Height => 3; + + public override float Size => 6; + } +} diff --git a/OshimaMaps/OshimaMaps.csproj b/OshimaMaps/OshimaMaps.csproj new file mode 100644 index 0000000..b9104ae --- /dev/null +++ b/OshimaMaps/OshimaMaps.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + enable + enable + Oshima Studios + Oshima Studios + ..\bin\ + Oshima.FunGame.$(MSBuildProjectName.Replace(" ", "_")) + + + + + + + + + ..\..\FunGame.Core\bin\Debug\net8.0\FunGame.Core.dll + + + + diff --git a/OshimaModes/FastAuto.cs b/OshimaModes/FastAuto.cs new file mode 100644 index 0000000..384415c --- /dev/null +++ b/OshimaModes/FastAuto.cs @@ -0,0 +1,65 @@ +using Milimoe.FunGame.Core.Api.Transmittal; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Interface; +using Milimoe.FunGame.Core.Library.Common.Addon; +using Milimoe.FunGame.Core.Library.Common.Event; +using Milimoe.FunGame.Core.Library.Constant; +using Milimoe.FunGame.Core.Model; +using Oshima.FunGame.OshimaModules; + +namespace Oshima.FunGame.OshimaModes +{ + public class FastAuto : GameModule, IGamingUpdateInfoEvent + { + public override string Name => OshimaGameModuleConstant.FastAuto; + public override string Description => OshimaGameModuleConstant.Description; + public override string Version => OshimaGameModuleConstant.Version; + public override string Author => OshimaGameModuleConstant.Author; + public override string DefaultMap => OshimaGameModuleConstant.FastAutoMap; + public override GameModuleDepend GameModuleDepend => OshimaGameModuleConstant.GameModuleDepend; + public override RoomType RoomType => RoomType.FastAuto; + public override bool HideMain => false; + + public override void StartGame(Gaming instance, params object[] args) + { + try + { + DataRequest request = Controller.NewDataRequest(GamingType.Connect); + request.AddRequestData("un", Session.LoginUserName); + request.SendRequest(); + } + catch (Exception e) + { + TXTHelper.AppendErrorLog(e.ToString()); + } + } + + public override void StartUI(params object[] args) + { + if (Application.MessageLoop) + { + FastAutoUI f = new(); + f.Invoke(f.Show); + } + else + { + ApplicationConfiguration.Initialize(); + Application.Run(new FastAutoUI()); + } + } + + + public void GamingUpdateInfoEvent(object sender, GamingEventArgs e, Dictionary data) + { + try + { + string msg = (DataRequest.GetDictionaryJsonObject(data, "msg") ?? "").Trim(); + if (msg != "") Controller.WriteLine(msg); + } + catch (Exception ex) + { + TXTHelper.AppendErrorLog(ex.ToString()); + } + } + } +} diff --git a/OshimaModes/FastAutoUI.Designer.cs b/OshimaModes/FastAutoUI.Designer.cs new file mode 100644 index 0000000..1567e73 --- /dev/null +++ b/OshimaModes/FastAutoUI.Designer.cs @@ -0,0 +1,187 @@ +using System.Windows.Forms; + +namespace Oshima.FunGame.OshimaModes +{ + partial class FastAutoUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + mainTableLayoutPanel = new TableLayoutPanel(); + flowLayoutPanel6 = new FlowLayoutPanel(); + flowLayoutPanel4 = new FlowLayoutPanel(); + flowLayoutPanel3 = new FlowLayoutPanel(); + leftTableLayoutPanel = new TableLayoutPanel(); + rightTableLayoutPanel = new TableLayoutPanel(); + richTextBox = new RichTextBox(); + flowLayoutPanel1 = new FlowLayoutPanel(); + flowLayoutPanel2 = new FlowLayoutPanel(); + flowLayoutPanel5 = new FlowLayoutPanel(); + mainTableLayoutPanel.SuspendLayout(); + SuspendLayout(); + // + // mainTableLayoutPanel + // + mainTableLayoutPanel.ColumnCount = 3; + mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel6, 2, 2); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel4, 2, 0); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel3, 0, 0); + mainTableLayoutPanel.Controls.Add(leftTableLayoutPanel, 0, 1); + mainTableLayoutPanel.Controls.Add(rightTableLayoutPanel, 2, 1); + mainTableLayoutPanel.Controls.Add(richTextBox, 1, 1); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel1, 1, 2); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel2, 1, 0); + mainTableLayoutPanel.Controls.Add(flowLayoutPanel5, 0, 2); + mainTableLayoutPanel.Dock = DockStyle.Fill; + mainTableLayoutPanel.Location = new Point(0, 0); + mainTableLayoutPanel.Name = "mainTableLayoutPanel"; + mainTableLayoutPanel.RowCount = 3; + mainTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 10F)); + mainTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 70F)); + mainTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 20F)); + mainTableLayoutPanel.Size = new Size(1688, 943); + mainTableLayoutPanel.TabIndex = 0; + // + // flowLayoutPanel6 + // + flowLayoutPanel6.Dock = DockStyle.Fill; + flowLayoutPanel6.Location = new Point(1269, 757); + flowLayoutPanel6.Name = "flowLayoutPanel6"; + flowLayoutPanel6.Size = new Size(416, 183); + flowLayoutPanel6.TabIndex = 8; + // + // flowLayoutPanel4 + // + flowLayoutPanel4.Dock = DockStyle.Fill; + flowLayoutPanel4.Location = new Point(1269, 3); + flowLayoutPanel4.Name = "flowLayoutPanel4"; + flowLayoutPanel4.Size = new Size(416, 88); + flowLayoutPanel4.TabIndex = 6; + // + // flowLayoutPanel3 + // + flowLayoutPanel3.Dock = DockStyle.Fill; + flowLayoutPanel3.Location = new Point(3, 3); + flowLayoutPanel3.Name = "flowLayoutPanel3"; + flowLayoutPanel3.Size = new Size(416, 88); + flowLayoutPanel3.TabIndex = 5; + // + // leftTableLayoutPanel + // + leftTableLayoutPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + leftTableLayoutPanel.ColumnCount = 2; + leftTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + leftTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + leftTableLayoutPanel.Location = new Point(3, 97); + leftTableLayoutPanel.Name = "leftTableLayoutPanel"; + leftTableLayoutPanel.RowCount = 3; + leftTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + leftTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + leftTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + leftTableLayoutPanel.Size = new Size(416, 654); + leftTableLayoutPanel.TabIndex = 0; + // + // rightTableLayoutPanel + // + rightTableLayoutPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + rightTableLayoutPanel.ColumnCount = 2; + rightTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + rightTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + rightTableLayoutPanel.Location = new Point(1269, 97); + rightTableLayoutPanel.Name = "rightTableLayoutPanel"; + rightTableLayoutPanel.RowCount = 3; + rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33F)); + rightTableLayoutPanel.Size = new Size(416, 654); + rightTableLayoutPanel.TabIndex = 1; + // + // richTextBox + // + richTextBox.Dock = DockStyle.Fill; + richTextBox.Location = new Point(425, 97); + richTextBox.Name = "richTextBox"; + richTextBox.ReadOnly = true; + richTextBox.Size = new Size(838, 654); + richTextBox.TabIndex = 2; + richTextBox.Text = ""; + // + // flowLayoutPanel1 + // + flowLayoutPanel1.Dock = DockStyle.Fill; + flowLayoutPanel1.Location = new Point(425, 757); + flowLayoutPanel1.Name = "flowLayoutPanel1"; + flowLayoutPanel1.Size = new Size(838, 183); + flowLayoutPanel1.TabIndex = 3; + // + // flowLayoutPanel2 + // + flowLayoutPanel2.Dock = DockStyle.Fill; + flowLayoutPanel2.Location = new Point(425, 3); + flowLayoutPanel2.Name = "flowLayoutPanel2"; + flowLayoutPanel2.Size = new Size(838, 88); + flowLayoutPanel2.TabIndex = 4; + // + // flowLayoutPanel5 + // + flowLayoutPanel5.Dock = DockStyle.Fill; + flowLayoutPanel5.Location = new Point(3, 757); + flowLayoutPanel5.Name = "flowLayoutPanel5"; + flowLayoutPanel5.Size = new Size(416, 183); + flowLayoutPanel5.TabIndex = 7; + // + // FastAutoUI + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1688, 943); + Controls.Add(mainTableLayoutPanel); + FormBorderStyle = FormBorderStyle.FixedSingle; + MaximizeBox = false; + Name = "FastAutoUI"; + Text = "游戏界面"; + mainTableLayoutPanel.ResumeLayout(false); + ResumeLayout(false); + } + + private System.Windows.Forms.TableLayoutPanel mainTableLayoutPanel; + private System.Windows.Forms.TableLayoutPanel leftTableLayoutPanel; + private System.Windows.Forms.TableLayoutPanel rightTableLayoutPanel; + private System.Windows.Forms.RichTextBox richTextBox; + + #endregion + + private FlowLayoutPanel flowLayoutPanel4; + private FlowLayoutPanel flowLayoutPanel3; + private FlowLayoutPanel flowLayoutPanel1; + private FlowLayoutPanel flowLayoutPanel2; + private FlowLayoutPanel flowLayoutPanel6; + private FlowLayoutPanel flowLayoutPanel5; + } +} diff --git a/OshimaModes/FastAutoUI.cs b/OshimaModes/FastAutoUI.cs new file mode 100644 index 0000000..67b6ee7 --- /dev/null +++ b/OshimaModes/FastAutoUI.cs @@ -0,0 +1,57 @@ +namespace Oshima.FunGame.OshimaModes +{ + public partial class FastAutoUI : Form + { + public FastAutoUI() + { + InitializeComponent(); + + // Ӹ + AddPlayers(7); + } + + // ̬Ҹ + private void AddPlayers(int playerCount) + { + int leftIndex = 0; // Ҽ + int rightIndex = 0; // ҲżҼ + + for (int i = 1; i <= playerCount; i++) + { + // ÿButtonʾ + CharacterStatus playerSlot = new(); + + if (i % 2 == 1) // ң + { + AddToLeftPanel(playerSlot, leftIndex); + leftIndex++; + } + else // żңҲ + { + AddToRightPanel(playerSlot, rightIndex); + rightIndex++; + } + } + } + + // ҵTableLayoutPanel + private void AddToLeftPanel(Control control, int index) + { + int col = index / 3; // ÿ3 + int row = index % 3; // кŴ02 + leftTableLayoutPanel.Controls.Add(control, col, row); + } + + // żҵҲTableLayoutPanel + private void AddToRightPanel(Control control, int index) + { + // żҵй + // - һ: Player 10, Player 11, Player 12 (index3ʼ) + // - ڶ: Player 2, Player 4, Player 6 (index0ʼ) + + int col = (index >= 3) ? 0 : 1; // 3 λҵżӦڵһУڵڶ + int row = index % 3; // кŴ02 + rightTableLayoutPanel.Controls.Add(control, col, row); + } + } +} diff --git a/OshimaModes/FastAutoUI.resx b/OshimaModes/FastAutoUI.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/OshimaModes/FastAutoUI.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OshimaModes/OshimaModes.csproj b/OshimaModes/OshimaModes.csproj new file mode 100644 index 0000000..388426f --- /dev/null +++ b/OshimaModes/OshimaModes.csproj @@ -0,0 +1,40 @@ + + + + WinExe + net8.0-windows + enable + true + enable + ..\bin\ + Oshima.FunGame.$(MSBuildProjectName.Replace(" ", "_")) + Oshima Studios + + + + + + + + + + ..\..\FunGame.Core\bin\Debug\net8.0\FunGame.Core.dll + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/OshimaModes/Program.cs b/OshimaModes/Program.cs new file mode 100644 index 0000000..8fa1b11 --- /dev/null +++ b/OshimaModes/Program.cs @@ -0,0 +1,17 @@ +namespace Oshima.FunGame.OshimaModes +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new FastAutoUI()); + } + } +} \ No newline at end of file diff --git a/OshimaModes/Properties/Resources.Designer.cs b/OshimaModes/Properties/Resources.Designer.cs new file mode 100644 index 0000000..c4a9dbf --- /dev/null +++ b/OshimaModes/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Oshima.FunGame.OshimaModes.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Oshima.FunGame.OshimaModes.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/OshimaModes/Properties/Resources.resx b/OshimaModes/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/OshimaModes/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OshimaModes/UserControsl/CharacterStatus.Designer.cs b/OshimaModes/UserControsl/CharacterStatus.Designer.cs new file mode 100644 index 0000000..5c41653 --- /dev/null +++ b/OshimaModes/UserControsl/CharacterStatus.Designer.cs @@ -0,0 +1,359 @@ +namespace Oshima.FunGame.OshimaModes +{ + partial class CharacterStatus + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CharacterStatus)); + CharacterName = new Label(); + HPBar = new CustomProgressBar(); + MPBar = new CustomProgressBar(); + CharacterAvatar = new PictureBox(); + EPBar = new CustomProgressBar(); + EquipSlots = new TableLayoutPanel(); + pictureBox2 = new PictureBox(); + pictureBox3 = new PictureBox(); + pictureBox4 = new PictureBox(); + pictureBox5 = new PictureBox(); + pictureBox6 = new PictureBox(); + pictureBox7 = new PictureBox(); + SkillSlots = new TableLayoutPanel(); + pictureBox8 = new PictureBox(); + pictureBox9 = new PictureBox(); + pictureBox10 = new PictureBox(); + pictureBox11 = new PictureBox(); + pictureBox1 = new PictureBox(); + pictureBox12 = new PictureBox(); + pictureBox13 = new PictureBox(); + pictureBox14 = new PictureBox(); + ((System.ComponentModel.ISupportInitialize)CharacterAvatar).BeginInit(); + EquipSlots.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox6).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox7).BeginInit(); + SkillSlots.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox8).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox9).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox10).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox11).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox12).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox13).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox14).BeginInit(); + SuspendLayout(); + // + // CharacterName + // + CharacterName.Dock = DockStyle.Top; + CharacterName.Font = new Font("Microsoft YaHei UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 134); + CharacterName.Location = new Point(0, 0); + CharacterName.Name = "CharacterName"; + CharacterName.Size = new Size(308, 34); + CharacterName.TabIndex = 0; + CharacterName.Text = "角色名称"; + CharacterName.TextAlign = ContentAlignment.MiddleCenter; + // + // HPBar + // + HPBar.BorderStyle = BorderStyle.FixedSingle; + HPBar.Dock = DockStyle.Bottom; + HPBar.Location = new Point(0, 276); + HPBar.Maximum = 1000D; + HPBar.Name = "HPBar"; + HPBar.ProgressColor = Color.PaleVioletRed; + HPBar.Size = new Size(308, 20); + HPBar.TabIndex = 1; + HPBar.Value = 325D; + // + // MPBar + // + MPBar.BorderStyle = BorderStyle.FixedSingle; + MPBar.Dock = DockStyle.Bottom; + MPBar.Location = new Point(0, 296); + MPBar.Maximum = 142D; + MPBar.Name = "MPBar"; + MPBar.ProgressColor = Color.SteelBlue; + MPBar.Size = new Size(308, 20); + MPBar.TabIndex = 2; + MPBar.Value = 24D; + // + // CharacterAvatar + // + CharacterAvatar.Dock = DockStyle.Left; + CharacterAvatar.Image = (Image)resources.GetObject("CharacterAvatar.Image"); + CharacterAvatar.Location = new Point(0, 34); + CharacterAvatar.Name = "CharacterAvatar"; + CharacterAvatar.Size = new Size(181, 182); + CharacterAvatar.SizeMode = PictureBoxSizeMode.Zoom; + CharacterAvatar.TabIndex = 3; + CharacterAvatar.TabStop = false; + // + // EPBar + // + EPBar.BorderStyle = BorderStyle.FixedSingle; + EPBar.Dock = DockStyle.Bottom; + EPBar.Location = new Point(0, 316); + EPBar.Maximum = 200D; + EPBar.Name = "EPBar"; + EPBar.ProgressColor = Color.LightGoldenrodYellow; + EPBar.Size = new Size(308, 21); + EPBar.TabIndex = 4; + EPBar.Value = 54D; + // + // EquipSlots + // + EquipSlots.ColumnCount = 2; + EquipSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + EquipSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); + EquipSlots.Controls.Add(pictureBox2, 0, 0); + EquipSlots.Controls.Add(pictureBox3, 1, 0); + EquipSlots.Controls.Add(pictureBox4, 0, 1); + EquipSlots.Controls.Add(pictureBox5, 1, 1); + EquipSlots.Controls.Add(pictureBox6, 0, 2); + EquipSlots.Controls.Add(pictureBox7, 1, 2); + EquipSlots.Dock = DockStyle.Right; + EquipSlots.Location = new Point(180, 34); + EquipSlots.Name = "EquipSlots"; + EquipSlots.RowCount = 3; + EquipSlots.RowStyles.Add(new RowStyle(SizeType.Percent, 33.3333321F)); + EquipSlots.RowStyles.Add(new RowStyle(SizeType.Percent, 33.3333321F)); + EquipSlots.RowStyles.Add(new RowStyle(SizeType.Percent, 33.3333321F)); + EquipSlots.Size = new Size(128, 182); + EquipSlots.TabIndex = 8; + // + // pictureBox2 + // + pictureBox2.Image = (Image)resources.GetObject("pictureBox2.Image"); + pictureBox2.Location = new Point(3, 3); + pictureBox2.Name = "pictureBox2"; + pictureBox2.Size = new Size(58, 50); + pictureBox2.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox2.TabIndex = 0; + pictureBox2.TabStop = false; + // + // pictureBox3 + // + pictureBox3.Image = (Image)resources.GetObject("pictureBox3.Image"); + pictureBox3.Location = new Point(67, 3); + pictureBox3.Name = "pictureBox3"; + pictureBox3.Size = new Size(58, 50); + pictureBox3.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox3.TabIndex = 1; + pictureBox3.TabStop = false; + // + // pictureBox4 + // + pictureBox4.Image = (Image)resources.GetObject("pictureBox4.Image"); + pictureBox4.Location = new Point(3, 63); + pictureBox4.Name = "pictureBox4"; + pictureBox4.Size = new Size(58, 50); + pictureBox4.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox4.TabIndex = 2; + pictureBox4.TabStop = false; + // + // pictureBox5 + // + pictureBox5.Image = (Image)resources.GetObject("pictureBox5.Image"); + pictureBox5.Location = new Point(67, 63); + pictureBox5.Name = "pictureBox5"; + pictureBox5.Size = new Size(58, 50); + pictureBox5.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox5.TabIndex = 3; + pictureBox5.TabStop = false; + // + // pictureBox6 + // + pictureBox6.Image = (Image)resources.GetObject("pictureBox6.Image"); + pictureBox6.Location = new Point(3, 123); + pictureBox6.Name = "pictureBox6"; + pictureBox6.Size = new Size(58, 50); + pictureBox6.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox6.TabIndex = 4; + pictureBox6.TabStop = false; + // + // pictureBox7 + // + pictureBox7.Image = (Image)resources.GetObject("pictureBox7.Image"); + pictureBox7.Location = new Point(67, 123); + pictureBox7.Name = "pictureBox7"; + pictureBox7.Size = new Size(58, 50); + pictureBox7.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox7.TabIndex = 5; + pictureBox7.TabStop = false; + // + // SkillSlots + // + SkillSlots.ColumnCount = 4; + SkillSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + SkillSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + SkillSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + SkillSlots.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F)); + SkillSlots.Controls.Add(pictureBox1, 0, 0); + SkillSlots.Controls.Add(pictureBox12, 1, 0); + SkillSlots.Controls.Add(pictureBox13, 2, 0); + SkillSlots.Controls.Add(pictureBox14, 3, 0); + SkillSlots.Dock = DockStyle.Bottom; + SkillSlots.Location = new Point(0, 216); + SkillSlots.Name = "SkillSlots"; + SkillSlots.RowCount = 1; + SkillSlots.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); + SkillSlots.Size = new Size(308, 60); + SkillSlots.TabIndex = 9; + // + // pictureBox8 + // + pictureBox8.Location = new Point(0, 0); + pictureBox8.Name = "pictureBox8"; + pictureBox8.Size = new Size(100, 50); + pictureBox8.TabIndex = 0; + pictureBox8.TabStop = false; + // + // pictureBox9 + // + pictureBox9.Location = new Point(0, 0); + pictureBox9.Name = "pictureBox9"; + pictureBox9.Size = new Size(100, 50); + pictureBox9.TabIndex = 0; + pictureBox9.TabStop = false; + // + // pictureBox10 + // + pictureBox10.Location = new Point(0, 0); + pictureBox10.Name = "pictureBox10"; + pictureBox10.Size = new Size(100, 50); + pictureBox10.TabIndex = 0; + pictureBox10.TabStop = false; + // + // pictureBox11 + // + pictureBox11.Location = new Point(0, 0); + pictureBox11.Name = "pictureBox11"; + pictureBox11.Size = new Size(100, 50); + pictureBox11.TabIndex = 0; + pictureBox11.TabStop = false; + // + // pictureBox1 + // + pictureBox1.Image = (Image)resources.GetObject("pictureBox1.Image"); + pictureBox1.Location = new Point(3, 3); + pictureBox1.Name = "pictureBox1"; + pictureBox1.Size = new Size(71, 50); + pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox1.TabIndex = 0; + pictureBox1.TabStop = false; + // + // pictureBox12 + // + pictureBox12.Image = (Image)resources.GetObject("pictureBox12.Image"); + pictureBox12.Location = new Point(80, 3); + pictureBox12.Name = "pictureBox12"; + pictureBox12.Size = new Size(71, 50); + pictureBox12.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox12.TabIndex = 1; + pictureBox12.TabStop = false; + // + // pictureBox13 + // + pictureBox13.Image = (Image)resources.GetObject("pictureBox13.Image"); + pictureBox13.Location = new Point(157, 3); + pictureBox13.Name = "pictureBox13"; + pictureBox13.Size = new Size(71, 50); + pictureBox13.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox13.TabIndex = 2; + pictureBox13.TabStop = false; + // + // pictureBox14 + // + pictureBox14.Image = (Image)resources.GetObject("pictureBox14.Image"); + pictureBox14.Location = new Point(234, 3); + pictureBox14.Name = "pictureBox14"; + pictureBox14.Size = new Size(71, 50); + pictureBox14.SizeMode = PictureBoxSizeMode.Zoom; + pictureBox14.TabIndex = 3; + pictureBox14.TabStop = false; + // + // CharacterStatus + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(CharacterAvatar); + Controls.Add(EquipSlots); + Controls.Add(SkillSlots); + Controls.Add(CharacterName); + Controls.Add(HPBar); + Controls.Add(MPBar); + Controls.Add(EPBar); + Name = "CharacterStatus"; + Size = new Size(308, 337); + ((System.ComponentModel.ISupportInitialize)CharacterAvatar).EndInit(); + EquipSlots.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox3).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox4).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox5).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox6).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox7).EndInit(); + SkillSlots.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)pictureBox8).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox9).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox10).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox11).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox12).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox13).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox14).EndInit(); + ResumeLayout(false); + } + + #endregion + + private Label CharacterName; + private CustomProgressBar HPBar; + private CustomProgressBar MPBar; + private PictureBox CharacterAvatar; + private CustomProgressBar EPBar; + private TableLayoutPanel EquipSlots; + private PictureBox pictureBox2; + private PictureBox pictureBox3; + private PictureBox pictureBox4; + private PictureBox pictureBox5; + private PictureBox pictureBox6; + private PictureBox pictureBox7; + private TableLayoutPanel SkillSlots; + private PictureBox pictureBox8; + private PictureBox pictureBox9; + private PictureBox pictureBox10; + private PictureBox pictureBox11; + private PictureBox pictureBox1; + private PictureBox pictureBox12; + private PictureBox pictureBox13; + private PictureBox pictureBox14; + } +} diff --git a/OshimaModes/UserControsl/CharacterStatus.cs b/OshimaModes/UserControsl/CharacterStatus.cs new file mode 100644 index 0000000..faafe5f --- /dev/null +++ b/OshimaModes/UserControsl/CharacterStatus.cs @@ -0,0 +1,10 @@ +namespace Oshima.FunGame.OshimaModes +{ + public partial class CharacterStatus : UserControl + { + public CharacterStatus() + { + InitializeComponent(); + } + } +} diff --git a/OshimaModes/UserControsl/CharacterStatus.resx b/OshimaModes/UserControsl/CharacterStatus.resx new file mode 100644 index 0000000..d617629 --- /dev/null +++ b/OshimaModes/UserControsl/CharacterStatus.resx @@ -0,0 +1,1218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + YR5QS5WBV+kCYAAE6niX5LzNF4lk0rlGKGJ9RiIr/9k= + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + AQEBAAAAAAAAAAEAAgMEBQYHCAkKC//EALURAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZx + gZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp + 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJ + WWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AvzJ5p0vyppHlu3g8t6TfTXel2tzJ + Nc2cTmQmL99+9yuIv3fb8WycgPexX/lcNv8A9SdoP/SL/blngtP5kd34+SoPzhiLAr5N8vkgfFSz/twH + GBzIZQyyl9MZE1vSMk/MlRbK58p+XwJSCB9S/eUHf7X2cwTqqPDX4/W9Nh7B48fGZEAVtXTv+r6VGP8A + MQSzpAvlfQk9VxRvqe/xf7L5YBqAY3XL8frZ5+wpY58Jnsao13/539VB3H5nJHPLE3ljQ/gciotOvFv9 + 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 + oKcv3X2MozyEZ8I5kX+zbl1/ouRpcEpYjkkajGQF7bX1359P6Tz7zF5E1DTzJbLHCsDhH5tPz5f8k81m + qmRQkPk7/sYwjPxIylxbjlVf7JhOo21namIScLOUGgi/34O/0fqzHxRnksDfb5d3x+/d6TLrIYTGUpAG + 6j5jqP6v+59LH7Aky6r7Wjj9WdDpRWKHveF9pJmXaGXyAH+ximmvJbawmntHf20YtLKC3/fSen9n/JzI + hIjof7Of3uizwE+oFX+LSb/Dic+P6Tsvn6uWeL5Fo/LD+cG28toP+lpZ/wDI3B43kUHT+YR2m2+p6aZD + p3mCGzMwpJ6NyYuY+jAZ3ziW2EKuph6tp35yxRrpM2rWNlqeraXEbePUjqBieQSp6cnrfuT2zGniEpRk + QbjdfEU5mLUyhCeMECMzGxe+xsIPzL+cd1qjq9ja6ZaS8eEjzz/W2I/yTwtovwyEtMJSs3+O/emePVmE + ABXPb9np4nmdzFPd3ctzfanbXc0tKytLQgjpTYbb/LJTwekCFxr7f2+fNzND2n4cpSzRGa6q6BiR9Nen + 6d/p+hakcNqt5M1zDJ68DRqsUlT0XLMWPhjGPd+suJ2lrBqM881CPFW3P+GL/9k= + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + 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 + IssEiIkUlaMR4HxwEkkbMoREAdxuH//Z + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + AQEBAAAAAAAAAAEAAgMEBQYHCAkKC//EALURAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZx + gZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp + 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJ + WWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8Ab5l80aX5U0jy3bw+WtJvprvS7S5k + nuLOIly0R9X971/lyEBxe77fizmRH3n9H4LGR+b8B/6Y7Qf+kX+3LPB/FMY5ien4+SuPzbgrz/wf5f8A + +kL+3D4B73JjXmiV/MWZ/gPk3QU9T7P+h/25kR7Omf7P2sxij1LNLW2gGnLc6lpGj2M3D1ZbeHSPrXpe + p/cRTfvv76T7fpYRoDKVRkPu95G/Id7gajUjELo199f8V9K+0t9C1CO+ks7fS5I7H/en/cFw9P8A5GXm + GXZU4kWRv+OjVj7RhO6v08+n+6SWK7sTpl9eXOnaVbxwNKlmsmkpyn9D++9H/S8n/JJvaX7L5WjL2iIb + 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 + 2wgIg0RuH//Z + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + AQEBAAAAAAAAAAEAAgMEBQYHCAkKC//EALURAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZx + gZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp + 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJ + WWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AkVtbafbaPpEFtomjyyLpVhfTS3Fj + FLLJ9Yi/ef8AJnNbrNYcNULv8Fz9NgGXntX4C2ya0nb05tG0GBO7/ovn6b/8jsxcfanEfpod97OTPQGI + 2lZ7uWyO806Nf6XpK6ro3l7y/rixf7128em+nIkfb/d0vq5uIxB36fd97rZTINb/AK/9y8rf83o+Dp/g + /QP+kT+3J+E4/wCY8vtQ7fmzGf8Apk9C/wCkX+3D4KPzPktf82OfXyvoY/6Nf7cfAX815Kf/ACtT93w/ + wxolPH6oP64+D5r+a8vtR1n5si1rSdVtpNI0y2dbS4cSwWlGjpQxCKXn8PV8rlARI/H6W2M+MEDuP45P + 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 + bj0zH/v1RQPnO9q9iR1cxMHgPXa77j0dzo9ecMeA1IDlvuP6P8SI88+fR5kAmkjhto4YJ4be3huPWAEv + p8Ph4f8AFWZHZnZX5aUiZcXFXSq4b/pebRqtWMkQNgR53xd/8L//2Q== + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + AQEBAAAAAAAAAAEAAgMEBQYHCAkKC//EALURAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZx + gZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp + 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJ + WWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AW1PWLLQrLyzp9n5Z0a8lvNJtbuW4 + u7RGkMjJQ1Yca1413yq3MwYPENBPNC0zXdYtXmtvKXl4Km/+8Qb6P7wZWZHucnLo/DoGSR6nrt5YTMs/ + lLy9zj+Ej6kB/wAbYRK2Z7ONXaTr55vHjYR+S9AeOvD1PqY6/PlkrDhHDK6ATeL/ABPPpL6rD5M0JrSP + 4nl+qDan+yyIlf4/a2y01Gr3Y5H52urm7+rR+VdCDk0FLTp/w2SNAWwhp5ynw0zzTfJ/mm+svX/QOgwx + OKhzZ/qPqjKRl8m/JpeE1xbsT8xtc2Z1bRb/AEvSYJY7CW4S4tbRVkFAKUYs9Op365ZCV0WrUYDjFE3Y + P45lU12eL9K+TzIPgTQbQH7myTd2eam9q/Ly4K25itE5I/4ZCUiDs5GtiDvJiX5j+W531Ys0W8lCQvQj + KxY2Lk6aQnDZhWrabe2dYrWH0beQ14bmgHauSjG2cNIDuiY/PeuWXl6fQrcqLe4Xi9V+MA+GSjEjZlPQ + AyEuqK/LTyM15qAuJo9ydiRtkJ77BllEcMeI83sOt+Z7fQ9KNgYgJI04e3zyQltwutw6M5Z+Jez5w8ya + mNT8w65ccuX+4yYV+gZKHIe9h2mRxUOkUw82lGvfKFAAf0BZ8qfJslTHs6NzeoflVc3McwAPJCOJyB2L + s+0cI4N3qt3pdtdoHlQO/icslAEW6DHnlA0OSQ695UivLBLbgvCOrKab1PvjVBzdPrOGd97C7D8qxcak + zS7RIe/fKjIy2DtMnaojHzZvdSaLoOlceSW8kK/CehrkYkcv4nVwGTNk7wXgn5jedzdyyGOStdq165cI + u8yCOnxvOdCnkmk1uQmp/R09cnIVXveTnkM5SJ7mc6tHBLqnlZHNB+grSn/DZB2/Y8fWfx3vZ/y80tLe + FHB+1guy3dp5b2ekqQFAy554rZCOGMuSY80h13W7fSYDMOorsMx5Gj6XN0+E5DReDebtf8yeZLi9azWs + Nupkk5NxooyAEYGzzL0ceDBCo83jOo6lNO55tmbGLy2u18shRvlaT4NZNeunzD8MGUcve4OA/V7me60a + av5W/wC2HZ/8b5XF6XsP+8Pue9+R/h0+CngMhHm19o/UWapICuXumIUp5d6DBJnCLCPPa+tbOgbiffKB + zdroRvb5+8yw6lZvKYJGVJAVfg1KjwOSBiTu5muEjH0vOb+J1fkVK18cyovGZBIS3FJh5Z/u9V/5gZv1 + ZDL097dpuUvczrVy0ur+WgD9nRrQf8TymJoPSdiz4ch9z33yHdwtpsSqwLKtDlUZVJPaEDxWzNJBxzJt + 1BihL28SCMuzZVObdjx28k/MPzOjMY4n378cGMW9FoNPwiy8Z1zXrhiUL8vnko497db2pr/D5Mem1kbL + JGG+WXeG6jF2tf1RROkXEMv6TaNOANlKCKe2RmCKYzzwyEmIrZkuvX62t5obgUP6Itl3/wBnlcY25uhz + Rhkssy/L7zbJbTcWf931NTleQPR54xywsPS1/M7TY0blIDx2yHqdWezpWxXzv+Y1bX1LVuUbbcsceMk7 + uw0WhF+p43q3ma5mlaRn5V8czOAAU5mu1UMUKCQz3y3qmnwyYQKeN1E4anltJK5YpEb4x9OWg26jJhlD + YppoH93qX/MJJ+rKsvMN2n5S9yea39V1VdNkh1C3jNrZQW5EsgQ8lBLinzPXb5ZVEkXs3zAlREgCtsnu + rMFYtTsqt+16gwHfoXNxa3JAVxArppr1lp+lLLfrSUZIHycv+Wcn9FclzeCya1fU7GSJ67NKKj8Mied0 + UHtfId7jaTy6NzPxapaf8jBloyeTrc+aeXnIKI0FAajU7QEf8WYfF8nDGGjYkFb9GClG1G0cf64yPF5F + yhkNUTEr7e3t7GK7Y3UEvrwPGqxuCeRG22AkmtmoREbojk//2Q== + + + + + /9j/4AAQSkZJRgABAgEAAAAAAAD/7gAOQWRvYmUAZAAAAAAB/9sAQwAGBAQEBQQGBQUGCQYFBgkLCAYG + CAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8f/9sAQwEHBwcNDA0YEBAY + GhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA + QABAAwERAAIRAQMRAf/EAB8AAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKC//EALUQAAIBAwMCBAIG + BwMEAgYCcwECAxEEAAUhEjFBUQYTYSJxgRQykaEHFbFCI8FS0eEzFmLwJHKC8SVDNFOSorJjc8I1RCeT + o7M2F1RkdMPS4ggmgwkKGBmElEVGpLRW01UoGvLj88TU5PRldYWVpbXF1eX1ZnaGlqa2xtbm9jdHV2d3 + h5ent8fX5/c4SFhoeIiYqLjI2Oj4KTlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/EAB8BAAICAwEB + AQEBAAAAAAAAAAEAAgMEBQYHCAkKC//EALURAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZx + 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 + HTR4I2Rd7s9ZqxliBQHDEjnzf//Z + + + + + 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 + EaFs0IJTggeQZKacppaDCb7sJpwYwgRPA3rDBE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBE8D + esMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBN+l + Ae+fv3xz8ysnkBfNT2htFib4zgz4cPObBZYzfHz7rn3SZLOwzPdkAOo3Pz4tzvK5naVhOe/JgFr9Zzef + 0oU2IbY/D+ps4W4MqD/aZiOdP3Wp/gzkNqFUg7sxQN8aa0pcz4N1P/h2FMozuA8D0FQZNhd61iJV2Pgq + pDyD+zAATZVhU9+jFbYD5RnczQyIUz8sRZ8iDVgZ9efLN/5cpjyD12AAzwf66suhL25sB5I6uHsDWJ3q + 54PLv0K0NJRqcMcGxBdA6uTzSbgrLPON772CpX09BsBDZ6RNwXLe/R7Aol/vAdv3QKkGd28AsHdJ862I + FVA/iL24+AfOF4XyDF6JAUDv1jEbStEmIamD+zAgTpzw0PezQX0kLUWbhJIM7sMApYfKpWiANGBBKL0R + A1Rn4+9GKM/gPgw4esip/x+Qm/D8qP/piBn2OxB2DM23oxdBLTGvGfIIDV/ff6i3QuHIGrURKNXgbgw4 + +pkUOJwcG4TlvBsDAOIOf+xJ5NL21QeW9p4MCLx79CR+f0x8de/Bxt9+qGGC78+AvcMETwN6wwRPA3rD + BE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rDBE8DesMETwN6wwRPA3rD + BE8DesMETwN6wwRPA3rDBE8DesMEdwOSnZkGrMw0YGWmASszDViVt+78BxcRNIGuRG8gAAAAAElFTkSu + QmCC + + + + + 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 + rwAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/OshimaModes/UserControsl/CustomProgressBar.cs b/OshimaModes/UserControsl/CustomProgressBar.cs new file mode 100644 index 0000000..4c810c0 --- /dev/null +++ b/OshimaModes/UserControsl/CustomProgressBar.cs @@ -0,0 +1,67 @@ +namespace Oshima.FunGame.OshimaModes +{ + public class CustomProgressBar : UserControl + { + private double _value = 0; + private double _maximum = 100; + private Color _progressColor = Color.Red; + + public double Value + { + get => _value; + set + { + _value = Math.Max(0, Math.Min(value, _maximum)); // 限制值在范围内 + Invalidate(); // 触发重绘 + } + } + + public double Maximum + { + get => _maximum; + set + { + _maximum = Math.Max(1, value); // 最大值不能小于1 + Invalidate(); // 触发重绘 + } + } + + public Color ProgressColor + { + get => _progressColor; + set + { + _progressColor = value; + Invalidate(); // 触发重绘 + } + } + + public CustomProgressBar() + { + this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.OptimizedDoubleBuffer, true); + this.Height = 20; // 设置控件的默认高度 + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + + // 计算进度条填充宽度 + double percent = _value / _maximum; + int fillWidth = (int)(this.Width * percent); + + // 填充背景(灰色) + e.Graphics.FillRectangle(Brushes.LightGray, 0, 0, this.Width, this.Height); + + // 填充进度条(自定义颜色) + e.Graphics.FillRectangle(new SolidBrush(_progressColor), 0, 0, fillWidth, this.Height); + + // 可选:绘制进度百分比文字 + string text = $"{_value} / {_maximum}"; + SizeF textSize = e.Graphics.MeasureString(text, this.Font); + e.Graphics.DrawString(text, this.Font, Brushes.Black, + (this.Width - textSize.Width) / 2, (this.Height - textSize.Height) / 2); + } + } +} diff --git a/OshimaModes/UserControsl/CustomProgressBar.resx b/OshimaModes/UserControsl/CustomProgressBar.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/OshimaModes/UserControsl/CustomProgressBar.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OshimaModes/UserControsl/PlayerStatusControl.cs b/OshimaModes/UserControsl/PlayerStatusControl.cs new file mode 100644 index 0000000..c9f2cfd --- /dev/null +++ b/OshimaModes/UserControsl/PlayerStatusControl.cs @@ -0,0 +1,59 @@ +namespace Oshima.FunGame.OshimaModes +{ + public partial class PlayerStatusControl : UserControl + { + public Label PlayerNameLabel { get; } + public PictureBox AvatarBox { get; } + public CustomProgressBar HPBar { get; } + public CustomProgressBar MPBar { get; } + + public PlayerStatusControl(int index) + { + // 玩家名标签 + PlayerNameLabel = new() + { + Text = "Player " + index, + TextAlign = ContentAlignment.MiddleCenter, + ImageAlign = ContentAlignment.MiddleCenter, + Dock = DockStyle.Top, + AutoSize = true + }; + + // 头像框 + AvatarBox = new() + { + BorderStyle = BorderStyle.FixedSingle, + SizeMode = PictureBoxSizeMode.StretchImage, + Height = 100, + Width = 100, + Dock = DockStyle.Top + }; + + // HP条 + HPBar = new() + { + Maximum = 100, + Value = 75.5, // 支持浮点数 + ProgressColor = Color.Red, // 自定义颜色 + Dock = DockStyle.Bottom, + Height = 20 + }; + + // MP条 + MPBar = new() + { + Maximum = 100, + Value = 50.7, // 支持浮点数 + ProgressColor = Color.Blue, // 自定义颜色 + Dock = DockStyle.Bottom, + Height = 20 + }; + + // 添加控件到用户控件 + this.Controls.Add(MPBar); + this.Controls.Add(HPBar); + this.Controls.Add(AvatarBox); + this.Controls.Add(PlayerNameLabel); + } + } +} diff --git a/OshimaModes/UserControsl/PlayerStatusControl.resx b/OshimaModes/UserControsl/PlayerStatusControl.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/OshimaModes/UserControsl/PlayerStatusControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OshimaModules/Characters/ColdBlue.cs b/OshimaModules/Characters/ColdBlue.cs new file mode 100644 index 0000000..4d92589 --- /dev/null +++ b/OshimaModules/Characters/ColdBlue.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class ColdBlue : Character + { + public ColdBlue() : base() + { + Id = 10; + Name = "Cold"; + FirstName = "Blue"; + NickName = "冷蓝"; + PrimaryAttribute = PrimaryAttribute.STR; + InitialATK = 28; + InitialHP = 95; + InitialMP = 25; + InitialSTR = 22; + STRGrowth = 1.9; + InitialAGI = 4; + AGIGrowth = 0.6; + InitialINT = 4; + INTGrowth = 0.6; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/DokyoMayor.cs b/OshimaModules/Characters/DokyoMayor.cs new file mode 100644 index 0000000..e0a904c --- /dev/null +++ b/OshimaModules/Characters/DokyoMayor.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class DokyoMayor : Character + { + public DokyoMayor() : base() + { + Id = 6; + Name = "Dokyo"; + FirstName = "Mayor"; + NickName = "铎京市长"; + PrimaryAttribute = PrimaryAttribute.AGI; + InitialATK = 21; + InitialHP = 120; + InitialMP = 20; + InitialSTR = 7; + STRGrowth = 1; + InitialAGI = 21; + AGIGrowth = 1.8; + InitialINT = 2; + INTGrowth = 0.2; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/MagicalGirl.cs b/OshimaModules/Characters/MagicalGirl.cs new file mode 100644 index 0000000..5a0d5dd --- /dev/null +++ b/OshimaModules/Characters/MagicalGirl.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class MagicalGirl : Character + { + public MagicalGirl() : base() + { + Id = 7; + Name = "Magical"; + FirstName = "Girl"; + NickName = "魔法少女"; + PrimaryAttribute = PrimaryAttribute.AGI; + InitialATK = 20; + InitialHP = 95; + InitialMP = 35; + InitialSTR = 7; + STRGrowth = 0.3; + InitialAGI = 15; + AGIGrowth = 2.3; + InitialINT = 8; + INTGrowth = 0.4; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/NanGanYu.cs b/OshimaModules/Characters/NanGanYu.cs new file mode 100644 index 0000000..c91045a --- /dev/null +++ b/OshimaModules/Characters/NanGanYu.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class NanGanYu : Character + { + public NanGanYu() : base() + { + Id = 4; + Name = "Nan"; + FirstName = "Ganyu"; + NickName = "男甘雨"; + PrimaryAttribute = PrimaryAttribute.INT; + InitialATK = 17; + InitialHP = 115; + InitialMP = 80; + InitialSTR = 6; + STRGrowth = 0.6; + InitialAGI = 7; + AGIGrowth = 0.7; + InitialINT = 17; + INTGrowth = 1.7; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/NiuNan.cs b/OshimaModules/Characters/NiuNan.cs new file mode 100644 index 0000000..12ecc98 --- /dev/null +++ b/OshimaModules/Characters/NiuNan.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class NiuNan : Character + { + public NiuNan() : base() + { + Id = 5; + Name = "Niu"; + FirstName = "Nan"; + NickName = "牛腩"; + PrimaryAttribute = PrimaryAttribute.INT; + InitialATK = 16; + InitialHP = 75; + InitialMP = 90; + InitialSTR = 0; + STRGrowth = 0; + InitialAGI = 0; + AGIGrowth = 0; + InitialINT = 30; + INTGrowth = 3; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/OshimaShiya.cs b/OshimaModules/Characters/OshimaShiya.cs new file mode 100644 index 0000000..7936d2a --- /dev/null +++ b/OshimaModules/Characters/OshimaShiya.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class OshimaShiya : Character + { + public OshimaShiya() : base() + { + Id = 1; + Name = "Oshima"; + FirstName = "Shiya"; + NickName = "大島シヤ"; + PrimaryAttribute = PrimaryAttribute.STR; + InitialATK = 25; + InitialHP = 85; + InitialMP = 10; + InitialSTR = 35; + STRGrowth = 3.5; + InitialAGI = 0; + AGIGrowth = 0; + InitialINT = 0; + INTGrowth = 0; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/QWQAQW.cs b/OshimaModules/Characters/QWQAQW.cs new file mode 100644 index 0000000..10d3f10 --- /dev/null +++ b/OshimaModules/Characters/QWQAQW.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class QWQAQW : Character + { + public QWQAQW() : base() + { + Id = 9; + Name = "QWQ"; + FirstName = "AQW"; + NickName = "LUOLI66"; + PrimaryAttribute = PrimaryAttribute.INT; + InitialATK = 18; + InitialHP = 125; + InitialMP = 45; + InitialSTR = 0; + STRGrowth = 0; + InitialAGI = 15; + AGIGrowth = 1.5; + InitialINT = 15; + INTGrowth = 1.5; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/QingXiang.cs b/OshimaModules/Characters/QingXiang.cs new file mode 100644 index 0000000..e8141ec --- /dev/null +++ b/OshimaModules/Characters/QingXiang.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class QingXiang : Character + { + public QingXiang() : base() + { + Id = 8; + Name = "Qing"; + FirstName = "Xiang"; + NickName = "清香"; + PrimaryAttribute = PrimaryAttribute.INT; + InitialATK = 26; + InitialHP = 110; + InitialMP = 80; + InitialSTR = 6; + STRGrowth = 0.5; + InitialAGI = 4; + AGIGrowth = 0.5; + InitialINT = 20; + INTGrowth = 2; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/Quduoduo.cs b/OshimaModules/Characters/Quduoduo.cs new file mode 100644 index 0000000..1633ee7 --- /dev/null +++ b/OshimaModules/Characters/Quduoduo.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class Quduoduo : Character + { + public Quduoduo() : base() + { + Id = 12; + Name = "Qu"; + FirstName = "Duoduo"; + NickName = "趣多多"; + PrimaryAttribute = PrimaryAttribute.STR; + InitialATK = 19; + InitialHP = 90; + InitialMP = 40; + InitialSTR = 13; + STRGrowth = 1.5; + InitialAGI = 13; + AGIGrowth = 1.2; + InitialINT = 4; + INTGrowth = 0.3; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/XinYin.cs b/OshimaModules/Characters/XinYin.cs new file mode 100644 index 0000000..cce0dd5 --- /dev/null +++ b/OshimaModules/Characters/XinYin.cs @@ -0,0 +1,30 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class XinYin : Character + { + public XinYin() : base() + { + Id = 2; + Name = "Xiyue"; + FirstName = "XinYin"; + NickName = "心音"; + PrimaryAttribute = PrimaryAttribute.AGI; + InitialATK = 22; + InitialHP = 80; + InitialMP = 60; + InitialSTR = 8; + STRGrowth = 0.9; + InitialAGI = 19; + AGIGrowth = 1.7; + InitialINT = 3; + INTGrowth = 0.4; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + + } + } +} diff --git a/OshimaModules/Characters/Yang.cs b/OshimaModules/Characters/Yang.cs new file mode 100644 index 0000000..dbca7e2 --- /dev/null +++ b/OshimaModules/Characters/Yang.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class Yang : Character + { + public Yang() : base() + { + Id = 3; + Name = "Ya"; + FirstName = "Yang"; + NickName = "吖养"; + PrimaryAttribute = PrimaryAttribute.STR; + InitialATK = 23; + InitialHP = 105; + InitialMP = 55; + InitialSTR = 11; + STRGrowth = 1.8; + InitialAGI = 9; + AGIGrowth = 0.5; + InitialINT = 10; + INTGrowth = 0.7; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Characters/dddovo.cs b/OshimaModules/Characters/dddovo.cs new file mode 100644 index 0000000..c8ab5d7 --- /dev/null +++ b/OshimaModules/Characters/dddovo.cs @@ -0,0 +1,29 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Characters +{ + public class dddovo : Character + { + public dddovo() : base() + { + Id = 11; + Name = "ddd"; + FirstName = "ovo"; + NickName = "绿拱门"; + PrimaryAttribute = PrimaryAttribute.AGI; + InitialATK = 22; + InitialHP = 65; + InitialMP = 22; + InitialSTR = 10; + STRGrowth = 1; + InitialAGI = 20; + AGIGrowth = 2; + InitialINT = 0; + INTGrowth = 0; + InitialSPD = 300; + InitialHR = 4; + InitialMR = 2; + } + } +} diff --git a/OshimaModules/Controllers/Controller.cs b/OshimaModules/Controllers/Controller.cs new file mode 100644 index 0000000..e904f28 --- /dev/null +++ b/OshimaModules/Controllers/Controller.cs @@ -0,0 +1,7 @@ +namespace Oshima.FunGame.OshimaModules.Controllers +{ + public class Controller + { + + } +} diff --git a/OshimaModules/Effects/ItemEffects/冷却缩减加成.cs b/OshimaModules/Effects/ItemEffects/冷却缩减加成.cs new file mode 100644 index 0000000..a995ad5 --- /dev/null +++ b/OshimaModules/Effects/ItemEffects/冷却缩减加成.cs @@ -0,0 +1,35 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 冷却缩减加成 : Effect + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"增加角色 {实际冷却缩减加成 * 100:0.##}% 冷却缩减。" + (!TargetSelf ? $"来自:[ {Source} ]" + (Item != null ? $" 的 [ {Item.Name} ]" : "") : ""); + public override EffectType EffectType => EffectType.Item; + public override bool TargetSelf => true; + + public Item? Item { get; } + private readonly double 实际冷却缩减加成 = 0; + + public override void OnEffectGained(Character character) + { + character.ExCDR += 实际冷却缩减加成; + } + + public override void OnEffectLost(Character character) + { + character.ExCDR -= 实际冷却缩减加成; + } + + public 冷却缩减加成(Skill skill, Character? source, Item? item, double exCdr) : base(skill) + { + ActionQueue = skill.ActionQueue; + Source = source; + Item = item; + 实际冷却缩减加成 = exCdr; + } + } +} diff --git a/OshimaModules/Effects/ItemEffects/技能硬直时间减少.cs b/OshimaModules/Effects/ItemEffects/技能硬直时间减少.cs new file mode 100644 index 0000000..ee7dc6c --- /dev/null +++ b/OshimaModules/Effects/ItemEffects/技能硬直时间减少.cs @@ -0,0 +1,52 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 技能硬直时间减少 : Effect + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"减少角色的所有主动技能 {实际硬直时间减少} 硬直时间。" + (!TargetSelf ? $"来自:[ {Source} ]" + (Item != null ? $" 的 [ {Item.Name} ]" : "") : ""); + public override EffectType EffectType => EffectType.Item; + public override bool TargetSelf => true; + + public Item? Item { get; } + private readonly double 实际硬直时间减少 = 2; + + public override void OnEffectGained(Character character) + { + foreach (Skill s in character.Skills) + { + s.HardnessTime = Calculation.Round2Digits(s.HardnessTime - 实际硬直时间减少); + } + foreach (Skill? s in character.Items.Select(i => i.Skills.Active)) + { + if (s != null) + s.HardnessTime = Calculation.Round2Digits(s.HardnessTime - 实际硬直时间减少); + } + } + + public override void OnEffectLost(Character character) + { + foreach (Skill s in character.Skills) + { + s.HardnessTime = Calculation.Round2Digits(s.HardnessTime + 实际硬直时间减少); + } + foreach (Skill? s in character.Items.Select(i => i.Skills.Active)) + { + if (s != null) + s.HardnessTime = Calculation.Round2Digits(s.HardnessTime + 实际硬直时间减少); + } + } + + public 技能硬直时间减少(Skill skill, Character? source, Item? item, double reduce) : base(skill) + { + ActionQueue = skill.ActionQueue; + Source = source; + Item = item; + 实际硬直时间减少 = reduce; + } + } +} diff --git a/OshimaModules/Effects/ItemEffects/攻击力加成.cs b/OshimaModules/Effects/ItemEffects/攻击力加成.cs new file mode 100644 index 0000000..30a7368 --- /dev/null +++ b/OshimaModules/Effects/ItemEffects/攻击力加成.cs @@ -0,0 +1,35 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 攻击力加成 : Effect + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"增加角色 {实际攻击力加成} 点攻击力。" + (!TargetSelf ? $"来自:[ {Source} ]" + (Item != null ? $" 的 [ {Item.Name} ]" : "") : ""); + public override EffectType EffectType => EffectType.Item; + public override bool TargetSelf => true; + + public Item? Item { get; } + private readonly double 实际攻击力加成 = 0; + + public override void OnEffectGained(Character character) + { + character.ExATK2 += 实际攻击力加成; + } + + public override void OnEffectLost(Character character) + { + character.ExATK2 -= 实际攻击力加成; + } + + public 攻击力加成(Skill skill, Character? source, Item? item, double exATK) : base(skill) + { + ActionQueue = skill.ActionQueue; + Source = source; + Item = item; + 实际攻击力加成 = exATK; + } + } +} diff --git a/OshimaModules/Effects/ItemEffects/普攻硬直时间减少.cs b/OshimaModules/Effects/ItemEffects/普攻硬直时间减少.cs new file mode 100644 index 0000000..71c5f5b --- /dev/null +++ b/OshimaModules/Effects/ItemEffects/普攻硬直时间减少.cs @@ -0,0 +1,36 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 普攻硬直时间减少 : Effect + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"减少角色的普通攻击 {实际硬直时间减少} 硬直时间。" + (!TargetSelf ? $"来自:[ {Source} ]" + (Item != null ? $" 的 [ {Item.Name} ]" : "") : ""); + public override EffectType EffectType => EffectType.Item; + public override bool TargetSelf => true; + + public Item? Item { get; } + private readonly double 实际硬直时间减少 = 2; + + public override void OnEffectGained(Character character) + { + character.NormalAttack.HardnessTime = Calculation.Round2Digits(character.NormalAttack.HardnessTime - 实际硬直时间减少); ; + } + + public override void OnEffectLost(Character character) + { + character.NormalAttack.HardnessTime = Calculation.Round2Digits(character.NormalAttack.HardnessTime + 实际硬直时间减少); ; + } + + public 普攻硬直时间减少(Skill skill, Character? source, Item? item, double reduce) : base(skill) + { + ActionQueue = skill.ActionQueue; + Source = source; + Item = item; + 实际硬直时间减少 = reduce; + } + } +} diff --git a/OshimaModules/Effects/ItemEffects/物理护甲加成.cs b/OshimaModules/Effects/ItemEffects/物理护甲加成.cs new file mode 100644 index 0000000..7d7f25f --- /dev/null +++ b/OshimaModules/Effects/ItemEffects/物理护甲加成.cs @@ -0,0 +1,35 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 物理护甲加成 : Effect + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"增加角色 {实际物理护甲加成} 点物理护甲。" + (!TargetSelf ? $"来自:[ {Source} ]" + (Item != null ? $" 的 [ {Item.Name} ]" : "") : ""); + public override EffectType EffectType => EffectType.Item; + public override bool TargetSelf => true; + + public Item? Item { get; } + private readonly double 实际物理护甲加成 = 0; + + public override void OnEffectGained(Character character) + { + character.ExDEF2 += 实际物理护甲加成; + } + + public override void OnEffectLost(Character character) + { + character.ExDEF2 -= 实际物理护甲加成; + } + + public 物理护甲加成(Skill skill, Character? source, Item? item, double exDef) : base(skill) + { + ActionQueue = skill.ActionQueue; + Source = source; + Item = item; + 实际物理护甲加成 = exDef; + } + } +} diff --git a/OshimaModules/Effects/眩晕.cs b/OshimaModules/Effects/眩晕.cs new file mode 100644 index 0000000..03d8358 --- /dev/null +++ b/OshimaModules/Effects/眩晕.cs @@ -0,0 +1,47 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 眩晕 : Effect + { + public override long Id => 4101; + public override string Name => "眩晕"; + public override string Description => $"此角色被眩晕了,不能行动。来自:[ {Source} ] 的 [ {Skill.Name} ]"; + public override EffectType EffectType => EffectType.Stun; + public override bool TargetSelf => true; + public override Character Source => _sourceCharacter; + public override bool Durative => _durative; + public override double Duration => _duration; + public override int DurationTurn => _durationTurn; + + private readonly Character _sourceCharacter; + private readonly bool _durative; + private readonly double _duration; + private readonly int _durationTurn; + + public 眩晕(Skill skill, Character sourceCharacter, bool durative = false, double duration = 0, int durationTurn = 1) : base(skill) + { + ActionQueue = skill.ActionQueue; + _sourceCharacter = sourceCharacter; + _durative = durative; + _duration = duration; + _durationTurn = durationTurn; + } + + public override void OnEffectGained(Character character) + { + if (_durative) RemainDuration = Duration; + else RemainDurationTurn = DurationTurn; + character.CharacterEffectStates.Add(this, [CharacterState.NotActionable]); + character.UpdateCharacterState(); + InterruptCasting(character, Source); + } + + public override void OnEffectLost(Character character) + { + character.CharacterEffectStates.Remove(this); + character.UpdateCharacterState(); + } + } +} diff --git a/OshimaModules/Effects/累积之压标记.cs b/OshimaModules/Effects/累积之压标记.cs new file mode 100644 index 0000000..1b6b1ce --- /dev/null +++ b/OshimaModules/Effects/累积之压标记.cs @@ -0,0 +1,24 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Effects +{ + public class 累积之压标记 : Effect + { + public override long Id => 4102; + public override string Name => "累积之压标记"; + public override string Description => $"此角色持有累积之压标记,已累计 {MarkLevel} 层。来自:[ {Source} ]"; + public override EffectType EffectType => EffectType.Mark; + public override bool TargetSelf => true; + public override Character Source => _sourceCharacter; + public int MarkLevel { get; set; } = 1; + + private readonly Character _sourceCharacter; + + public 累积之压标记(Skill skill, Character sourceCharacter) : base(skill) + { + ActionQueue = skill.ActionQueue; + _sourceCharacter = sourceCharacter; + } + } +} diff --git a/OshimaModules/Items/Accessory/攻击之爪.cs b/OshimaModules/Items/Accessory/攻击之爪.cs new file mode 100644 index 0000000..9fb7fe7 --- /dev/null +++ b/OshimaModules/Items/Accessory/攻击之爪.cs @@ -0,0 +1,62 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Effects; +using Oshima.FunGame.OshimaModules.Skills; + +namespace Oshima.FunGame.OshimaModules.Items +{ + public class 攻击之爪10 : Item + { + public override long Id => (long)AccessoryID.攻击之爪10; + public override string Name => "攻击之爪 +10"; + public override string Description => Skills.Passives.Count > 0 ? Skills.Passives.First().Description : ""; + + public 攻击之爪10(Character? character = null) : base(ItemType.Accessory, slot: EquipSlotType.Accessory) + { + Skills.Passives.Add(new 攻击之爪技能(character, this, 10)); + } + } + + public class 攻击之爪30 : Item + { + public override long Id => (long)AccessoryID.攻击之爪30; + public override string Name => "攻击之爪 +30"; + public override string Description => Skills.Passives.Count > 0 ? Skills.Passives.First().Description : ""; + + public 攻击之爪30(Character? character = null) : base(ItemType.Accessory, slot: EquipSlotType.Accessory) + { + Skills.Passives.Add(new 攻击之爪技能(character, this, 30)); + } + } + + public class 攻击之爪50 : Item + { + public override long Id => (long)AccessoryID.攻击之爪50; + public override string Name => "攻击之爪 +50"; + public override string Description => Skills.Passives.Count > 0 ? Skills.Passives.First().Description : ""; + + public 攻击之爪50(Character? character = null) : base(ItemType.Accessory, slot: EquipSlotType.Accessory) + { + Skills.Passives.Add(new 攻击之爪技能(character, this, 50)); + } + } + + public class 攻击之爪技能 : Skill + { + public override long Id => (long)ItemPassiveID.攻击之爪; + public override string Name => "攻击之爪"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 攻击之爪技能(Character? character = null, Item? item = null, double exATK = 0) : base(SkillType.Passive, character) + { + Level = 1; + Item = item; + Effects.Add(new 攻击力加成(this, character, item, exATK)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } +} diff --git a/OshimaModules/Items/ItemID.cs b/OshimaModules/Items/ItemID.cs new file mode 100644 index 0000000..14d55ba --- /dev/null +++ b/OshimaModules/Items/ItemID.cs @@ -0,0 +1,9 @@ +namespace Oshima.FunGame.OshimaModules.Items +{ + public enum AccessoryID : long + { + 攻击之爪10 = 14001, + 攻击之爪30 = 14002, + 攻击之爪50 = 14003, + } +} diff --git a/OshimaModules/Items/Weapon/独奏弓.cs b/OshimaModules/Items/Weapon/独奏弓.cs new file mode 100644 index 0000000..1d7e983 --- /dev/null +++ b/OshimaModules/Items/Weapon/独奏弓.cs @@ -0,0 +1,43 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Effects; + +namespace Oshima.FunGame.OshimaModules.Items +{ + [Obsolete] + public class 独奏弓 : Item + { + public override long Id => 11999; + public override string Name => "独奏弓"; + public override string Description => Skills.Passives.Count > 0 ? Skills.Passives.First().Description : ""; + + public 独奏弓(Character? character = null) : base(ItemType.Weapon, slot: EquipSlotType.Weapon) + { + WeaponType = WeaponType.Bow; + Skills.Passives.Add(new 独奏弓技能(character, this)); + } + } + + public class 独奏弓技能 : Skill + { + public override long Id => 5999; + public override string Name => "独奏弓"; + public override string Description => $"增加角色 {攻击力加成} 点攻击力,减少普通攻击 {硬直时间减少} 硬直时间。"; + + private readonly double 攻击力加成 = 80; + private readonly double 硬直时间减少 = 2; + + public 独奏弓技能(Character? character, Item item) : base(SkillType.Passive, character) + { + Level = 1; + Item = item; + Effects.Add(new 攻击力加成(this, character, item, 攻击力加成)); + Effects.Add(new 普攻硬直时间减少(this, character, item, 硬直时间减少)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } +} diff --git a/OshimaModules/Modules/CharacterModule.cs b/OshimaModules/Modules/CharacterModule.cs new file mode 100644 index 0000000..cca2a54 --- /dev/null +++ b/OshimaModules/Modules/CharacterModule.cs @@ -0,0 +1,23 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; + +namespace Oshima.FunGame.OshimaModules +{ + public class CharacterModule : Milimoe.FunGame.Core.Library.Common.Addon.CharacterModule + { + public override string Name => OshimaGameModuleConstant.Character; + public override string Description => OshimaGameModuleConstant.Description; + public override string Version => OshimaGameModuleConstant.Version; + public override string Author => OshimaGameModuleConstant.Author; + + public override List Characters + { + get + { + EntityModuleConfig config = new(OshimaGameModuleConstant.General, OshimaGameModuleConstant.Character); + config.LoadConfig(); + return [.. config.Values]; + } + } + } +} diff --git a/OshimaModules/Modules/Constant.cs b/OshimaModules/Modules/Constant.cs new file mode 100644 index 0000000..589203d --- /dev/null +++ b/OshimaModules/Modules/Constant.cs @@ -0,0 +1,23 @@ +using Milimoe.FunGame.Core.Library.Common.Addon; + +namespace Oshima.FunGame.OshimaModules +{ + public class OshimaGameModuleConstant + { + public const string General = "oshima-studios"; + public const string FastAuto = "oshima.fungame.fastauto"; + public const string Character = "oshima.fungame.characters"; + public const string Skill = "oshima.fungame.skills"; + public const string Item = "oshima.fungame.items"; + public const string Description = "Oshima Studios Presents"; + public const string Version = "1.0.0"; + public const string Author = "Oshima Studios"; + public const string FastAutoMap = "oshima.fungame.fastauto.map"; + + private static readonly string[] Maps = [FastAutoMap]; + private static readonly string[] Characters = [Character]; + private static readonly string[] Skills = [Skill]; + private static readonly string[] Items = [Item]; + public static GameModuleDepend GameModuleDepend { get; } = new(Maps, Characters, Skills, Items); + } +} diff --git a/OshimaModules/Modules/ItemModule.cs b/OshimaModules/Modules/ItemModule.cs new file mode 100644 index 0000000..c2fe45a --- /dev/null +++ b/OshimaModules/Modules/ItemModule.cs @@ -0,0 +1,58 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Items; + +namespace Oshima.FunGame.OshimaModules +{ + public class ItemModule : Milimoe.FunGame.Core.Library.Common.Addon.ItemModule + { + public override string Name => OshimaGameModuleConstant.Item; + public override string Description => OshimaGameModuleConstant.Description; + public override string Version => OshimaGameModuleConstant.Version; + public override string Author => OshimaGameModuleConstant.Author; + + public override List Items + { + get + { + EntityModuleConfig config = new(OshimaGameModuleConstant.General, OshimaGameModuleConstant.Item); + config.LoadConfig(); + foreach (string key in config.Keys) + { + Item prev = config[key]; + Item? next = GetItem(prev.Id, prev.Name, prev.ItemType); + if (next != null) + { + prev.SetPropertyToItemModuleNew(next); + config[key] = next; + } + } + return [.. config.Values]; + } + } + + public override Item? GetItem(long id, string name, ItemType type) + { + if (type == ItemType.MagicCardPack) + { + + } + + if (type == ItemType.Accessory) + { + switch ((AccessoryID)id) + { + case AccessoryID.攻击之爪10: + return new 攻击之爪10(); + case AccessoryID.攻击之爪30: + return new 攻击之爪30(); + case AccessoryID.攻击之爪50: + return new 攻击之爪50(); + } + } + + return null; + } + } +} diff --git a/OshimaModules/Modules/SkillModule.cs b/OshimaModules/Modules/SkillModule.cs new file mode 100644 index 0000000..69429d3 --- /dev/null +++ b/OshimaModules/Modules/SkillModule.cs @@ -0,0 +1,125 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Items; +using Oshima.FunGame.OshimaModules.Skills; + +namespace Oshima.FunGame.OshimaModules +{ + public class SkillModule : Milimoe.FunGame.Core.Library.Common.Addon.SkillModule + { + public override string Name => OshimaGameModuleConstant.Skill; + public override string Description => OshimaGameModuleConstant.Description; + public override string Version => OshimaGameModuleConstant.Version; + public override string Author => OshimaGameModuleConstant.Author; + + public override List Skills + { + get + { + EntityModuleConfig config = new(OshimaGameModuleConstant.General, OshimaGameModuleConstant.Skill); + config.LoadConfig(); + foreach (string key in config.Keys) + { + Skill prev = config[key]; + Skill? next = GetSkill(prev.Id, prev.Name, prev.SkillType); + if (next != null) + { + config[key] = next; + } + } + return [.. config.Values]; + } + } + + public override Skill? GetSkill(long id, string name, SkillType type) + { + if (type == SkillType.Magic) + { + switch ((MagicID)id) + { + case MagicID.冰霜攻击: + return new 冰霜攻击(); + } + } + + if (type == SkillType.Skill) + { + switch ((SkillID)id) + { + case SkillID.疾风步: + return new 疾风步(); + } + } + + if (type == SkillType.SuperSkill) + { + switch ((SuperSkillID)id) + { + case SuperSkillID.力量爆发: + return new 力量爆发(); + case SuperSkillID.天赐之力: + return new 天赐之力(); + case SuperSkillID.魔法涌流: + return new 魔法涌流(); + case SuperSkillID.三重叠加: + return new 三重叠加(); + case SuperSkillID.变幻之心: + return new 变幻之心(); + case SuperSkillID.精准打击: + return new 精准打击(); + case SuperSkillID.绝对领域: + return new 绝对领域(); + case SuperSkillID.能量毁灭: + return new 能量毁灭(); + case SuperSkillID.迅捷之势: + return new 迅捷之势(); + case SuperSkillID.嗜血本能: + return new 嗜血本能(); + case SuperSkillID.平衡强化: + return new 平衡强化(); + case SuperSkillID.血之狂欢: + return new 血之狂欢(); + } + } + + if (type == SkillType.Passive) + { + switch ((PassiveID)id) + { + case PassiveID.META马: + return new META马(); + case PassiveID.心灵之火: + return new 心灵之火(); + case PassiveID.魔法震荡: + return new 魔法震荡(); + case PassiveID.灵能反射: + return new 灵能反射(); + case PassiveID.智慧与力量: + return new 智慧与力量(); + case PassiveID.致命打击: + return new 致命打击(); + case PassiveID.毁灭之势: + return new 毁灭之势(); + case PassiveID.枯竭打击: + return new 枯竭打击(); + case PassiveID.玻璃大炮: + return new 玻璃大炮(); + case PassiveID.累积之压: + return new 累积之压(); + case PassiveID.敏捷之刃: + return new 敏捷之刃(); + case PassiveID.弱者猎手: + return new 弱者猎手(); + } + switch ((ItemPassiveID)id) + { + case ItemPassiveID.攻击之爪: + return new 攻击之爪技能(); + } + } + + return null; + } + } +} diff --git a/OshimaCustomizedMode.csproj b/OshimaModules/OshimaModules.csproj similarity index 79% rename from OshimaCustomizedMode.csproj rename to OshimaModules/OshimaModules.csproj index d7fbae6..2feee25 100644 --- a/OshimaCustomizedMode.csproj +++ b/OshimaModules/OshimaModules.csproj @@ -7,6 +7,9 @@ Oshima.FunGame.$(MSBuildProjectName.Replace(" ", "_")) Oshima Studios Oshima Studios + Library + False + ..\bin\ @@ -19,16 +22,10 @@ 1701;1702;CS8981;IDE1006 - - - - - - - ..\FunGame.Core\bin\Debug\net8.0\FunGame.Core.dll + ..\..\FunGame.Core\bin\Debug\net8.0\FunGame.Core.dll - + diff --git a/OshimaModules/Skills/ColdBlue/嗜血本能.cs b/OshimaModules/Skills/ColdBlue/嗜血本能.cs new file mode 100644 index 0000000..8430930 --- /dev/null +++ b/OshimaModules/Skills/ColdBlue/嗜血本能.cs @@ -0,0 +1,65 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Effects; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 嗜血本能 : Skill + { + public override long Id => (long)SuperSkillID.嗜血本能; + public override string Name => "嗜血本能"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 42 - 1 * (Level - 1); + public override double HardnessTime { get; set; } = 12; + + public 嗜血本能(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 嗜血本能特效(this)); + } + } + + public class 嗜血本能特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"{Duration} 时间内,攻击拥有标记的角色将根据标记层数获得 {吸血 * 100:0.##}% 吸血每层。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 30; + + public HashSet 角色有第四层 { get; } = []; + private double 吸血 => Calculation.Round4Digits(0.03 * Level); + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && damageResult != DamageResult.Evaded && character.HP < character.MaxHP) + { + int 层数 = 0; + if (enemy.Effects.Where(e => e is 累积之压标记).FirstOrDefault() is 累积之压标记 e) + { + 层数 = e.MarkLevel; + } + else if (角色有第四层.Remove(enemy)) + { + 层数 = 4; + } + double 实际吸血 = Calculation.Round2Digits(吸血 * 层数 * damage); + character.HP += 实际吸血; + WriteLine($"[ {character} ] 回复了 {实际吸血} 点生命值!"); + } + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 角色有第四层.Clear(); + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/ColdBlue/累积之压.cs b/OshimaModules/Skills/ColdBlue/累积之压.cs new file mode 100644 index 0000000..fd27601 --- /dev/null +++ b/OshimaModules/Skills/ColdBlue/累积之压.cs @@ -0,0 +1,90 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Effects; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 累积之压 : Skill + { + public override long Id => (long)PassiveID.累积之压; + public override string Name => "累积之压"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 累积之压(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 累积之压特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 累积之压特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"每次造成伤害都可以叠一层标记,累计 4 层时回收该角色所有标记并造成眩晕 1 回合,额外对该角色造成 {系数 * 100:0.##}% 最大生命值的物理伤害。"; + public override bool TargetSelf => true; + + private readonly double 系数 = 0.12; + private bool 是否是嵌套伤害 = false; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && damageResult != DamageResult.Evaded && !是否是嵌套伤害) + { + // 叠标记 + IEnumerable effects = enemy.Effects.Where(e => e is 累积之压标记); + if (effects.Any() && effects.First() is 累积之压标记 e) + { + e.MarkLevel++; + IEnumerable effects2 = character.Effects.Where(e => e is 嗜血本能特效); + if (effects2.Any() && effects2.First() is 嗜血本能特效 e2) + { + if (e.MarkLevel >= 4) + { + e2.角色有第四层.Add(enemy); + } + else + { + e2.角色有第四层.Remove(enemy); + } + } + if (e.MarkLevel >= 4) + { + // 移除标记 + enemy.Effects.Remove(e); + double 额外伤害 = Calculation.Round2Digits(enemy.MaxHP * 系数); + WriteLine($"[ {character} ] 发动了累积之压!将对 [ {enemy} ] 造成眩晕和额外伤害!"); + // 眩晕 + IEnumerable effects3 = enemy.Effects.Where(e => e is 眩晕 && e.Skill == Skill); + if (effects3.Any()) + { + effects3.First().RemainDurationTurn++; + } + else + { + 眩晕 e3 = new(Skill, character, false, 0, 1); + enemy.Effects.Add(e3); + e3.OnEffectGained(enemy); + } + 是否是嵌套伤害 = true; + DamageToEnemy(character, enemy, false, magicType, 额外伤害); + } + } + else + { + enemy.Effects.Add(new 累积之压标记(Skill, character)); + } + } + + if (character == Skill.Character && 是否是嵌套伤害) + { + 是否是嵌套伤害 = false; + } + } + } +} diff --git a/OshimaModules/Skills/MagicalGirl/毁灭之势.cs b/OshimaModules/Skills/MagicalGirl/毁灭之势.cs new file mode 100644 index 0000000..bd306df --- /dev/null +++ b/OshimaModules/Skills/MagicalGirl/毁灭之势.cs @@ -0,0 +1,59 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 毁灭之势 : Skill + { + public override long Id => (long)PassiveID.毁灭之势; + public override string Name => "毁灭之势"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 毁灭之势(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 毁灭之势特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 毁灭之势特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"每时间提升 5.5% 所有伤害,无上限,但受到伤害时效果清零。" + (累计伤害 > 0 ? $"(当前总提升:{累计伤害 * 100:0.##}%)" : ""); + public override bool TargetSelf => true; + + private readonly double 伤害提升 = 0.055; + private double 累计伤害 = 0; + + public override bool AlterActualDamageAfterCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (damageResult != DamageResult.Evaded) + { + if (enemy == Skill.Character && damage > 0 && !enemy.Effects.Where(e => e is 绝对领域特效).Any()) + { + 累计伤害 = 0; + } + + if (character == Skill.Character) + { + double 实际伤害提升 = Calculation.Round2Digits(damage * 累计伤害); + damage = Calculation.Round2Digits(damage + 实际伤害提升); + if (实际伤害提升 > 0) WriteLine($"[ {character} ] 的伤害提升了 {实际伤害提升} 点!"); + } + } + return false; + } + + public override void OnTimeElapsed(Character character, double eapsed) + { + 累计伤害 = Calculation.Round4Digits(累计伤害 + 伤害提升 * eapsed); + WriteLine($"[ {character} ] 的 [ {Name} ] 效果增加了,当前总提升:{累计伤害 * 100:0.##}%。"); + } + } +} diff --git a/OshimaModules/Skills/MagicalGirl/绝对领域.cs b/OshimaModules/Skills/MagicalGirl/绝对领域.cs new file mode 100644 index 0000000..4803f36 --- /dev/null +++ b/OshimaModules/Skills/MagicalGirl/绝对领域.cs @@ -0,0 +1,74 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 绝对领域 : Skill + { + public override long Id => (long)SuperSkillID.绝对领域; + public override string Name => "绝对领域"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => Math.Max(100, Character?.EP ?? 100); + public override double CD => 32 + (1 * (Level - 1)); + public override double HardnessTime { get; set; } = 12; + + public 绝对领域(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 绝对领域特效(this)); + } + } + + public class 绝对领域特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"{Duration} 时间内无法受到任何伤害,且敏捷提升 {系数 * 100:0.##}% [ {敏捷提升} ]。此技能会消耗至少 100 点能量。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => Calculation.Round2Digits(16 + 释放时的能量值 * 0.03); + + private double 系数 => Calculation.Round4Digits(0.3 + 0.03 * (Level - 1)); + private double 敏捷提升 => Calculation.Round2Digits(系数 * Skill.Character?.BaseAGI ?? 0); + private double 实际敏捷提升 = 0; + private double 释放时的能量值 = 0; + + public override void OnEffectGained(Character character) + { + 实际敏捷提升 = 敏捷提升; + character.ExAGI += 实际敏捷提升; + WriteLine($"[ {character} ] 的敏捷提升了 {系数 * 100:0.##}% [ {实际敏捷提升} ] !"); + } + + public override void OnEffectLost(Character character) + { + character.ExAGI -= 实际敏捷提升; + } + + public override bool AlterActualDamageAfterCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (enemy == Skill.Character && damageResult != DamageResult.Evaded) + { + WriteLine($"[ {enemy} ] 发动了绝对领域,巧妙的化解了此伤害!"); + return true; + } + return false; + } + + public override void OnSkillCasting(Character caster) + { + 释放时的能量值 = caster.EP; + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 实际敏捷提升 = 0; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/Mayor/精准打击.cs b/OshimaModules/Skills/Mayor/精准打击.cs new file mode 100644 index 0000000..ec086af --- /dev/null +++ b/OshimaModules/Skills/Mayor/精准打击.cs @@ -0,0 +1,64 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 精准打击 : Skill + { + public override long Id => (long)SuperSkillID.精准打击; + public override string Name => "精准打击"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 40 - 1 * (Level - 1); + public override double HardnessTime { get; set; } = 8; + + public 精准打击(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 精准打击特效(this)); + } + } + + public class 精准打击特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"30 时间内暴击率提升 {暴击率提升 * 100:0.##}%,暴击伤害再提升 {暴击伤害提升 * 100:0.##}%。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 30; + + private double 暴击率提升 => Calculation.Round4Digits(0.2 + 0.03 * (Level - 1)); + private double 暴击伤害提升 => Calculation.Round4Digits(0.8 + 0.04 * (Level - 1)); + private double 实际暴击率提升 = 0; + private double 实际暴击伤害提升 = 0; + + public override void OnEffectGained(Character character) + { + 实际暴击率提升 = 暴击率提升; + 实际暴击伤害提升 = 暴击伤害提升; + character.ExCritRate += 实际暴击率提升; + WriteLine($"[ {character} ] 的暴击率提升了 [ {实际暴击率提升 * 100:0.##}% ] !"); + character.ExCritDMG += 实际暴击伤害提升; + WriteLine($"[ {character} ] 的暴击伤害提升了 [ {实际暴击伤害提升 * 100:0.##}% ] !"); + } + + public override void OnEffectLost(Character character) + { + character.ExCritRate -= 实际暴击率提升; + character.ExCritDMG -= 实际暴击伤害提升; + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 实际暴击率提升 = 0; + 实际暴击伤害提升 = 0; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/Mayor/致命打击.cs b/OshimaModules/Skills/Mayor/致命打击.cs new file mode 100644 index 0000000..e51aa9a --- /dev/null +++ b/OshimaModules/Skills/Mayor/致命打击.cs @@ -0,0 +1,40 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 致命打击 : Skill + { + public override long Id => (long)PassiveID.致命打击; + public override string Name => "致命打击"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 致命打击(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 致命打击特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 致命打击特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"暴击伤害提升 70%。"; + public override bool TargetSelf => true; + + public override void OnEffectGained(Character character) + { + character.ExCritDMG += 0.7; + } + + public override void OnEffectLost(Character character) + { + character.ExCritDMG -= 0.7; + } + } +} diff --git a/OshimaModules/Skills/NanGanyu/三重叠加.cs b/OshimaModules/Skills/NanGanyu/三重叠加.cs new file mode 100644 index 0000000..882456e --- /dev/null +++ b/OshimaModules/Skills/NanGanyu/三重叠加.cs @@ -0,0 +1,64 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 三重叠加 : Skill + { + public override long Id => (long)SuperSkillID.三重叠加; + public override string Name => "三重叠加"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 35 - 2 * (Level - 1); + public override double HardnessTime { get; set; } = 10; + + public 三重叠加(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 三重叠加特效(this)); + } + } + + public class 三重叠加特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => "三重叠加"; + public override string Description => $"使 [ 灵能反射 ] 支持普通攻击,且当前释放魔法次数归零,最大硬直消除次数提高到 {灵能反射次数} 次;在魔法命中和普通攻击命中时能够回复所回复能量值的 10 倍魔法值,持续 {技能持续次数} 次(灵能反射每消除次数达到最大时算一次)。" + + $"(剩余:{剩余持续次数} 次)"; + public override bool TargetSelf => true; + + public int 剩余持续次数 { get; set; } = 0; + private readonly int 灵能反射次数 = 3; + private readonly int 技能持续次数 = 2; + + public override void OnEffectGained(Character character) + { + IEnumerable effects = character.Effects.Where(e => e is 灵能反射特效); + if (effects.Any() && effects.First() is 灵能反射特效 e) + { + e.是否支持普攻 = true; + e.触发硬直次数 = 3; + e.释放次数 = 0; + } + } + + public override void OnEffectLost(Character character) + { + IEnumerable effects = character.Effects.Where(e => e is 灵能反射特效); + if (effects.Any() && effects.First() is 灵能反射特效 e) + { + e.是否支持普攻 = false; + e.触发硬直次数 = 2; + } + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + 剩余持续次数 = 技能持续次数; + if (!caster.Effects.Contains(this)) + { + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/NanGanyu/灵能反射.cs b/OshimaModules/Skills/NanGanyu/灵能反射.cs new file mode 100644 index 0000000..e6f2e38 --- /dev/null +++ b/OshimaModules/Skills/NanGanyu/灵能反射.cs @@ -0,0 +1,103 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 灵能反射 : Skill + { + public override long Id => (long)PassiveID.灵能反射; + public override string Name => "灵能反射"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 灵能反射(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 灵能反射特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 灵能反射特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"每释放 {触发硬直次数} 次魔法才会触发硬直时间,且魔法命中时基于 25% 智力 [ {获得额外能量值} ] 获得额外能量值。"; + public override bool TargetSelf => true; + + public bool 是否支持普攻 { get; set; } = false; + public int 触发硬直次数 { get; set; } = 2; + public int 释放次数 { get; set; } = 0; + public double 获得额外能量值 + { + get + { + return Calculation.Round2Digits(0.25 * Skill.Character?.INT ?? 0); + } + } + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && (是否支持普攻 && isNormalAttack || isMagicDamage) && damageResult != DamageResult.Evaded && character.EP < 200) + { + double 实际获得能量值 = 获得额外能量值; + character.EP += 实际获得能量值; + WriteLine("[ " + character + " ] 发动了灵能反射!额外获得了 " + 实际获得能量值 + " 能量!"); + IEnumerable effects = character.Effects.Where(e => e is 三重叠加特效); + if (effects.Any() && effects.First() is 三重叠加特效 e) + { + double 获得的魔法值 = Calculation.Round2Digits(实际获得能量值 * 10); + character.MP += 获得的魔法值; + WriteLine("[ " + character + " ] 发动了三重叠加!回复了 " + 获得的魔法值 + " 魔法值!"); + } + } + } + + public override void AlterHardnessTimeAfterNormalAttack(Character character, ref double baseHardnessTime, ref bool isCheckProtected) + { + if (是否支持普攻) + { + AlterHardnessTime(character, ref baseHardnessTime, ref isCheckProtected); + } + } + + public override void AlterHardnessTimeAfterCastSkill(Character character, Skill skill, ref double baseHardnessTime, ref bool isCheckProtected) + { + if (skill.SkillType == SkillType.Magic) + { + AlterHardnessTime(character, ref baseHardnessTime, ref isCheckProtected); + } + } + + public void AlterHardnessTime(Character character, ref double baseHardnessTime, ref bool isCheckProtected) + { + 释放次数++; + if (释放次数 < 触发硬直次数) + { + baseHardnessTime = 0; + isCheckProtected = false; + WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!"); + } + else + { + 释放次数 = 0; + IEnumerable effects = character.Effects.Where(e => e is 三重叠加特效); + if (effects.Any() && effects.First() is 三重叠加特效 e) + { + baseHardnessTime = 0; + isCheckProtected = false; + WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!"); + e.剩余持续次数--; + if (e.剩余持续次数 == 0) + { + character.Effects.Remove(e); + e.OnEffectLost(character); + } + } + } + } + } +} diff --git a/OshimaModules/Skills/NiuNan/变幻之心.cs b/OshimaModules/Skills/NiuNan/变幻之心.cs new file mode 100644 index 0000000..90ad765 --- /dev/null +++ b/OshimaModules/Skills/NiuNan/变幻之心.cs @@ -0,0 +1,77 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 变幻之心 : Skill + { + public override long Id => (long)SuperSkillID.变幻之心; + public override string Name => "变幻之心"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 30; + public override double HardnessTime { get; set; } = 10; + + public 变幻之心(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 变幻之心特效(this)); + } + } + + public class 变幻之心特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => "变幻之心"; + public override string Description => $"检查 [ 智慧与力量 ] 的模式。在力量模式下,立即回复 {生命值回复 * 100:0.##}% 生命值;智力模式下,下一次魔法伤害提升 {伤害提升 * 100:0.##}%。"; + public override bool TargetSelf => true; + + private double 生命值回复 => Calculation.Round4Digits(0.25 + 0.03 * (Level - 1)); + private double 伤害提升 => Calculation.Round4Digits(0.55 + 0.25 * (Level - 1)); + + public override void OnEffectGained(Character character) + { + Skill.IsInEffect = true; + } + + public override void OnEffectLost(Character character) + { + Skill.IsInEffect = false; + } + + public override void AlterExpectedDamageBeforeCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType) + { + if (character == Skill.Character && isMagicDamage) + { + double 实际伤害提升百分比 = 伤害提升; + double 实际伤害提升 = Calculation.Round2Digits(damage * 实际伤害提升百分比); + damage = Calculation.Round2Digits(damage + 实际伤害提升); + WriteLine("[ " + character + " ] 发动了变幻之心!伤害提升了 " + 实际伤害提升 + " 点!"); + character.Effects.Remove(this); + OnEffectLost(character); + } + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + IEnumerable effects = caster.Effects.Where(e => e is 智慧与力量特效); + if (effects.Any()) + { + if (caster.PrimaryAttribute == PrimaryAttribute.STR) + { + double 回复的生命 = Calculation.Round2Digits(生命值回复 * caster.MaxHP); + caster.HP += 回复的生命; + WriteLine("[ " + caster + " ] 回复了 " + 回复的生命 + " 点生命值!"); + } + else if (caster.PrimaryAttribute == PrimaryAttribute.INT) + { + if (!caster.Effects.Contains(this)) + { + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } + } + } +} diff --git a/OshimaModules/Skills/NiuNan/智慧与力量.cs b/OshimaModules/Skills/NiuNan/智慧与力量.cs new file mode 100644 index 0000000..09843c8 --- /dev/null +++ b/OshimaModules/Skills/NiuNan/智慧与力量.cs @@ -0,0 +1,91 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 智慧与力量 : Skill + { + public override long Id => (long)PassiveID.智慧与力量; + public override string Name => "智慧与力量"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 智慧与力量(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 智慧与力量特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 智慧与力量特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"当生命值低于 30% 时,智力转化为力量;当生命值高于或等于 30% 时,力量转化为智力。" + + (Skill.Character != null ? "(当前模式:" + CharacterSet.GetPrimaryAttributeName(Skill.Character.PrimaryAttribute) + ")" : ""); + public override bool TargetSelf => true; + + private double 交换前的额外智力 = 0; + private double 交换前的额外力量 = 0; + + public override void OnAttributeChanged(Character character) + { + if (Skill.Character != null) + { + if (Skill.Character.PrimaryAttribute == PrimaryAttribute.INT) + { + double diff = character.ExSTR - 交换前的额外力量; + character.ExINT = 交换前的额外力量 + character.BaseSTR + diff; + } + else if (Skill.Character.PrimaryAttribute == PrimaryAttribute.STR) + { + double diff = character.ExINT - 交换前的额外智力; + character.ExSTR = 交换前的额外智力 + character.BaseINT + diff; + } + } + } + + public override void OnTimeElapsed(Character character, double elapsed) + { + if (Skill.Character != null) + { + Character c = Skill.Character; + if (c.HP < c.MaxHP * 0.3) + { + if (c.PrimaryAttribute == PrimaryAttribute.INT) + { + double pastHP = c.HP; + double pastMaxHP = c.MaxHP; + double pastMP = c.MP; + double pastMaxMP = c.MaxMP; + c.PrimaryAttribute = PrimaryAttribute.STR; + 交换前的额外智力 = c.ExINT; + 交换前的额外力量 = c.ExSTR; + c.ExINT = -c.BaseINT; + c.ExSTR = 交换前的额外智力 + c.BaseINT + 交换前的额外力量; + c.Recovery(pastHP, pastMP, pastMaxHP, pastMaxMP); + } + } + else + { + if (c.PrimaryAttribute == PrimaryAttribute.STR) + { + double pastHP = c.HP; + double pastMaxHP = c.MaxHP; + double pastMP = c.MP; + double pastMaxMP = c.MaxMP; + c.PrimaryAttribute = PrimaryAttribute.INT; + 交换前的额外智力 = c.ExINT; + 交换前的额外力量 = c.ExSTR; + c.ExINT = 交换前的额外力量 + c.BaseSTR + 交换前的额外智力; + c.ExSTR = -c.BaseSTR; + c.Recovery(pastHP, pastMP, pastMaxHP, pastMaxMP); + } + } + } + } + } +} diff --git a/OshimaModules/Skills/Oshima/META马.cs b/OshimaModules/Skills/Oshima/META马.cs new file mode 100644 index 0000000..5b9f80f --- /dev/null +++ b/OshimaModules/Skills/Oshima/META马.cs @@ -0,0 +1,47 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class META马 : Skill + { + public override long Id => (long)PassiveID.META马; + public override string Name => "META马"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public META马(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new META马特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class META马特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"META马专属被动:力量+5,力量成长+0.5;在受到伤害时,获得的能量提升50%,每回合开始还能获得额外的 [ {EP} ] 能量值。"; + public override bool TargetSelf => true; + public static double EP => 10; + + public override void AlterEPAfterGetDamage(Character character, ref double baseEP) + { + baseEP = Calculation.Round2Digits(baseEP * 1.5); + if (Skill.Character != null) WriteLine("[ " + Skill.Character + " ] 发动了META马专属被动!本次获得了 " + baseEP + " 能量!"); + } + + public override void OnTurnStart(Character character) + { + if (character.EP < 200) + { + character.EP += EP; + WriteLine("[ " + character + " ] 发动了META马专属被动!本次获得了 " + EP + " 能量!"); + } + } + } +} diff --git a/OshimaModules/Skills/Oshima/力量爆发.cs b/OshimaModules/Skills/Oshima/力量爆发.cs new file mode 100644 index 0000000..d7c04d7 --- /dev/null +++ b/OshimaModules/Skills/Oshima/力量爆发.cs @@ -0,0 +1,58 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 力量爆发 : Skill + { + public override long Id => (long)SuperSkillID.力量爆发; + public override string Name => "力量爆发"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 55; + public override double HardnessTime { get; set; } = 0; + + public 力量爆发(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 力量爆发特效(this)); + } + } + + public class 力量爆发特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => "力量爆发"; + public override string Description => $"获得 150% 力量 [ {攻击力加成} ] 的攻击力加成,持续 {Duration} 时间。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 10 + 1 * (Level - 1); + + private double 攻击力加成 => Calculation.Round2Digits(Skill.Character?.STR * 1.5 ?? 0); + private double 实际攻击力加成 = 0; + + public override void OnEffectGained(Character character) + { + 实际攻击力加成 = 攻击力加成; + character.ExATK2 += 实际攻击力加成; + WriteLine($"[ {character} ] 的攻击力增加了 [ {实际攻击力加成} ] !"); + } + + public override void OnEffectLost(Character character) + { + // 恢复到原始攻击力 + character.ExATK2 -= 实际攻击力加成; + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 实际攻击力加成 = 0; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/QWQAQW/玻璃大炮.cs b/OshimaModules/Skills/QWQAQW/玻璃大炮.cs new file mode 100644 index 0000000..7ad5875 --- /dev/null +++ b/OshimaModules/Skills/QWQAQW/玻璃大炮.cs @@ -0,0 +1,101 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 玻璃大炮 : Skill + { + public override long Id => (long)PassiveID.玻璃大炮; + public override string Name => "玻璃大炮"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 玻璃大炮(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 玻璃大炮特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 玻璃大炮特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"生命值高于 30% 时,受到额外的 [ {高于30额外伤害下限}~{高于30额外伤害上限}% ] 伤害,但是获得 [ 累计所受伤害的 {高于30的加成下限}~{高于30的加成上限}% ] 伤害加成;生命值低于等于 30% 时,不会受到额外的伤害,仅能获得 [ 累计受到的伤害 {低于30的加成下限}~{低于30的加成上限}% ] 伤害加成。" + + $"在没有受到任何伤害的时候,将获得 {常规伤害加成 * 100:0.##}% 伤害加成。" + (累计受到的伤害 > 0 ? $"(当前累计受到伤害:{累计受到的伤害})" : ""); + public override bool TargetSelf => true; + + private double 累计受到的伤害 = 0; + private double 这次的伤害加成 = 0; + private double 受到伤害之前的HP = 0; + private double 这次受到的额外伤害 = 0; + private readonly double 常规伤害加成 = 0.35; + private readonly int 高于30额外伤害上限 = 40; + private readonly int 高于30额外伤害下限 = 20; + private readonly int 高于30的加成上限 = 100; + private readonly int 高于30的加成下限 = 80; + private readonly int 低于30的加成上限 = 60; + private readonly int 低于30的加成下限 = 40; + + private double 伤害加成(double damage) + { + double 系数 = 常规伤害加成; + Character? character = Skill.Character; + if (character != null && 累计受到的伤害 != 0) + { + if (character.HP > character.MaxHP * 0.3) + { + 系数 = Calculation.Round4Digits(1.0 + ((new Random().Next(高于30的加成下限, 高于30的加成上限) + 0.0) / 100)); + } + else + { + 系数 = Calculation.Round4Digits(1.0 + ((new Random().Next(低于30的加成下限, 低于30的加成上限) + 0.0) / 100)); + } + return Calculation.Round2Digits(系数 * 累计受到的伤害); + } + return Calculation.Round2Digits(系数 * damage); + } + + public override void AlterExpectedDamageBeforeCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType) + { + if (character == Skill.Character) + { + 这次的伤害加成 = 伤害加成(damage); + damage = Calculation.Round2Digits(damage + 这次的伤害加成); + WriteLine($"[ {character} ] 发动了玻璃大炮,获得了 {这次的伤害加成} 点伤害加成!"); + 累计受到的伤害 = 0; + } + + if (enemy == Skill.Character) + { + 受到伤害之前的HP = enemy.HP; + if (enemy.HP > enemy.MaxHP * 0.3) + { + // 额外受到伤害 + double 系数 = Calculation.Round4Digits((new Random().Next(高于30额外伤害下限, 高于30额外伤害上限) + 0.0) / 100); + 这次受到的额外伤害 = Calculation.Round2Digits(damage * 系数); + damage = Calculation.Round2Digits(damage + 这次受到的额外伤害); + WriteLine($"[ {enemy} ] 的玻璃大炮触发,将额外受到 {这次受到的额外伤害} 点伤害!"); + } + else 这次受到的额外伤害 = 0; + } + } + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (enemy == Skill.Character && damageResult != DamageResult.Evaded) + { + 累计受到的伤害 = Calculation.Round2Digits(累计受到的伤害 + damage); + if (enemy.HP < 0 && 受到伤害之前的HP - damage + 这次受到的额外伤害 > 0) + { + enemy.HP = 10; + WriteLine($"[ {enemy} ] 的玻璃大炮触发,保护了自己不进入死亡!!"); + } + } + } + } +} diff --git a/OshimaModules/Skills/QWQAQW/迅捷之势.cs b/OshimaModules/Skills/QWQAQW/迅捷之势.cs new file mode 100644 index 0000000..19f4544 --- /dev/null +++ b/OshimaModules/Skills/QWQAQW/迅捷之势.cs @@ -0,0 +1,67 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 迅捷之势 : Skill + { + public override long Id => (long)SuperSkillID.迅捷之势; + public override string Name => "迅捷之势"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 60 - 2 * (Level - 1); + public override double HardnessTime { get; set; } = 15; + + public 迅捷之势(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 迅捷之势特效(this)); + } + } + + public class 迅捷之势特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"{Duration} 时间内,普通攻击转为魔法伤害,且硬直时间减少50%,并基于 {智力系数 * 100:0.##}% 智力 [{智力加成}] 强化普通攻击伤害。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 40; + + private double 智力系数 => Calculation.Round4Digits(1.4 + 0.4 * (Level - 1)); + private double 智力加成 => Calculation.Round2Digits(智力系数 * Skill.Character?.INT ?? 0); + + public override void OnEffectGained(Character character) + { + character.NormalAttack.SetMagicType(true, character.MagicType); + } + + public override void OnEffectLost(Character character) + { + character.NormalAttack.SetMagicType(false, character.MagicType); + } + + public override void AlterExpectedDamageBeforeCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType) + { + if (character == Skill.Character && isNormalAttack) + { + damage = Calculation.Round2Digits(damage + 智力加成); + } + } + + public override void AlterHardnessTimeAfterNormalAttack(Character character, ref double baseHardnessTime, ref bool isCheckProtected) + { + baseHardnessTime = Calculation.Round2Digits(baseHardnessTime * 0.5); + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/QingXiang/枯竭打击.cs b/OshimaModules/Skills/QingXiang/枯竭打击.cs new file mode 100644 index 0000000..708a7aa --- /dev/null +++ b/OshimaModules/Skills/QingXiang/枯竭打击.cs @@ -0,0 +1,57 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 枯竭打击 : Skill + { + public override long Id => (long)PassiveID.枯竭打击; + public override string Name => "枯竭打击"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 枯竭打击(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 枯竭打击特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 枯竭打击特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"每次造成伤害都会随机减少对方 [ 10~25 ] 点能量值,对能量值低于一半的角色额外造成 30% 伤害。对于枯竭打击而言,能量值大于100且小于150时,视为低于一半。"; + public override bool TargetSelf => true; + + private bool 是否是嵌套伤害 = false; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && damageResult != DamageResult.Evaded && !是否是嵌套伤害) + { + // 减少能量 + double EP = new Random().Next(10, 25); + enemy.EP -= EP; + WriteLine($"[ {character} ] 发动了枯竭打击![ {enemy} ] 的能量值被减少了 {EP} 点!现有能量:{enemy.EP}。"); + // 额外伤害 + if (enemy.EP >= 0 && enemy.EP < 50 || enemy.EP >= 100 && enemy.EP < 150) + { + double 额外伤害 = Calculation.Round2Digits(damage * 0.3); + WriteLine($"[ {character} ] 发动了枯竭打击!将造成额外伤害!"); + 是否是嵌套伤害 = true; + DamageToEnemy(character, enemy, isMagicDamage, magicType, 额外伤害); + } + } + + if (character == Skill.Character && 是否是嵌套伤害) + { + 是否是嵌套伤害 = false; + } + } + } +} diff --git a/OshimaModules/Skills/QingXiang/能量毁灭.cs b/OshimaModules/Skills/QingXiang/能量毁灭.cs new file mode 100644 index 0000000..bf026f5 --- /dev/null +++ b/OshimaModules/Skills/QingXiang/能量毁灭.cs @@ -0,0 +1,45 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 能量毁灭 : Skill + { + public override long Id => (long)SuperSkillID.能量毁灭; + public override string Name => "能量毁灭"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 55 - 3 * (Level - 1); + public override double HardnessTime { get; set; } = 25; + + public 能量毁灭(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 能量毁灭特效(this)); + } + } + + public class 能量毁灭特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"对所有角色造成 " + + $"{能量系数 * 100:0.##}% 其现有能量值 + {智力系数 * 100:0.##}% 智力 [ {智力伤害} ] 的魔法伤害。"; + public override bool TargetSelf => false; + public override double TargetRange => 999; + + private double 智力系数 => Calculation.Round4Digits(0.55 * Level); + private double 智力伤害 => Calculation.Round2Digits(智力系数 * Skill.Character?.INT ?? 0); + private double 能量系数 => Calculation.Round4Digits(0.75 * Level); + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + foreach (Character c in enemys) + { + WriteLine($"[ {caster} ] 正在毁灭 [ {c} ] 的能量!!"); + double ep = c.EP; + DamageToEnemy(caster, c, true, MagicType, Calculation.Round2Digits(ep * 能量系数 + 智力伤害)); + } + } + } +} diff --git a/OshimaModules/Skills/QuDuoduo/弱者猎手.cs b/OshimaModules/Skills/QuDuoduo/弱者猎手.cs new file mode 100644 index 0000000..12585cc --- /dev/null +++ b/OshimaModules/Skills/QuDuoduo/弱者猎手.cs @@ -0,0 +1,52 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 弱者猎手 : Skill + { + public override long Id => (long)PassiveID.弱者猎手; + public override string Name => "弱者猎手"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 弱者猎手(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 弱者猎手特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 弱者猎手特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"优先攻击血量更低的角色,对生命值百分比低于自己的角色造成 150% 伤害。"; + public override bool TargetSelf => true; + + public override void AlterExpectedDamageBeforeCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType) + { + if (character == Skill.Character && (enemy.HP / enemy.MaxHP) <= (character.HP / character.MaxHP)) + { + double 额外伤害 = Calculation.Round2Digits(damage * 0.5); + damage = Calculation.Round2Digits(damage + 额外伤害); + } + } + + public override bool AlterEnemyListBeforeAction(Character character, List enemys, List teammates, List skills, Dictionary continuousKilling, Dictionary earnedMoney) + { + IEnumerable list = [.. enemys.OrderBy(e => Calculation.Round4Digits(e.HP / e.MaxHP))]; + if (list.Any()) + { + enemys.Clear(); + enemys.Add(list.First()); + WriteLine($"[ {character} ] 发动了弱者猎手![ {list.First()} ] 被盯上了!"); + } + return true; + } + } +} diff --git a/OshimaModules/Skills/QuDuoduo/血之狂欢.cs b/OshimaModules/Skills/QuDuoduo/血之狂欢.cs new file mode 100644 index 0000000..4543b92 --- /dev/null +++ b/OshimaModules/Skills/QuDuoduo/血之狂欢.cs @@ -0,0 +1,51 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 血之狂欢 : Skill + { + public override long Id => (long)SuperSkillID.血之狂欢; + public override string Name => "血之狂欢"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 45; + public override double HardnessTime { get; set; } = 7; + + public 血之狂欢(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 血之狂欢特效(this)); + } + } + + public class 血之狂欢特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"获得 40% 吸血,持续 {Duration} 时间。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 30; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && damageResult != DamageResult.Evaded && character.HP < character.MaxHP) + { + double 实际吸血 = Calculation.Round2Digits(0.4 * damage); + character.HP += 实际吸血; + WriteLine($"[ {character} ] 回复了 {实际吸血} 点生命值!"); + } + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/SkillID.cs b/OshimaModules/Skills/SkillID.cs new file mode 100644 index 0000000..badeb82 --- /dev/null +++ b/OshimaModules/Skills/SkillID.cs @@ -0,0 +1,54 @@ +namespace Oshima.FunGame.OshimaModules.Skills +{ + public enum MagicID : long + { + 冰霜攻击 = 1001, + } + + public enum SkillID : long + { + 疾风步 = 2001, + } + + public enum SuperSkillID : long + { + 力量爆发 = 3001, + 天赐之力 = 3002, + 魔法涌流 = 3003, + 三重叠加 = 3004, + 变幻之心 = 3005, + 精准打击 = 3006, + 绝对领域 = 3007, + 能量毁灭 = 3008, + 迅捷之势 = 3009, + 嗜血本能 = 3010, + 平衡强化 = 3011, + 血之狂欢 = 3012, + } + + public enum PassiveID : long + { + META马 = 4001, + 心灵之火 = 4002, + 魔法震荡 = 4003, + 灵能反射 = 4004, + 智慧与力量 = 4005, + 致命打击 = 4006, + 毁灭之势 = 4007, + 枯竭打击 = 4008, + 玻璃大炮 = 4009, + 累积之压 = 4010, + 敏捷之刃 = 4011, + 弱者猎手 = 4012, + } + + public enum ItemPassiveID : long + { + 攻击之爪 = 5001, + } + + public enum ItemActiveID : long + { + + } +} diff --git a/OshimaModules/Skills/XinYin/天赐之力.cs b/OshimaModules/Skills/XinYin/天赐之力.cs new file mode 100644 index 0000000..bcb59b3 --- /dev/null +++ b/OshimaModules/Skills/XinYin/天赐之力.cs @@ -0,0 +1,90 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 天赐之力 : Skill + { + public override long Id => (long)SuperSkillID.天赐之力; + public override string Name => "天赐之力"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 60; + public override double HardnessTime { get; set; } = 15; + + public 天赐之力(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 天赐之力特效(this)); + } + } + + public class 天赐之力特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"{Duration} 时间内,增加 40% 攻击力 [ {攻击力提升} ]、30% 物理穿透和 25% 闪避率(不可叠加),普通攻击硬直时间额外减少 20%,基于 {系数 * 100:0.##}% 敏捷 [ {伤害加成} ] 强化普通攻击的伤害。在持续时间内,【心灵之火】的冷却时间降低至 3 时间。"; + public override bool TargetSelf => false; + public override int TargetCount => 1; + public override bool Durative => true; + public override double Duration => 40; + + private double 系数 => Calculation.Round4Digits(1.2 * (1 + 0.6 * (Skill.Level - 1))); + private double 伤害加成 => Calculation.Round2Digits(系数 * Skill.Character?.AGI ?? 0); + private double 攻击力提升 => Calculation.Round2Digits(0.4 * Skill.Character?.BaseATK ?? 0); + private double 实际的攻击力提升 = 0; + + public override void OnEffectGained(Character character) + { + 实际的攻击力提升 = 攻击力提升; + character.ExATK2 += 实际的攻击力提升; + character.PhysicalPenetration += 0.3; + character.ExEvadeRate += 0.25; + if (character.Effects.Where(e => e is 心灵之火特效).FirstOrDefault() is 心灵之火特效 e) + { + e.基础冷却时间 = 3; + if (e.冷却时间 > e.基础冷却时间) e.冷却时间 = e.基础冷却时间; + } + } + + public override void OnEffectLost(Character character) + { + character.ExATK2 -= 实际的攻击力提升; + character.PhysicalPenetration -= 0.3; + character.ExEvadeRate -= 0.25; + if (character.Effects.Where(e => e is 心灵之火特效).FirstOrDefault() is 心灵之火特效 e) + { + e.基础冷却时间 = 8; + } + } + + public override CharacterActionType AlterActionTypeBeforeAction(Character character, CharacterState state, ref bool canUseItem, ref bool canCastSkill, ref double pUseItem, ref double pCastSkill, ref double pNormalAttack) + { + pNormalAttack += 0.1; + return CharacterActionType.None; + } + + public override void AlterExpectedDamageBeforeCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType) + { + if (character == Skill.Character && isNormalAttack) + { + damage = Calculation.Round2Digits(damage + 伤害加成); + } + } + + public override void AlterHardnessTimeAfterNormalAttack(Character character, ref double baseHardnessTime, ref bool isCheckProtected) + { + baseHardnessTime = Calculation.Round2Digits(baseHardnessTime * 0.8); + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/XinYin/心灵之火.cs b/OshimaModules/Skills/XinYin/心灵之火.cs new file mode 100644 index 0000000..4701d4e --- /dev/null +++ b/OshimaModules/Skills/XinYin/心灵之火.cs @@ -0,0 +1,69 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 心灵之火 : Skill + { + public override long Id => (long)PassiveID.心灵之火; + public override string Name => "心灵之火"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 心灵之火(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 心灵之火特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 心灵之火特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"普通攻击硬直时间减少 20%。每次使用普通攻击时,额外再发动一次普通攻击,伤害特效可叠加,冷却 {基础冷却时间:0.##} 时间。" + + (冷却时间 > 0 ? $"(正在冷却:剩余 {冷却时间:0.##} 时间)" : ""); + public override bool TargetSelf => true; + + public double 冷却时间 { get; set; } = 0; + public double 基础冷却时间 { get; set; } = 20; + private bool 是否是嵌套普通攻击 = false; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && isNormalAttack && 冷却时间 == 0 && !是否是嵌套普通攻击 && ActionQueue != null) + { + WriteLine($"[ {character} ] 发动了心灵之火!额外进行一次普通攻击!"); + 冷却时间 = 基础冷却时间; + 是否是嵌套普通攻击 = true; + character.NormalAttack.Attack(ActionQueue, character, enemy); + } + + if (character == Skill.Character && 是否是嵌套普通攻击) + { + 是否是嵌套普通攻击 = false; + } + } + + public override void OnTimeElapsed(Character character, double elapsed) + { + if (冷却时间 > 0) + { + 冷却时间 = Calculation.Round2Digits(冷却时间 - elapsed); + if (冷却时间 <= 0) + { + 冷却时间 = 0; + } + } + } + + public override void AlterHardnessTimeAfterNormalAttack(Character character, ref double baseHardnessTime, ref bool isCheckProtected) + { + baseHardnessTime = Calculation.Round2Digits(baseHardnessTime * 0.8); + } + } +} diff --git a/OshimaModules/Skills/Yang/魔法涌流.cs b/OshimaModules/Skills/Yang/魔法涌流.cs new file mode 100644 index 0000000..e63fbe9 --- /dev/null +++ b/OshimaModules/Skills/Yang/魔法涌流.cs @@ -0,0 +1,65 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 魔法涌流 : Skill + { + public override long Id => (long)SuperSkillID.魔法涌流; + public override string Name => "魔法涌流"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 35; + public override double HardnessTime { get; set; } = 10; + + public 魔法涌流(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 魔法涌流特效(this)); + } + } + + public class 魔法涌流特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => "魔法涌流"; + public override string Description => $"{Duration} 时间内,增加所有伤害的 {减伤比例 * 100:0.##}% 伤害减免,并将普通攻击转为魔法伤害,可叠加魔法震荡的效果。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 25; + + private double 减伤比例 => Calculation.Round2Digits(0.1 + 0.02 * (Level - 1)); + private double 实际比例 = 0; + + public override void OnEffectGained(Character character) + { + 实际比例 = 减伤比例; + character.NormalAttack.SetMagicType(true, character.MagicType); + } + + public override void OnEffectLost(Character character) + { + character.NormalAttack.SetMagicType(false, character.MagicType); + } + + public override bool AlterActualDamageAfterCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (enemy == Skill.Character) + { + damage = Calculation.Round2Digits(damage * (1 - 实际比例)); + } + return false; + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 实际比例 = 0; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/Yang/魔法震荡.cs b/OshimaModules/Skills/Yang/魔法震荡.cs new file mode 100644 index 0000000..e5bd3b2 --- /dev/null +++ b/OshimaModules/Skills/Yang/魔法震荡.cs @@ -0,0 +1,50 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules.Effects; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 魔法震荡 : Skill + { + public override long Id => (long)PassiveID.魔法震荡; + public override string Name => "魔法震荡"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 魔法震荡(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 魔法震荡特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 魔法震荡特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"造成魔法伤害时有 35% 几率使敌人眩晕 1 回合。"; + public override bool TargetSelf => true; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && isMagicDamage && damageResult != DamageResult.Evaded && new Random().NextDouble() < 0.35) + { + IEnumerable effects = enemy.Effects.Where(e => e is 眩晕 && e.Skill == Skill); + if (effects.Any()) + { + effects.First().RemainDurationTurn++; + } + else + { + 眩晕 e = new(Skill, character, false, 0, 1); + enemy.Effects.Add(e); + e.OnEffectGained(enemy); + } + WriteLine($"[ {character} ] 的魔法伤害触发了魔法震荡,[ {enemy} ] 被眩晕了!"); + } + } + } +} diff --git a/OshimaModules/Skills/dddovo/平衡强化.cs b/OshimaModules/Skills/dddovo/平衡强化.cs new file mode 100644 index 0000000..928c309 --- /dev/null +++ b/OshimaModules/Skills/dddovo/平衡强化.cs @@ -0,0 +1,70 @@ +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 平衡强化 : Skill + { + public override long Id => (long)SuperSkillID.平衡强化; + public override string Name => "平衡强化"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 100; + public override double CD => 55 - (1 * (Level - 1)); + public override double HardnessTime { get; set; } = 12; + + public 平衡强化(Character? character = null) : base(SkillType.SuperSkill, character) + { + Effects.Add(new 平衡强化特效(this)); + } + } + + public class 平衡强化特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"敏捷提高 20%,然后将目前的力量补充到与敏捷持平,持续 {Duration} 时间。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 30; + + private double 本次提升的敏捷 = 0; + private double 本次提升的力量 = 0; + + public override void OnEffectGained(Character character) + { + double pastHP = character.HP; + double pastMaxHP = character.MaxHP; + double pastMP = character.MP; + double pastMaxMP = character.MaxMP; + 本次提升的敏捷 = character.BaseAGI * 0.2; + character.ExAGI += 本次提升的敏捷; + 本次提升的力量 = character.AGI - character.STR; + character.ExSTR += 本次提升的力量; + character.Recovery(pastHP, pastMP, pastMaxHP, pastMaxMP); + WriteLine($"[ {character} ] 敏捷提升了 {本次提升的敏捷:0.##},力量提升了 {本次提升的力量:0.##}!"); + } + + public override void OnEffectLost(Character character) + { + double pastHP = character.HP; + double pastMaxHP = character.MaxHP; + double pastMP = character.MP; + double pastMaxMP = character.MaxMP; + character.ExAGI -= character.BaseAGI * 0.2; + character.ExSTR -= 本次提升的力量; + character.Recovery(pastHP, pastMP, pastMaxHP, pastMaxMP); + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + RemainDuration = Duration; + if (!caster.Effects.Contains(this)) + { + 本次提升的敏捷 = 0; + 本次提升的力量 = 0; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/dddovo/敏捷之刃.cs b/OshimaModules/Skills/dddovo/敏捷之刃.cs new file mode 100644 index 0000000..e492cb5 --- /dev/null +++ b/OshimaModules/Skills/dddovo/敏捷之刃.cs @@ -0,0 +1,50 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 敏捷之刃 : Skill + { + public override long Id => (long)PassiveID.敏捷之刃; + public override string Name => "敏捷之刃"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + + public 敏捷之刃(Character? character = null) : base(SkillType.Passive, character) + { + Effects.Add(new 敏捷之刃特效(this)); + } + + public override IEnumerable AddInactiveEffectToCharacter() + { + return Effects; + } + } + + public class 敏捷之刃特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"每次普通攻击都将附带基于 {敏捷系数 * 100:0.##}% 敏捷 [ {敏捷伤害} ] 的魔法伤害。"; + public override bool TargetSelf => true; + + private double 敏捷伤害 => Calculation.Round2Digits(敏捷系数 * Skill.Character?.AGI ?? 0); + private readonly double 敏捷系数 = 2.5; + private bool 是否是嵌套伤害 = false; + + public override void AfterDamageCalculation(Character character, Character enemy, double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && isNormalAttack && damageResult != DamageResult.Evaded && !是否是嵌套伤害) + { + WriteLine($"[ {character} ] 发动了敏捷之刃!将造成额外伤害!"); + 是否是嵌套伤害 = true; + DamageToEnemy(character, enemy, true, magicType, 敏捷伤害); + } + + if (character == Skill.Character && 是否是嵌套伤害) + { + 是否是嵌套伤害 = false; + } + } + } +} diff --git a/OshimaModules/Skills/战技/疾风步.cs b/OshimaModules/Skills/战技/疾风步.cs new file mode 100644 index 0000000..cd7b7bd --- /dev/null +++ b/OshimaModules/Skills/战技/疾风步.cs @@ -0,0 +1,85 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 疾风步 : Skill + { + public override long Id => (long)SkillID.疾风步; + public override string Name => "疾风步"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double EPCost => 60; + public override double CD => 35; + public override double HardnessTime { get; set; } = 5; + + public 疾风步(Character? character = null) : base(SkillType.Skill, character) + { + Effects.Add(new 疾风步特效(this)); + } + } + + public class 疾风步特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"进入不可选中状态,获得 100 行动速度,提高 8% 暴击率,持续 {Duration} 时间。破隐一击:在持续时间内,首次造成伤害会附加 {系数 * 100:0.##}% 敏捷 [ {伤害加成} ] 的强化伤害,并解除不可选中状态。"; + public override bool TargetSelf => true; + public override bool Durative => true; + public override double Duration => 12 + (1 * (Level - 1)); + + private double 系数 => Calculation.Round4Digits(0.5 + 0.5 * (Skill.Level - 1)); + private double 伤害加成 => Calculation.Round2Digits(系数 * Skill.Character?.AGI ?? 0); + private bool 首次伤害 { get; set; } = true; + private bool 破隐一击 { get; set; } = false; + + public override void OnEffectGained(Character character) + { + Skill.IsInEffect = true; + character.CharacterEffectTypes.Add(this, [EffectType.Unselectable]); + character.UpdateCharacterState(); + character.ExSPD += 100; + character.ExCritRate += 0.08; + } + + public override void OnEffectLost(Character character) + { + Skill.IsInEffect = false; + if (!破隐一击) + { + // 在没有打出破隐一击的情况下,恢复角色状态 + character.CharacterEffectTypes.Remove(this); + character.UpdateCharacterState(); + } + character.ExSPD -= 100; + character.ExCritRate -= 0.08; + } + + public override bool AlterActualDamageAfterCalculation(Character character, Character enemy, ref double damage, bool isNormalAttack, bool isMagicDamage, MagicType magicType, DamageResult damageResult) + { + if (character == Skill.Character && 首次伤害) + { + 首次伤害 = false; + 破隐一击 = true; + character.CharacterEffectTypes.Remove(this); + character.UpdateCharacterState(); + double d = 伤害加成; + damage = Calculation.Round2Digits(damage + d); + WriteLine($"[ {character} ] 触发了疾风步破隐一击,获得了 [ {d} ] 点伤害加成!"); + } + return false; + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + if (!caster.Effects.Contains(this)) + { + 首次伤害 = true; + 破隐一击 = false; + RemainDuration = Duration; + caster.Effects.Add(this); + OnEffectGained(caster); + } + } + } +} diff --git a/OshimaModules/Skills/魔法/冰霜攻击.cs b/OshimaModules/Skills/魔法/冰霜攻击.cs new file mode 100644 index 0000000..15ae845 --- /dev/null +++ b/OshimaModules/Skills/魔法/冰霜攻击.cs @@ -0,0 +1,53 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Oshima.FunGame.OshimaModules.Skills +{ + public class 冰霜攻击 : Skill + { + public override long Id => (long)MagicID.冰霜攻击; + public override string Name => "冰霜攻击"; + public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; + public override double MPCost => 30 + (50 * (Level - 1)); + public override double CD => 20; + public override double CastTime => 6; + public override double HardnessTime { get; set; } = 3; + + public 冰霜攻击(Character? character = null) : base(SkillType.Magic, character) + { + Effects.Add(new 冰霜攻击特效(this)); + } + } + + public class 冰霜攻击特效(Skill skill) : Effect(skill) + { + public override long Id => Skill.Id; + public override string Name => Skill.Name; + public override string Description => $"对目标敌人造成 {Calculation.Round2Digits(90 + 60 * (Skill.Level - 1))} + {Calculation.Round2Digits((1.2 + 1.8 * (Skill.Level - 1)) * 100)}% 智力 [ {Damage} ] 点{CharacterSet.GetMagicDamageName(MagicType)}。"; + public override bool TargetSelf => false; + public override int TargetCount => 1; + + private double Damage + { + get + { + double d = 0; + if (Skill.Character != null) + { + d = Calculation.Round2Digits(90 + 60 * (Skill.Level - 1) + (1.2 + 1.8 * (Skill.Level - 1)) * Skill.Character.INT); + } + return d; + } + } + + public override void OnSkillCasted(Character caster, List enemys, List teammates, Dictionary others) + { + if (enemys.Count > 0) + { + Character enemy = enemys[new Random().Next(enemys.Count)]; + DamageToEnemy(caster, enemy, true, MagicType, Damage); + } + } + } +} diff --git a/OshimaServers/FastAutoServer.cs b/OshimaServers/FastAutoServer.cs new file mode 100644 index 0000000..0beed22 --- /dev/null +++ b/OshimaServers/FastAutoServer.cs @@ -0,0 +1,594 @@ +using System.Text; +using Milimoe.FunGame.Core.Api.Transmittal; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Base; +using Milimoe.FunGame.Core.Library.Common.Addon; +using Milimoe.FunGame.Core.Library.Constant; +using Oshima.FunGame.OshimaModules; +using Oshima.FunGame.OshimaModules.Items; +using Oshima.FunGame.OshimaModules.Skills; + +namespace Oshima.FunGame.OshimaServers +{ + public class FastAutoServer : GameModuleServer + { + public override string Name => OshimaGameModuleConstant.FastAuto; + public override string Description => OshimaGameModuleConstant.Description; + public override string Version => OshimaGameModuleConstant.Version; + public override string Author => OshimaGameModuleConstant.Author; + public override string DefaultMap => OshimaGameModuleConstant.FastAutoMap; + public override GameModuleDepend GameModuleDepend => OshimaGameModuleConstant.GameModuleDepend; + public static List Characters { get; } = []; + public static Dictionary CharacterStatistics { get; } = []; + public static PluginConfig StatsConfig { get; } = new(OshimaGameModuleConstant.FastAuto, nameof(CharacterStatistics)); + public static GameModuleLoader? GameModuleLoader { get; set; } = null; + public static List ConnectedUsers { get; } = []; + + public override Dictionary GamingMessageHandler(string username, GamingType type, Dictionary data) + { + Dictionary result = []; + + switch (type) + { + case GamingType.Connect: + string un = (DataRequest.GetDictionaryJsonObject(data, "un") ?? "").Trim(); + if (un != "" && !ConnectedUsers.Where(u => u.Username == un).Any()) + { + ConnectedUsers.Add(Users.Where(u => u.Username == un).First()); + Controller.WriteLine(un + " 已连接至房间。"); + } + break; + case GamingType.Disconnect: + break; + case GamingType.Reconnect: + break; + case GamingType.BanCharacter: + break; + case GamingType.PickCharacter: + break; + case GamingType.Random: + break; + case GamingType.Round: + break; + case GamingType.LevelUp: + break; + case GamingType.Move: + break; + case GamingType.Attack: + break; + case GamingType.Skill: + break; + case GamingType.Item: + break; + case GamingType.Magic: + break; + case GamingType.Buy: + break; + case GamingType.SuperSkill: + break; + case GamingType.Pause: + break; + case GamingType.Unpause: + break; + case GamingType.Surrender: + break; + case GamingType.UpdateInfo: + break; + case GamingType.Punish: + break; + case GamingType.None: + default: + break; + } + + return result; + } + + public override bool StartServer(string GameModule, Room Room, List Users, IServerModel RoomMasterServerModel, Dictionary ServerModels, params object[] Args) + { + // 将参数转为本地属性 + this.Room = Room; + this.Users = Users; + RoomMaster = RoomMasterServerModel; + All = ServerModels; + TaskUtility.NewTask(StartGame).OnError(Controller.Error); + return true; + } + + public async Task StartGame() + { + try + { + while (true) + { + if (ConnectedUsers.Count == Users.Count) + { + break; + } + await Task.Delay(500); + } + + Dictionary characters = []; + List characterPickeds = []; + Dictionary data = []; + + // 抽取角色 + foreach (User user in Users) + { + List list = [.. Characters.Where(c => !characterPickeds.Contains(c))]; + Character cr = list[Random.Shared.Next(list.Count - 1)]; + string msg = $"{user.Username} 抽到了 [ {cr} ]"; + characterPickeds.Add(cr); + characters.Add(user, cr.Copy()); + Controller.WriteLine(msg); + SendAllGamingMessage(data, msg); + } + + int clevel = 60; + int slevel = 6; + int mlevel = 8; + + List inGameCharacters = [.. characters.Values]; + + // 升级和赋能 + foreach (Character c in inGameCharacters) + { + c.Level = clevel; + c.NormalAttack.Level = mlevel; + + Skill 冰霜攻击 = new 冰霜攻击(c) + { + Level = mlevel + }; + c.Skills.Add(冰霜攻击); + + Skill 疾风步 = new 疾风步(c) + { + Level = slevel + }; + c.Skills.Add(疾风步); + + if (c.Id == 1) + { + Skill META马 = new META马(c) + { + Level = 1 + }; + c.Skills.Add(META马); + + Skill 力量爆发 = new 力量爆发(c) + { + Level = mlevel + }; + c.Skills.Add(力量爆发); + } + + if (c.Id == 2) + { + Skill 心灵之火 = new 心灵之火(c) + { + Level = 1 + }; + c.Skills.Add(心灵之火); + + Skill 天赐之力 = new 天赐之力(c) + { + Level = slevel + }; + c.Skills.Add(天赐之力); + } + + if (c.Id == 3) + { + Skill 魔法震荡 = new 魔法震荡(c) + { + Level = 1 + }; + c.Skills.Add(魔法震荡); + + Skill 魔法涌流 = new 魔法涌流(c) + { + Level = slevel + }; + c.Skills.Add(魔法涌流); + } + + if (c.Id == 4) + { + Skill 灵能反射 = new 灵能反射(c) + { + Level = 1 + }; + c.Skills.Add(灵能反射); + + Skill 三重叠加 = new 三重叠加(c) + { + Level = slevel + }; + c.Skills.Add(三重叠加); + } + + if (c.Id == 5) + { + Skill 智慧与力量 = new 智慧与力量(c) + { + Level = 1 + }; + c.Skills.Add(智慧与力量); + + Skill 变幻之心 = new 变幻之心(c) + { + Level = slevel + }; + c.Skills.Add(变幻之心); + } + + if (c.Id == 6) + { + Skill 致命打击 = new 致命打击(c) + { + Level = 1 + }; + c.Skills.Add(致命打击); + + Skill 精准打击 = new 精准打击(c) + { + Level = slevel + }; + c.Skills.Add(精准打击); + } + + if (c.Id == 7) + { + Skill 毁灭之势 = new 毁灭之势(c) + { + Level = 1 + }; + c.Skills.Add(毁灭之势); + + Skill 绝对领域 = new 绝对领域(c) + { + Level = slevel + }; + c.Skills.Add(绝对领域); + } + + if (c.Id == 8) + { + Skill 枯竭打击 = new 枯竭打击(c) + { + Level = 1 + }; + c.Skills.Add(枯竭打击); + + Skill 能量毁灭 = new 能量毁灭(c) + { + Level = slevel + }; + c.Skills.Add(能量毁灭); + } + + if (c.Id == 9) + { + Skill 玻璃大炮 = new 玻璃大炮(c) + { + Level = 1 + }; + c.Skills.Add(玻璃大炮); + + Skill 迅捷之势 = new 迅捷之势(c) + { + Level = slevel + }; + c.Skills.Add(迅捷之势); + } + + if (c.Id == 10) + { + Skill 累积之压 = new 累积之压(c) + { + Level = 1 + }; + c.Skills.Add(累积之压); + + Skill 嗜血本能 = new 嗜血本能(c) + { + Level = slevel + }; + c.Skills.Add(嗜血本能); + } + + if (c.Id == 11) + { + Skill 敏捷之刃 = new 敏捷之刃(c) + { + Level = 1 + }; + c.Skills.Add(敏捷之刃); + + Skill 平衡强化 = new 平衡强化(c) + { + Level = slevel + }; + c.Skills.Add(平衡强化); + } + + if (c.Id == 12) + { + Skill 弱者猎手 = new 弱者猎手(c) + { + Level = 1 + }; + c.Skills.Add(弱者猎手); + + Skill 血之狂欢 = new 血之狂欢(c) + { + Level = slevel + }; + c.Skills.Add(血之狂欢); + } + + SendAllGamingMessage(data, c.GetInfo()); + } + + ActionQueue actionQueue = new(inGameCharacters, (str) => + { + SendAllGamingMessage(data, str); + }); + + // 总游戏时长 + double totalTime = 0; + // 总死亡数 + int deaths = 0; + + // 开始空投 + 空投(actionQueue, totalTime); + + // 总回合数 + int i = 1; + while (i < 999) + { + if (i == 998) + { + SendAllGamingMessage(data, $"=== 终局审判 ==="); + Dictionary 他们的血量百分比 = []; + foreach (Character c in inGameCharacters) + { + 他们的血量百分比.TryAdd(c, Calculation.Round4Digits(c.HP / c.MaxHP)); + } + double max = 他们的血量百分比.Values.Max(); + Character winner = 他们的血量百分比.Keys.Where(c => 他们的血量百分比[c] == max).First(); + SendAllGamingMessage(data, "[ " + winner + " ] 成为了天选之人!!"); + foreach (Character c in inGameCharacters.Where(c => c != winner && c.HP > 0)) + { + SendAllGamingMessage(data, "[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。"); + actionQueue.DeathCalculation(winner, c); + } + actionQueue.EndGameInfo(winner); + break; + } + + // 检查是否有角色可以行动 + Character? characterToAct = actionQueue.NextCharacter(); + + // 处理回合 + if (characterToAct != null) + { + SendAllGamingMessage(data, $"=== Round {i++} ==="); + SendAllGamingMessage(data, "现在是 [ " + characterToAct + " ] 的回合!"); + + if (actionQueue.Queue.Count == 0) + { + break; + } + + bool isGameEnd = actionQueue.ProcessTurn(characterToAct); + if (isGameEnd) + { + break; + } + + actionQueue.DisplayQueue(); + } + + // 模拟时间流逝 + totalTime += actionQueue.TimeLapse(); + + if (actionQueue.Eliminated.Count > deaths) + { + deaths = actionQueue.Eliminated.Count; + } + } + + SendAllGamingMessage(data, "--- End ---"); + SendAllGamingMessage(data, "总游戏时长:" + Calculation.Round2Digits(totalTime)); + + // 赛后统计 + SendAllGamingMessage(data, "=== 伤害排行榜 ==="); + int top = inGameCharacters.Count; + int count = 1; + foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.TotalDamage).Select(d => d.Key)) + { + StringBuilder builder = new(); + CharacterStatistics stats = actionQueue.CharacterStatistics[character]; + builder.AppendLine($"{count++}. [ {character.ToStringWithLevel()} ] ({stats.Kills} / {stats.Assists})"); + builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); + builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); + builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); + builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); + + SendAllGamingMessage(data, builder.ToString()); + + CharacterStatistics? totalStats = CharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault(); + if (totalStats != null) + { + // 统计此角色的所有数据 + totalStats.TotalDamage = Calculation.Round2Digits(totalStats.TotalDamage + stats.TotalDamage); + totalStats.TotalPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage + stats.TotalPhysicalDamage); + totalStats.TotalMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage + stats.TotalMagicDamage); + totalStats.TotalRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage + stats.TotalRealDamage); + totalStats.TotalTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage + stats.TotalTakenDamage); + totalStats.TotalTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage + stats.TotalTakenPhysicalDamage); + totalStats.TotalTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage + stats.TotalTakenMagicDamage); + totalStats.TotalTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage + stats.TotalTakenRealDamage); + totalStats.LiveRound += stats.LiveRound; + totalStats.ActionTurn += stats.ActionTurn; + totalStats.LiveTime = Calculation.Round2Digits(totalStats.LiveTime + stats.LiveTime); + totalStats.TotalEarnedMoney += stats.TotalEarnedMoney; + totalStats.Kills += stats.Kills; + totalStats.Deaths += stats.Deaths; + totalStats.Assists += stats.Assists; + totalStats.LastRank = stats.LastRank; + double totalRank = totalStats.AvgRank * totalStats.Plays + totalStats.LastRank; + totalStats.Plays += stats.Plays; + if (totalStats.Plays != 0) totalStats.AvgRank = Calculation.Round2Digits(totalRank / totalStats.Plays); + totalStats.Wins += stats.Wins; + totalStats.Top3s += stats.Top3s; + totalStats.Loses += stats.Loses; + if (totalStats.Plays != 0) + { + totalStats.AvgDamage = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.Plays); + totalStats.AvgPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage / totalStats.Plays); + totalStats.AvgMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage / totalStats.Plays); + totalStats.AvgRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage / totalStats.Plays); + totalStats.AvgTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage / totalStats.Plays); + totalStats.AvgTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage / totalStats.Plays); + totalStats.AvgTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage / totalStats.Plays); + totalStats.AvgTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage / totalStats.Plays); + totalStats.AvgLiveRound = totalStats.LiveRound / totalStats.Plays; + totalStats.AvgActionTurn = totalStats.ActionTurn / totalStats.Plays; + totalStats.AvgLiveTime = Calculation.Round2Digits(totalStats.LiveTime / totalStats.Plays); + totalStats.AvgEarnedMoney = totalStats.TotalEarnedMoney / totalStats.Plays; + totalStats.Winrates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Wins) / Convert.ToDouble(totalStats.Plays)); + totalStats.Top3rates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Top3s) / Convert.ToDouble(totalStats.Plays)); + } + if (totalStats.LiveRound != 0) totalStats.DamagePerRound = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveRound); + if (totalStats.ActionTurn != 0) totalStats.DamagePerTurn = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.ActionTurn); + if (totalStats.LiveTime != 0) totalStats.DamagePerSecond = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveTime); + } + } + + // 显示每个角色的信息 + for (i = actionQueue.Eliminated.Count - 1; i >= 0; i--) + { + Character character = actionQueue.Eliminated[i]; + SendAllGamingMessage(data, $"=== 角色 [ {character} ] ===\r\n{character.GetInfo()}"); + } + + lock (StatsConfig) + { + foreach (Character c in CharacterStatistics.Keys) + { + StatsConfig.Add(c.ToStringWithOutUser(), CharacterStatistics[c]); + } + StatsConfig.SaveConfig(); + } + + // 结束 + SendAll(SocketMessageType.EndGame, Room, Users); + foreach (IServerModel model in All.Values) + { + model.NowGamingServer = null; + } + ConnectedUsers.Clear(); + } + catch (Exception e) + { + TXTHelper.AppendErrorLog(e.ToString()); + } + } + + public static void 空投(ActionQueue queue, double totalTime) + { + Item[] 这次发放的空投; + if (totalTime == 0) + { + foreach (Character character in queue.Queue) + { + 这次发放的空投 = [new 攻击之爪50()]; + foreach (Item item in 这次发放的空投) + { + queue.Equip(character, EquipItemToSlot.Accessory1, item); + } + } + } + } + + public void SendAllGamingMessage(Dictionary data, string str, bool showmessage = false) + { + data.Clear(); + data.Add("msg", str); + data.Add("showmessage", showmessage); + SendAllGamingMessage(GamingType.UpdateInfo, data); + } + + public override void AfterLoad(params object[] args) + { + foreach (Character c in GameModuleDepend.Characters) + { + Character character = c.Copy(); + Characters.Add(character); + CharacterStatistics.Add(character, new()); + } + + StatsConfig.LoadConfig(); + foreach (Character character in CharacterStatistics.Keys) + { + if (StatsConfig.ContainsKey(character.ToStringWithOutUser())) + { + CharacterStatistics[character] = StatsConfig.Get(character.ToStringWithOutUser()) ?? CharacterStatistics[character]; + } + } + } + + protected Room Room = General.HallInstance; + protected List Users = []; + protected IServerModel? RoomMaster; + protected Dictionary All = []; + + protected void SendAllGamingMessage(GamingType type, Dictionary data) + { + // 循环服务线程,向所有玩家发送局内消息 + foreach (IServerModel s in All.Values) + { + if (s != null && s.Socket != null) + { + s.Send(s.Socket, SocketMessageType.Gaming, type, data); + } + } + } + + protected void SendGamingMessage(string username, GamingType type, Dictionary data) + { + // 向指定玩家发送局内消息 + IServerModel s = All[username]; + if (s != null && s.Socket != null) + { + s.Send(s.Socket, SocketMessageType.Gaming, type, data); + } + } + + protected void SendAll(SocketMessageType type, params object[] args) + { + // 循环服务线程,向所有玩家发送消息 + foreach (IServerModel s in All.Values) + { + if (s != null && s.Socket != null) + { + s.Send(s.Socket, type, args); + } + } + } + + protected void Send(string username, SocketMessageType type, params object[] args) + { + // 向指定玩家发送消息 + IServerModel s = All[username]; + if (s != null && s.Socket != null) + { + s.Send(s.Socket, type, args); + } + } + } +} diff --git a/OshimaServers/OshimaServers.csproj b/OshimaServers/OshimaServers.csproj new file mode 100644 index 0000000..0ccb7f1 --- /dev/null +++ b/OshimaServers/OshimaServers.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + ..\bin\ + Oshima Studios + Oshima.FunGame.$(MSBuildProjectName.Replace(" ", "_")) + + + + + + + + + ..\..\FunGame.Core\bin\Debug\net8.0\FunGame.Core.dll + + + + diff --git a/README.md b/README.md index 214f807..2d15c08 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# Oshima Studios定制的FunGame游戏模组 +# FunGame 定制模组 + +Oshima Studios 巨献 + +设定可参考:[Oshima Core 文档 | 喔 是吗?](https://docs.milimoe.com) + +FunGame 原项目地址:[https://github.com/project-redbud/FunGame-Core](https://github.com/project-redbud/FunGame-Core) diff --git a/实体编辑器.lnk b/实体编辑器.lnk new file mode 100644 index 0000000..ab31c0d Binary files /dev/null and b/实体编辑器.lnk differ