|
|
@ -7,7 +7,7 @@ using static Build_God_Api.DB.BagItem; |
|
|
|
|
|
|
|
|
namespace Build_God_Api.Services |
|
|
namespace Build_God_Api.Services |
|
|
{ |
|
|
{ |
|
|
public interface ICharacterService |
|
|
public interface ICharacterService |
|
|
{ |
|
|
{ |
|
|
public Task<Character?> GetCharacterByAccountId(int accountId); |
|
|
public Task<Character?> GetCharacterByAccountId(int accountId); |
|
|
public Task<List<Character>> GetCharactersByAccountId(int accountId); |
|
|
public Task<List<Character>> GetCharactersByAccountId(int accountId); |
|
|
@ -44,7 +44,7 @@ public interface ICharacterService |
|
|
public Task<decimal> StopTraining(int characterId); |
|
|
public Task<decimal> StopTraining(int characterId); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public class CharacterService(ISqlSugarClient db, |
|
|
public class CharacterService(ISqlSugarClient db, |
|
|
ICurrentUserService currentUserService, |
|
|
ICurrentUserService currentUserService, |
|
|
ICharacterAttributeCalculateService calculateService, |
|
|
ICharacterAttributeCalculateService calculateService, |
|
|
IBagService bagService, |
|
|
IBagService bagService, |
|
|
@ -62,7 +62,7 @@ public interface ICharacterService |
|
|
var currentLevel = await db.Queryable<Level>().FirstAsync(x => x.LevelId == character.LevelId); |
|
|
var currentLevel = await db.Queryable<Level>().FirstAsync(x => x.LevelId == character.LevelId); |
|
|
var nextLevelId = currentLevel?.NextLevelId ?? 1; |
|
|
var nextLevelId = currentLevel?.NextLevelId ?? 1; |
|
|
var nextLevel = await db.Queryable<Level>().FirstAsync(x => x.LevelId == nextLevelId) ?? throw new Exception("你暂时无敌了,没有等级可以突破了"); |
|
|
var nextLevel = await db.Queryable<Level>().FirstAsync(x => x.LevelId == nextLevelId) ?? throw new Exception("你暂时无敌了,没有等级可以突破了"); |
|
|
|
|
|
|
|
|
if (character.CurrentExp < nextLevel.CurrentLevelMinExp) |
|
|
if (character.CurrentExp < nextLevel.CurrentLevelMinExp) |
|
|
{ |
|
|
{ |
|
|
throw new Exception($"距离可以突破你还差 {nextLevel.CurrentLevelMinExp - character.CurrentExp}"); |
|
|
throw new Exception($"距离可以突破你还差 {nextLevel.CurrentLevelMinExp - character.CurrentExp}"); |
|
|
@ -106,7 +106,7 @@ public interface ICharacterService |
|
|
|
|
|
|
|
|
decimal randomValue = GenerateSecureRandomDecimal(0, 100, 1); |
|
|
decimal randomValue = GenerateSecureRandomDecimal(0, 100, 1); |
|
|
bool isSuccess = randomValue < character.BreakthroughRate; |
|
|
bool isSuccess = randomValue < character.BreakthroughRate; |
|
|
|
|
|
|
|
|
if (isSuccess) |
|
|
if (isSuccess) |
|
|
{ |
|
|
{ |
|
|
character.LevelId = nextLevelId; |
|
|
character.LevelId = nextLevelId; |
|
|
@ -122,16 +122,16 @@ public interface ICharacterService |
|
|
character.BreakthroughRate = 100; |
|
|
character.BreakthroughRate = 100; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async Task<bool> StartTraining(int characterId) |
|
|
public async Task<bool> StartTraining(int characterId) |
|
|
{ |
|
|
{ |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId) |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId) |
|
|
?? throw new Exception("角色不存在"); |
|
|
?? throw new Exception("角色不存在"); |
|
|
|
|
|
|
|
|
if (character.TrainingOn.HasValue) |
|
|
if (character.TrainingOn.HasValue) |
|
|
{ |
|
|
{ |
|
|
throw new Exception("你已经在打坐了"); |
|
|
throw new Exception("你已经在打坐了"); |
|
|
@ -144,7 +144,7 @@ public interface ICharacterService |
|
|
|
|
|
|
|
|
public async Task<decimal> StopTraining(int characterId) |
|
|
public async Task<decimal> StopTraining(int characterId) |
|
|
{ |
|
|
{ |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId) |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId) |
|
|
?? throw new Exception("角色不存在"); |
|
|
?? throw new Exception("角色不存在"); |
|
|
|
|
|
|
|
|
if (!character.TrainingOn.HasValue) |
|
|
if (!character.TrainingOn.HasValue) |
|
|
@ -153,16 +153,16 @@ public interface ICharacterService |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var duration = DateTime.Now - character.TrainingOn.Value; |
|
|
var duration = DateTime.Now - character.TrainingOn.Value; |
|
|
var seconds = (decimal)duration.TotalSeconds; |
|
|
var seconds = duration.TotalSeconds; |
|
|
|
|
|
|
|
|
// exp = 0.1 * seconds * level * level * (1 + buff)
|
|
|
|
|
|
var expGained = 0.01m * seconds * character.LevelId * character.LevelId * (1 + 0); |
|
|
|
|
|
|
|
|
|
|
|
character.CurrentExp += Math.Round(expGained); |
|
|
// exp = 0.02 * seconds * level^1.5 * (1 + buff)
|
|
|
|
|
|
var expGained = Convert.ToDecimal(0.02 * seconds * Math.Pow(character.LevelId, 1.5) * (1 + 0)); |
|
|
|
|
|
var result = Math.Round(expGained); |
|
|
|
|
|
character.CurrentExp += result; |
|
|
character.TrainingOn = null; |
|
|
character.TrainingOn = null; |
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
|
|
|
|
|
|
return expGained; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); |
|
|
private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); |
|
|
@ -196,7 +196,7 @@ public interface ICharacterService |
|
|
|
|
|
|
|
|
public async Task<bool> SelectCharacter(int characterId) |
|
|
public async Task<bool> SelectCharacter(int characterId) |
|
|
{ |
|
|
{ |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId && x.AccountId == currentUserService.UserId && x.isLocked == false) |
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId && x.AccountId == currentUserService.UserId && x.isLocked == false) |
|
|
?? throw new Exception("角色不存在"); |
|
|
?? throw new Exception("角色不存在"); |
|
|
character.LastLogin = DateTime.Now; |
|
|
character.LastLogin = DateTime.Now; |
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
await db.Updateable(character).ExecuteCommandAsync(); |
|
|
@ -211,7 +211,7 @@ public interface ICharacterService |
|
|
return await db.Queryable<Character>().AnyAsync(x => x.Name == name); |
|
|
return await db.Queryable<Character>().AnyAsync(x => x.Name == name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async Task<Character?> GetCharacterByAccountId(int accountId) |
|
|
public async Task<Character?> GetCharacterByAccountId(int accountId) |
|
|
{ |
|
|
{ |
|
|
return await db.Queryable<Character>().FirstAsync(x => x.AccountId == accountId && x.isLocked == false); |
|
|
return await db.Queryable<Character>().FirstAsync(x => x.AccountId == accountId && x.isLocked == false); |
|
|
} |
|
|
} |
|
|
@ -291,7 +291,7 @@ public async Task<Character?> GetCharacterByAccountId(int accountId) |
|
|
NextLevelRequiredPillId = nextLevelRequiredPillId, |
|
|
NextLevelRequiredPillId = nextLevelRequiredPillId, |
|
|
NextLevelRequiredPillName = nextLevelRequiredPillName, |
|
|
NextLevelRequiredPillName = nextLevelRequiredPillName, |
|
|
NextLevelRequiredPillQuantity = nextLevelRequiredPillQuantity, |
|
|
NextLevelRequiredPillQuantity = nextLevelRequiredPillQuantity, |
|
|
TrainingExpRate = 0.01m, |
|
|
TrainingExpRate = 0.02m, |
|
|
LastLogin = c.LastLogin, |
|
|
LastLogin = c.LastLogin, |
|
|
CreatedOn = c.CreatedOn |
|
|
CreatedOn = c.CreatedOn |
|
|
}); |
|
|
}); |
|
|
@ -331,7 +331,7 @@ public async Task<Character?> GetCharacterByAccountId(int accountId) |
|
|
Name = character.Name, |
|
|
Name = character.Name, |
|
|
AccountId = currentUserService.UserId, |
|
|
AccountId = currentUserService.UserId, |
|
|
CurrentExp = 0, |
|
|
CurrentExp = 0, |
|
|
LevelId = 1, |
|
|
LevelId = 10, |
|
|
Money = 0, |
|
|
Money = 0, |
|
|
CurrentHP = 100, |
|
|
CurrentHP = 100, |
|
|
ProfessionId = character.ProfessionId, |
|
|
ProfessionId = character.ProfessionId, |
|
|
|