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