diff --git a/Build_God_Api/Build_God_Api/Services/CharacterService.cs b/Build_God_Api/Build_God_Api/Services/CharacterService.cs
index 01294d3..d24f66c 100644
--- a/Build_God_Api/Build_God_Api/Services/CharacterService.cs
+++ b/Build_God_Api/Build_God_Api/Services/CharacterService.cs
@@ -104,8 +104,14 @@ namespace Build_God_Api.Services
return true;
}
+ // 存储的突破率可能为 0(新建角色未初始化)或历史数据低于当前境界基础概率;
+ // 实际判定应至少使用当前境界 BaseBreakthroughRate,失败累加也要在“不低于基础”之上再加 FailIncrement。
+ var rateForRoll = character.BreakthroughRate < currentLevel!.BaseBreakthroughRate
+ ? currentLevel.BaseBreakthroughRate
+ : character.BreakthroughRate;
+
decimal randomValue = GenerateSecureRandomDecimal(0, 100, 1);
- bool isSuccess = randomValue < character.BreakthroughRate;
+ bool isSuccess = randomValue < rateForRoll;
if (isSuccess)
{
@@ -116,7 +122,9 @@ namespace Build_God_Api.Services
}
else
{
- character.BreakthroughRate += currentLevel!.FailIncrement;
+ if (character.BreakthroughRate < currentLevel.BaseBreakthroughRate)
+ character.BreakthroughRate = currentLevel.BaseBreakthroughRate;
+ character.BreakthroughRate += currentLevel.FailIncrement;
if (character.BreakthroughRate > 100)
{
character.BreakthroughRate = 100;
@@ -176,13 +184,12 @@ namespace Build_God_Api.Services
/// 随机数
private decimal GenerateSecureRandomDecimal(decimal min, decimal max, int decimalPlaces)
{
- byte[] randomBytes = new byte[4];
+ Span randomBytes = stackalloc byte[4];
_rng.GetBytes(randomBytes);
- int randomInt = BitConverter.ToInt32(randomBytes, 0);
-
- decimal randomDecimal = (decimal)Math.Abs(randomInt) / int.MaxValue;
- decimal result = min + (randomDecimal * (max - min));
-
+ var u = BitConverter.ToUInt32(randomBytes);
+ // [0, uint.MaxValue] -> [0m, 1m],避免 int.MinValue 时 Math.Abs 溢出
+ decimal randomUnit = (decimal)u / uint.MaxValue;
+ decimal result = min + randomUnit * (max - min);
return Math.Round(result, decimalPlaces);
}
@@ -338,17 +345,20 @@ namespace Build_God_Api.Services
throw new Exception("每个账号最多只能创建3个角色");
}
+ const int startLevelId = 10;
+ var startLevel = await db.Queryable().FirstAsync(x => x.LevelId == startLevelId);
+
Character newOne = new()
{
Name = character.Name,
AccountId = currentUserService.UserId,
CurrentExp = 0,
- LevelId = 10,
+ LevelId = startLevelId,
Money = 0,
CurrentHP = 100,
ProfessionId = character.ProfessionId,
SpiritFieldId = 0,
- BreakthroughRate = 0,
+ BreakthroughRate = startLevel?.BaseBreakthroughRate ?? 0,
LastLogin = DateTime.Now
};