文字游戏
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

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;
}
}
}