You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
7.5 KiB
226 lines
7.5 KiB
using Build_God_Api.DB;
|
|
using Build_God_Api.Dto;
|
|
using SqlSugar;
|
|
using System.ComponentModel;
|
|
|
|
namespace Build_God_Api.Services
|
|
{
|
|
public interface IScrapService
|
|
{
|
|
Task<List<ScrapDto>> GetAllActiveScrapsAsync();
|
|
Task<ScrapScanResultDto> ScanAndAssignScrapAsync(int characterId);
|
|
Task<List<ScrapHistoryDto>> GetCharacterScrapHistoryAsync(int characterId);
|
|
Task<List<Scrap>> GetAllScrapsAsync();
|
|
Task<bool> AddScrapAsync(ScrapDto dto);
|
|
Task<bool> UpdateScrapAsync(ScrapDto dto);
|
|
Task<bool> DeleteScrapAsync(int id);
|
|
}
|
|
|
|
public class ScrapService(ISqlSugarClient db) : IScrapService
|
|
{
|
|
private readonly ISqlSugarClient db = db;
|
|
|
|
private static readonly Dictionary<ScrapLevel, string> LevelColors = new()
|
|
{
|
|
{ ScrapLevel.White, "#FFFFFF" },
|
|
{ ScrapLevel.Green, "#00FF00" },
|
|
{ ScrapLevel.Blue, "#0077FF" },
|
|
{ ScrapLevel.Purple, "#9932CC" },
|
|
{ ScrapLevel.Orange, "#FF8C00" }
|
|
};
|
|
|
|
private static readonly Dictionary<ScrapLevel, int> LevelWeights = new()
|
|
{
|
|
{ ScrapLevel.White, 50 },
|
|
{ ScrapLevel.Green, 30 },
|
|
{ ScrapLevel.Blue, 15 },
|
|
{ ScrapLevel.Purple, 4 },
|
|
{ ScrapLevel.Orange, 1 }
|
|
};
|
|
|
|
public async Task<List<ScrapDto>> GetAllActiveScrapsAsync()
|
|
{
|
|
var scraps = await db.Queryable<Scrap>()
|
|
.Where(x => x.IsActive)
|
|
.OrderBy(x => x.Level)
|
|
.ToListAsync();
|
|
|
|
return scraps.Select(MapToDto).ToList();
|
|
}
|
|
|
|
public async Task<ScrapScanResultDto> ScanAndAssignScrapAsync(int characterId)
|
|
{
|
|
var character = await db.Queryable<Character>().FirstAsync(x => x.Id == characterId)
|
|
?? throw new Exception("角色不存在");
|
|
|
|
var scraps = await db.Queryable<Scrap>()
|
|
.Where(x => x.IsActive)
|
|
.ToListAsync();
|
|
|
|
if (scraps.Count == 0)
|
|
{
|
|
throw new Exception("目前没有可捡的垃圾");
|
|
}
|
|
|
|
var selectedLevel = SelectRandomLevel();
|
|
var levelScraps = scraps.Where(x => x.Level == selectedLevel).ToList();
|
|
|
|
if (levelScraps.Count == 0)
|
|
{
|
|
levelScraps = scraps;
|
|
}
|
|
|
|
var random = new Random();
|
|
var selectedScrap = levelScraps[random.Next(levelScraps.Count)];
|
|
|
|
var characterScrap = new CharacterScrap
|
|
{
|
|
CharacterId = characterId,
|
|
ScrapId = selectedScrap.Id,
|
|
CreatedBy = characterId,
|
|
UpdatedBy = characterId
|
|
};
|
|
await db.Insertable(characterScrap).ExecuteCommandAsync();
|
|
|
|
character.Attack += selectedScrap.AttackBonus;
|
|
character.MaxHP += selectedScrap.HpBonus;
|
|
await db.Updateable(character).ExecuteCommandAsync();
|
|
|
|
return new ScrapScanResultDto
|
|
{
|
|
Scrap = MapToDto(selectedScrap),
|
|
AttackGain = selectedScrap.AttackBonus,
|
|
DefenseGain = selectedScrap.DefenseBonus,
|
|
HpGain = selectedScrap.HpBonus,
|
|
MagicGain = selectedScrap.MagicBonus
|
|
};
|
|
}
|
|
|
|
public async Task<List<ScrapHistoryDto>> GetCharacterScrapHistoryAsync(int characterId)
|
|
{
|
|
var history = await db.Queryable<CharacterScrap>()
|
|
.Where(x => x.CharacterId == characterId)
|
|
.OrderByDescending(x => x.ObtainedAt)
|
|
.ToListAsync();
|
|
|
|
var result = new List<ScrapHistoryDto>();
|
|
foreach (var item in history)
|
|
{
|
|
var scrap = await db.Queryable<Scrap>().FirstAsync(x => x.Id == item.ScrapId);
|
|
if (scrap != null)
|
|
{
|
|
result.Add(new ScrapHistoryDto
|
|
{
|
|
Id = item.Id,
|
|
Scrap = MapToDto(scrap),
|
|
ObtainedAt = item.ObtainedAt
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private ScrapLevel SelectRandomLevel()
|
|
{
|
|
var random = new Random();
|
|
int totalWeight = LevelWeights.Values.Sum();
|
|
int randomValue = random.Next(totalWeight);
|
|
|
|
int cumulativeWeight = 0;
|
|
foreach (var kvp in LevelWeights.OrderBy(x => x.Key))
|
|
{
|
|
cumulativeWeight += kvp.Value;
|
|
if (randomValue < cumulativeWeight)
|
|
{
|
|
return kvp.Key;
|
|
}
|
|
}
|
|
|
|
return ScrapLevel.White;
|
|
}
|
|
|
|
private static ScrapDto MapToDto(Scrap scrap)
|
|
{
|
|
var levelEnum = scrap.Level;
|
|
var description = GetEnumDescription(levelEnum);
|
|
|
|
return new ScrapDto
|
|
{
|
|
Id = scrap.Id,
|
|
Name = scrap.Name,
|
|
Description = scrap.Description,
|
|
Story = scrap.Story,
|
|
Level = (int)scrap.Level,
|
|
LevelName = description,
|
|
LevelColor = LevelColors.GetValueOrDefault(scrap.Level, "#FFFFFF"),
|
|
AttackBonus = scrap.AttackBonus,
|
|
DefenseBonus = scrap.DefenseBonus,
|
|
HpBonus = scrap.HpBonus,
|
|
MagicBonus = scrap.MagicBonus
|
|
};
|
|
}
|
|
|
|
private static string GetEnumDescription(ScrapLevel level)
|
|
{
|
|
var field = level.GetType().GetField(level.ToString());
|
|
var attribute = field?.GetCustomAttributes(typeof(DescriptionAttribute), false)
|
|
.FirstOrDefault() as DescriptionAttribute;
|
|
return attribute?.Description ?? level.ToString();
|
|
}
|
|
|
|
public async Task<List<Scrap>> GetAllScrapsAsync()
|
|
{
|
|
return await db.Queryable<Scrap>()
|
|
.OrderBy(x => x.Level)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<bool> AddScrapAsync(ScrapDto dto)
|
|
{
|
|
var scrap = new Scrap
|
|
{
|
|
Name = dto.Name,
|
|
Description = dto.Description,
|
|
Story = dto.Story,
|
|
Level = (ScrapLevel)dto.Level,
|
|
AttackBonus = dto.AttackBonus,
|
|
DefenseBonus = dto.DefenseBonus,
|
|
HpBonus = dto.HpBonus,
|
|
MagicBonus = dto.MagicBonus,
|
|
IsActive = dto.IsActive
|
|
};
|
|
|
|
await db.Insertable(scrap).ExecuteCommandAsync();
|
|
return true;
|
|
}
|
|
|
|
public async Task<bool> UpdateScrapAsync(ScrapDto dto)
|
|
{
|
|
var scrap = await db.Queryable<Scrap>().FirstAsync(x => x.Id == dto.Id);
|
|
if (scrap == null)
|
|
{
|
|
throw new Exception("垃圾不存在");
|
|
}
|
|
|
|
scrap.Name = dto.Name;
|
|
scrap.Description = dto.Description;
|
|
scrap.Story = dto.Story;
|
|
scrap.Level = (ScrapLevel)dto.Level;
|
|
scrap.AttackBonus = dto.AttackBonus;
|
|
scrap.DefenseBonus = dto.DefenseBonus;
|
|
scrap.HpBonus = dto.HpBonus;
|
|
scrap.MagicBonus = dto.MagicBonus;
|
|
scrap.IsActive = dto.IsActive;
|
|
|
|
await db.Updateable(scrap).ExecuteCommandAsync();
|
|
return true;
|
|
}
|
|
|
|
public async Task<bool> DeleteScrapAsync(int id)
|
|
{
|
|
await db.Deleteable<Scrap>().Where(x => x.Id == id).ExecuteCommandAsync();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|