27constexpr std::array<AbilitySpec, 20> kSpecs{{
28 {
"light-attack",
"melee", 120, 100, 180, 250, AbilityInstancingPolicy::PerExecution,
29 AbilityActivationGroup::ExclusiveReplaceable},
30 {
"heavy-attack",
"melee", 350, 160, 420, 650, AbilityInstancingPolicy::PerExecution,
31 AbilityActivationGroup::ExclusiveReplaceable},
32 {
"charge-attack",
"charge", 700, 180, 450, 900, AbilityInstancingPolicy::PerExecution,
33 AbilityActivationGroup::ExclusiveReplaceable},
34 {
"aerial-attack",
"melee-air", 140, 180, 260, 400, AbilityInstancingPolicy::PerExecution,
35 AbilityActivationGroup::ExclusiveReplaceable},
36 {
"hold-attack",
"hold", 200, 600, 250, 500, AbilityInstancingPolicy::PerExecution,
37 AbilityActivationGroup::ExclusiveReplaceable},
38 {
"block",
"guard", 80, 1000, 100, 0, AbilityInstancingPolicy::PerOwner,
39 AbilityActivationGroup::ExclusiveBlocking},
40 {
"parry",
"guard", 70, 180, 420, 600, AbilityInstancingPolicy::PerExecution,
41 AbilityActivationGroup::ExclusiveBlocking},
42 {
"dodge",
"movement", 80, 280, 220, 500, AbilityInstancingPolicy::PerExecution,
43 AbilityActivationGroup::ExclusiveReplaceable},
44 {
"dash",
"movement", 40, 240, 100, 350, AbilityInstancingPolicy::PerExecution,
45 AbilityActivationGroup::ExclusiveReplaceable},
46 {
"jump",
"movement-air", 40, 120, 80, 0, AbilityInstancingPolicy::PerExecution,
47 AbilityActivationGroup::Independent},
48 {
"double-jump",
"movement-air", 20, 120, 80, 0, AbilityInstancingPolicy::PerExecution,
49 AbilityActivationGroup::Independent},
50 {
"teleport",
"movement-warp", 180, 20, 220, 1200, AbilityInstancingPolicy::PerExecution,
51 AbilityActivationGroup::ExclusiveReplaceable},
52 {
"throw",
"projectile", 200, 100, 260, 500, AbilityInstancingPolicy::PerExecution,
53 AbilityActivationGroup::ExclusiveReplaceable},
54 {
"ranged-attack",
"projectile", 160, 80, 220, 350, AbilityInstancingPolicy::PerExecution,
55 AbilityActivationGroup::ExclusiveReplaceable},
56 {
"equip",
"equipment", 300, 80, 180, 0, AbilityInstancingPolicy::PerExecution,
57 AbilityActivationGroup::ExclusiveBlocking},
58 {
"unequip",
"equipment", 260, 60, 140, 0, AbilityInstancingPolicy::PerExecution,
59 AbilityActivationGroup::ExclusiveBlocking},
60 {
"heal",
"effect", 500, 80, 300, 1500, AbilityInstancingPolicy::PerExecution,
61 AbilityActivationGroup::ExclusiveReplaceable},
62 {
"buff",
"effect", 240, 80, 220, 800, AbilityInstancingPolicy::PerExecution,
63 AbilityActivationGroup::Independent},
64 {
"hit-reaction",
"reaction", 0, 240, 160, 0, AbilityInstancingPolicy::PerExecution,
65 AbilityActivationGroup::ExclusiveReplaceable},
66 {
"death",
"reaction", 0, 1200, 0, 0, AbilityInstancingPolicy::PerOwner,
67 AbilityActivationGroup::ExclusiveBlocking},
70Result<LogicalId>
id(std::string_view domain, std::string_view
name) {
75 std::string(domain) +
":" + std::string(
name)));
84 std::vector<action::AbilityDefinition> result;
85 result.reserve(kSpecs.size());
86 for (
const AbilitySpec& spec : kSpecs) {
87 auto abilityId =
id(
"combat-ability", spec.name);
89 auto actionId =
id(
"combat-action", spec.name);
93 definition.id = std::move(abilityId).takeValue();
94 definition.action.id = std::move(actionId).takeValue();
95 definition.action.timing.windup =
milliseconds(spec.windupMs);
96 definition.action.timing.active =
milliseconds(spec.activeMs);
97 definition.action.timing.recover =
milliseconds(spec.recoverMs);
98 definition.action.metadata[
"combat.adapter"] = std::string(spec.adapter);
100 definition.instancing = spec.instancing;
101 definition.activationGroup = spec.group;
102 auto valid = definition.validate();
104 result.push_back(std::move(definition));
building::EdgeCurveGroup group
Stable, structured diagnostics shared by engine modules.
AbilityInstancingPolicy instancing
Registerable standard action-combat ability archetypes.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
static constexpr Duration fromNanoseconds(std::int64_t nanoseconds) noexcept
Construct an exact duration from nanoseconds.
static std::optional< LogicalId > fromParts(std::string_view namespaceName, std::string_view name)
Builds a logical ID from separate namespace and name components.
Move-only operation result carrying either a value or Status.
static Result success(T value)
Construct a successful result owning value.
static Result failure(Status status)
Construct a failed result from a structured status.
AbilityActivationGroup
Concurrency policy modeled after independent and exclusive ability groups.
AbilityInstancingPolicy
Controls where mutable ability instance state is allocated.
Result< std::vector< action::AbilityDefinition > > standardCombatAbilities()
Build twenty validated, registerable standard combat ability definitions.
Canonical immutable-by-convention definition of a grantable ability.