Skip to content

Commit a3f536d

Browse files
authored
添加与完善经验系统 (#17)
* 忘改版本号力 * EX依赖更新 * 完善等级系统并进行代码清理 * 内嵌增加经验指令 * U README.md * 属性调成公开 * 添加AddExp方便调用 * 虚!
1 parent 1e8d87a commit a3f536d

23 files changed

+182
-102
lines changed

Commands/ExpCommand.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using CommandSystem;
2+
using Exiled.API.Features;
3+
using Exiled.Permissions.Extensions;
4+
using System;
5+
using YongAnFrame;
6+
using YongAnFrame.Commands;
7+
8+
namespace BAPlugin.Command
9+
{
10+
[CommandHandler(typeof(RemoteAdminCommandHandler))]
11+
public class ExpCommand : ICommand
12+
{
13+
public string Command => "experience";
14+
15+
public string[] Aliases => ["pexp"];
16+
17+
public string Description => "用于经验的设置";
18+
19+
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
20+
{
21+
response = "NO";
22+
if (sender.CheckPermission("yongan404.level.add"))
23+
{
24+
if (arguments.Array.Length > 2)
25+
{
26+
Player.Get(arguments.Array[1]).ToFPlayer().Level += ulong.Parse(arguments.Array[2]);
27+
response = "OK";
28+
return true;
29+
}
30+
}
31+
else
32+
{
33+
response = "请保证你有yongan404.level.add权限";
34+
}
35+
36+
return false;
37+
}
38+
}
39+
}

Commands/MessageCommand.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ namespace YongAnFrame.Commands
1111
/// 发送消息指令
1212
/// </summary>
1313
[CommandHandler(typeof(RemoteAdminCommandHandler))]
14-
public sealed class MessageCommand : CommandPlus
14+
public sealed class MessageCommand : ICommand
1515
{
16-
public override string Command => "message";
16+
public string Command => "message";
1717

18-
public override string[] Aliases => ["mes", "msg"];
18+
public string[] Aliases => ["mes", "msg"];
1919

20-
public override string Description => "用于发送消息";
20+
public string Description => "用于发送消息";
2121

22-
public override bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
22+
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
2323
{
2424
List<FramePlayer> choicePlayer = [];
2525
if (arguments.Count < 3)

Commands/PlayerCommand.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
using CommandSystem;
22
using Exiled.API.Features;
33
using System;
4-
using System.Collections.Generic;
5-
using System.Linq;
6-
using System.Text;
7-
using System.Threading.Tasks;
84
using YongAnFrame.Players;
95

106
namespace YongAnFrame.Commands
@@ -30,14 +26,11 @@ public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out s
3026
{
3127
FramePlayer fPlayer = FramePlayer.Get(player);
3228
fPlayer.HintManager.Clean();
33-
string[] text = new string[36];
34-
35-
fPlayer.ExPlayer.ShowHint($"<size=20>{string.Join("\n", text)}\n\n\n\n\n\n\n\n\n\n\n\n\n\n</size>", 10000f);
29+
fPlayer.ExPlayer.ShowHint($"<size=20>{YongAnFramePlugin.Instance.Config.BypassDoNotTrackText.Split('\n')}</size>", 10000f);
3630
}
37-
3831
return true;
3932
}
40-
33+
4134
}
4235
return false;
4336
}

Commands/SkillCommand.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ namespace YongAnFrame.Commands
88
/// 未完成请勿乱用
99
/// </summary>
1010
[CommandHandler(typeof(ClientCommandHandler))]
11-
public sealed class SkillsCommand : CommandPlus
11+
public sealed class SkillsCommand : ICommand
1212
{
13-
public override string Command => "skills";
13+
public string Command => "skills";
1414

15-
public override string[] Aliases => ["sk"];
15+
public string[] Aliases => ["sk"];
1616

17-
public override string Description => "skills";
17+
public string Description => "skills";
1818

19-
public override bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
19+
public bool Execute(ArraySegment<string> arguments, ICommandSender sender, out string response)
2020
{
2121
response = "NO";
2222

Components/CapacityList.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using Exiled.API.Features;
2-
using System;
3-
using System.Collections;
4-
using System.Collections.Generic;
5-
using System.Linq;
6-
using System.Text;
7-
using System.Threading.Tasks;
1+
using System.Collections.Generic;
82

93
namespace YongAnFrame.Components
104
{
@@ -16,9 +10,9 @@ public class CapacityList<T>(int capacity)
1610

1711
public int Count => list.Count;
1812

19-
public T this[int index]
20-
{
21-
get
13+
public T this[int index]
14+
{
15+
get
2216
{
2317
if (Count > index)
2418
{

Events/EventArgs/FramePlayer/FramePlayerInvalidingEventArgs.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ namespace YongAnFrame.Events.EventArgs.FramePlayer
55
/// <summary>
66
/// FramePlayer被无效时的事件数据
77
/// </summary>
8-
public sealed class FramePlayerInvalidatingEventArgs : IExiledEvent
8+
public sealed class FramePlayerInvalidatingEventArgs(Players.FramePlayer fPlayer) : IExiledEvent
99
{
10-
public Players.FramePlayer FPlayer { get; }
11-
12-
public FramePlayerInvalidatingEventArgs(Players.FramePlayer fPlayer)
13-
{
14-
FPlayer = fPlayer;
15-
}
10+
public Players.FramePlayer FPlayer { get; } = fPlayer;
1611
}
1712
}

Events/Handlers/FramePlayer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ public sealed class FramePlayer
1313
/// FramePlayer被无效时的事件
1414
/// </summary>
1515
public static Event<FramePlayerInvalidatingEventArgs> FramePlayerInvalidating { get; set; } = new Event<FramePlayerInvalidatingEventArgs>();
16+
/// <summary>
17+
/// FramePlayer提示刷新前的事件
18+
/// </summary>
19+
public static Event FramePlayerHintUpdate { get; set; } = new Event();
1620

1721
public static void OnFramePlayerCreated(FramePlayerCreatedEventArgs args)
1822
{
1923
FramePlayerCreated.InvokeSafely(args);
2024
}
25+
public static void OnFramerHintUpdate()
26+
{
27+
FramePlayerHintUpdate.InvokeSafely();
28+
}
2129
public static void OnFramePlayerInvalidating(FramePlayerInvalidatingEventArgs args)
2230
{
2331
FramePlayerInvalidating.InvokeSafely(args);

Players/CustomPlayer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ public abstract class CustomPlayer(FramePlayer player)
44
{
55
public FramePlayer FramePlayer { get; private set; } = player;
66
public bool IsInvalid => FramePlayer == null;
7+
public float ExpMultiplier { get { return FramePlayer.ExpMultiplier; } set { FramePlayer.ExpMultiplier = value; } }
8+
public ulong Exp { get { return FramePlayer.Exp; } set { FramePlayer.Exp = value; } }
79
public ulong Level { get { return FramePlayer.Level; } set { FramePlayer.Level = value; } }
810
public HintManager HintManager => FramePlayer.HintManager;
911
public PlayerTitle UsingTitles { get { return FramePlayer.UsingTitles; } set { FramePlayer.UsingTitles = value; } }
1012
public PlayerTitle UsingRankTitles { get { return FramePlayer.UsingRankTitles; } set { FramePlayer.UsingRankTitles = value; } }
1113

14+
public void AddExp(ulong exp, string name = "未知原因")
15+
{
16+
FramePlayer.AddExp(exp, name);
17+
}
18+
1219
public virtual void Invalid()
1320
{
1421
FramePlayer = null;

Players/FramePlayer.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
using Exiled.Events.EventArgs.Player;
44
using Exiled.Events.Features;
55
using MEC;
6+
using System;
67
using System.Collections.Generic;
7-
using System.Linq;
88
using YongAnFrame.Events.EventArgs.FramePlayer;
99
using YongAnFrame.Roles;
10+
using static YongAnFrame.Players.HintManager;
1011

1112
namespace YongAnFrame.Players
1213
{
13-
public sealed class FramePlayer
14+
public sealed class FramePlayer : ICustomAlgorithm
1415
{
1516
private PlayerTitle usingTitles = null;
1617
private PlayerTitle usingRankTitles = null;
@@ -31,7 +32,8 @@ public sealed class FramePlayer
3132
/// <summary>
3233
/// 实例拥有的自定义角色
3334
/// </summary>
34-
public CustomRolePlus CustomRolePlus {
35+
public CustomRolePlus CustomRolePlus
36+
{
3537
get
3638
{
3739
if (ExPlayer.GetCustomRoles().Count != 0)
@@ -45,11 +47,25 @@ public CustomRolePlus CustomRolePlus {
4547
/// 提示系统管理器
4648
/// </summary>
4749
public HintManager HintManager { get; private set; }
50+
51+
/// <summary>
52+
/// 正在使用的主要自定义算法
53+
/// </summary>
54+
public ICustomAlgorithm CustomAlgorithm { get; set; }
55+
4856
/// <summary>
4957
/// 玩家等级
5058
/// </summary>
5159
public ulong Level { get; set; }
5260
/// <summary>
61+
/// 玩家经验
62+
/// </summary>
63+
public ulong Exp { get; set; }
64+
/// <summary>
65+
/// 玩家经验倍率
66+
/// </summary>
67+
public float ExpMultiplier { get; set; }
68+
/// <summary>
5369
/// 玩家批准绕过DNT
5470
/// </summary>
5571
public bool IsBDNT { get; set; }
@@ -104,9 +120,36 @@ internal FramePlayer(Player player)
104120
ExPlayer = player;
105121
HintManager = new HintManager(this);
106122
dictionary.Add(ExPlayer.Id, this);
123+
CustomAlgorithm = this;
107124
Events.Handlers.FramePlayer.OnFramePlayerCreated(new FramePlayerCreatedEventArgs(this));
108125
}
109126

127+
public void AddExp(ulong exp, string name = "未知原因")
128+
{
129+
float globalExpMultiplier = YongAnFramePlugin.Instance.Config.GlobalExpMultiplier;
130+
float expMultiplier = ExpMultiplier * globalExpMultiplier;
131+
ulong addExp = (ulong)(exp * expMultiplier);
132+
133+
Exp += addExp;
134+
HintManager.MessageTexts.Add(new Text($"{name},获得{exp}+{addExp - exp}经验({expMultiplier}倍经验)", 5));
135+
136+
ulong needExp = CustomAlgorithm.GetNeedUpLevel(Level);
137+
ulong oldLevel = Level;
138+
while (Exp >= needExp)
139+
{
140+
Log.Debug($"{Exp}/{needExp}");
141+
Level++;
142+
Exp -= needExp;
143+
needExp = CustomAlgorithm.GetNeedUpLevel(Level);
144+
}
145+
if (oldLevel < Level)
146+
{
147+
UpdateShowInfoList();
148+
HintManager.MessageTexts.Add(new Text($"恭喜你从{oldLevel}级到达{Level}级,距离下一级需要{Exp}/{needExp}经验", 8));
149+
}
150+
}
151+
152+
110153
#region ShowRank
111154

112155
private readonly CoroutineHandle[] coroutines = new CoroutineHandle[2];
@@ -236,6 +279,11 @@ private IEnumerator<float> DynamicTitlesShow()
236279
}
237280
#endregion
238281

282+
public ulong GetNeedUpLevel(ulong level)
283+
{
284+
return (ulong)(100 + Math.Floor(level / 10f) * 100);
285+
}
286+
239287
/// <summary>
240288
/// 获取框架玩家
241289
/// </summary>

Players/HintManager.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using Exiled.API.Features;
2-
using MEC;
1+
using MEC;
32
using System.Collections.Generic;
4-
using System.Reflection;
53
using YongAnFrame.Components;
64

75
namespace YongAnFrame.Players
@@ -31,23 +29,24 @@ public IEnumerator<float> Update()
3129
{
3230
while (true)
3331
{
32+
Events.Handlers.FramePlayer.OnFramerHintUpdate();
3433
string[] text = new string[36];
3534

3635
int used = 0;
37-
text[used] = $"YongAnFrame 1.0.0-alpha7";
36+
text[used] = $"YongAnFrame 1.0.0-Beta1";
3837

3938
if (fPlayer.ExPlayer.DoNotTrack && !fPlayer.IsBDNT)
4039
{
4140
text[used] = "[注意]已开启DoNotTrack(DNT),游戏数据不会被保存,想保存数据请控制台输入pl BDNT查看详情";
4241
}
43-
42+
4443
used = 1;
4544
text[used] = "<align=left>";
4645

4746
for (int i = 0; i < ChatTexts.Capacity; i++)
4847
{
4948
Text chatText = ChatTexts[i];
50-
if(chatText != null)
49+
if (chatText != null)
5150
{
5251
text[used] += chatText;
5352
chatText.Duration--;
@@ -109,16 +108,10 @@ public void Clean()
109108
Timing.KillCoroutines(coroutine);
110109
}
111110

112-
public class Text
111+
public class Text(string text, float duration, int size = 0)
113112
{
114-
public string Content { get; private set; }
115-
public float Duration { get; internal set; }
116-
117-
public Text(string text, float duration, int size = 0)
118-
{
119-
Content = text;
120-
Duration = duration;
121-
}
113+
public string Content { get; private set; } = text;
114+
public float Duration { get; internal set; } = duration;
122115

123116
public override string ToString()
124117
{

0 commit comments

Comments
 (0)