Creating a character is a pivotal aspect of Dungeons & Dragons, as it defines the essence of the player's journey in the fantastical realms.
今天將進行製作腳色之API,其中將重點聚焦於一對一之API開發。
製作角色在龍與地下城中極為重要且令人興奮的一步,亦是讓玩家進入這個幻想世界的第一步,這一過程不僅定義了角色的種族和職業,還決定了角色的背景故事、技能和特殊能力。其中包含命名、確定種族、選擇職業、分配能力值、決定背景、選擇技能等等,完成這些步驟,便準備好踏上冒險之旅。以下是角色製作之API Controller,需使用者登入才可創建:
[Authorize]
[ApiController]
[Route("[controller]")]
public class CharacterController : ControllerBase
{
private readonly CharacterService _characterService;
public CharacterController(CharacterService characterService)
{
_characterService = characterService;
}
}
如同上面所述製作角色是龍與地下城極為重要且令人興奮的一步,若要製作角色則先製作DTO,在建Controller,再以Service新增使用者之角色,並設定AutoMapper:
// 使用者須輸入之角色資料
public class CreateCharacterDto
{
[MaxLength(100)]
[DefaultValue(null)]
public string? Name { get; set; }
[MaxLength(20)]
[DefaultValue(null)]
public string? Race { get; set; }
[MaxLength(20)]
[DefaultValue(null)]
public string? Class { get; set; }
[DefaultValue(null)]
// 上傳圖片
public IFormFile? Avatar { get; set; }
}
[HttpPost]
public async Task<IActionResult> CreateCharacter([FromForm] CreateCharacterDto createCharacter)
{
// 以此法可由jwt抓到使用者之uuid
var uuid = User.Claims.First(claim => claim.Type == "jti").Value;
if (createCharacter == null)
{
return BadRequest("請檢察輸入資料");
}
var result = await _characterService.CreateCharacter(createCharacter, uuid);
return result;
}
public async Task<IActionResult> CreateCharacter(CreateCharacterDto createCharacter, string uuid)
{
var fullSlots = new JsonResult(new { status = "character slots are full" });
var user = _context.UserProfile.Include(e => e.UserCharacters)
.SingleOrDefault(e => e.Uuid.Equals(uuid));
if (user == null) return not_found;
// 使用者腳色數量超過3則角色槽滿
if (user.UserCharacters.Count >= 3) return fullSlots;
// 若角色名稱為null則以使用者名稱之角色為名
createCharacter.Name = createCharacter.Name ?? $"{user.Username}'s character";
var character = new UserCharacters()
{
Name = createCharacter.Name,
Uuid = uuid
};
character = _mapper.Map(createCharacter, character);
_context.UserCharacters.Add(character);
// 建立其他一對一關聯之角色資訊之資料
var details = new CharacterDetails()
{
UserCharacters = character,
Created_At = DateTime.Now,
};
var physical = new PhysicalCharacteristics()
{
UserCharacters = character,
Created_At = DateTime.Now,
};
var personal = new PersonalCharacteristics()
{
UserCharacters = character,
Created_At = DateTime.Now,
};
var notes = new CharacterNotes()
{
UserCharacters = character,
Created_At = DateTime.Now,
};
var ability = new AbilityScores()
{
UserCharacters = character,
Created_At = DateTime.Now,
};
_context.AddRange(details, physical, personal, notes, ability);
try
{
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
return fail;
}
return success;
}
CreateMap<CreateCharacterDto, UserCharacters>()
.ForMember(x => x.Created_At, y => y.MapFrom(o => DateTime.Now))
.ForMember(x => x.Name, y => y.Ignore());
在龍與地下城中,能力值為角色在某一領域之自然天賦,能力值可以影響角色之各種屬性,例如力量、敏捷、體質、智力、感知、魅力。玩家於創建角色時會獲得一定數量之屬性點,可以用來提升能力值,能力值越高,在該領域的表現就越出色。因製作角色時能力值亦會一併建立,並給予預設值,因此在此可以直接製作獲取角色之能力值之API,先製作欲顯示之內容DTO,除能力值外尚有一調整值需考慮,是故還需製作一helper以明調整值,調整值之表,皆完成後便可製作API:
public class GetAbilityDto
{
public string STR { get; set; }
public string DEX { get; set; }
public string CON { get; set; }
public string INT { get; set;}
public string WIS { get; set;}
public string CHA { get; set;}
}
public class ModifierHelper
{
public string AbilityModifier(int ability)
{
switch (ability)
{
case 1:
return $"{ability}(-5)";
case 2 | 3:
return $"{ability}(-4)";
case 4 | 5:
return $"{ability}(-3)";
case 6 | 7:
return $"{ability}(-2)";
case 8 | 9:
return $"{ability}(-1)";
case 10 | 11:
return $"{ability}(+0)";
case 12 | 13:
return $"{ability}(+1)";
case 14 | 15:
return $"{ability}(+2)";
case 16 | 17:
return $"{ability}(+3)";
case 18 | 19:
return $"{ability}(+4)";
case 20 | 21:
return $"{ability}(+5)";
case 22 | 23:
return $"{ability}(+6)";
case 24 | 25:
return $"{ability}(+7)";
case 26 | 27:
return $"{ability}(+8)";
case 28 | 29:
return $"{ability}(+9)";
case 30:
return $"{ability}(+10)";
}
return $"{ability}";
}
}
[HttpGet("ability")]
public async Task<IActionResult> GetAbility([FromForm]string name)
{
var uuid = User.Claims.First(claim => claim.Type == "jti").Value;
if (name == null)
{
return BadRequest("請檢察輸入資料");
}
var result = await _characterService.GetAbility(name, uuid);
return result;
}
public async Task<IActionResult> GetAbility(string name, string uuid)
{
// 將以uuid找出使用者角色,並以角色表之關聯召出能力值之表
var characters = _context.UserCharacters.Include(e => e.AbilityScores)
.SingleOrDefault(e => e.Name.Equals(name) && e.Uuid.Equals(uuid));
if (characters == null) return not_found;
var ability =new GetAbilityDto()
{
STR = _modifierHelper.AbilityModifier(characters.AbilityScores.Strength),
DEX = _modifierHelper.AbilityModifier(characters.AbilityScores.Dexterity),
CON = _modifierHelper.AbilityModifier(characters.AbilityScores.Constitution),
INT = _modifierHelper.AbilityModifier(characters.AbilityScores.Intelligence),
WIS = _modifierHelper.AbilityModifier(characters.AbilityScores.Wisdom),
CHA = _modifierHelper.AbilityModifier(characters.AbilityScores.Charisma)
};
var result = new JsonResult(new
{
name,
ability
});
return result;
}