horse, horsegen: redesign approach for koka

This commit is contained in:
2026-01-27 08:34:11 -05:00
parent 0126101b1b
commit e890108591
11 changed files with 14312 additions and 4449 deletions

226
horse/skill.kk Normal file
View File

@@ -0,0 +1,226 @@
module horse/skill
// This module contains skill-related definitions
// common to all versions of the game.
import std/num/decimal
import horse/game-id
import horse/movement
// Full details about a skill.
pub struct skill-detail
skill-id: skill-id
name: string
description: string
group-id: skill-group-id
rarity: rarity
group-rate: int
grade-value: int
wit-check: bool
activations: list<activation>
owner: maybe<trainee-id>
sp-cost: int
icon-id: skill-icon-id
pub fun detail(
s: skill-id,
?skill/show: (skill-id) -> string,
?skill/description: (skill-id) -> string,
?skill/group: (skill-id) -> skill-group-id,
?skill/rarity: (skill-id) -> rarity,
?skill/group-rate: (skill-id) -> int,
?skill/grade-value: (skill-id) -> int,
?skill/wit-check: (skill-id) -> bool,
?skill/activations: (skill-id) -> list<activation>,
?skill/unique-owner: (skill-id) -> maybe<trainee-id>,
?skill/sp-cost: (skill-id) -> int,
?skill/icon-id: (skill-id) -> skill-icon-id
): skill-detail
Skill-detail(
s,
s.show,
s.description,
s.group,
s.rarity,
s.group-rate,
s.grade-value,
s.wit-check,
s.activations,
s.unique-owner,
s.sp-cost,
s.icon-id
)
pub fun skill-detail/show(d: skill-detail, ?character/show: (character-id) -> string, ?trainee/show: (trainee-id) -> string): string
val Skill-detail(Skill-id(id), name, desc, _, rarity, _, grade-value, wit-check, activations, owner, sp-cost, _) = d
val r = name ++ " (ID " ++ id.show ++ "): " ++ desc ++ " " ++ activations.map(activation/show).join(". ") ++ (if wit-check then ". Wit check. " else ". No wit check. ") ++ rarity.show ++ " costing " ++ sp-cost.show ++ " SP, worth " ++ grade-value.show ++ " grade value."
match owner
Nothing -> r
Just(owner-id) -> match owner-id.show
"" -> r ++ " Unique skill of trainee with ID " ++ owner-id.show ++ "."
owner-name -> r ++ " Unique skill of " ++ owner-name ++ "."
// Skill rarity levels.
pub type rarity
Common // white
Rare // gold
Unique-Low // 1*/2* unique
Unique-Upgraded // 3*+ unique on a trainee upgraded from 1*/2*
Unique // base 3* unique
pub fun rarity/show(r: rarity): string
match r
Common -> "Common"
Rare -> "Rare"
Unique-Low -> "Unique (1\u2606/2\u2606)"
Unique-Upgraded -> "Unique (3\u2606+ from 1\u2606/2\u2606 upgraded)"
Unique -> "Unique (3\u2606+)"
// Condition and precondition logic.
pub alias condition = string
// Activation conditions and effects.
// A skill has one or two activations.
pub struct activation
precondition: condition
condition: condition
duration: decimal // seconds
cooldown: decimal // seconds
abilities: list<ability> // one to three elements
pub fun activation/show(a: activation, ?character/show: (character-id) -> string): string
match a
Activation("", condition, duration, _, abilities) | !duration.is-pos -> condition ++ " -> " ++ abilities.show
Activation("", condition, duration, cooldown, abilities) | cooldown >= 500.decimal -> condition ++ " -> for " ++ duration.show ++ "s, " ++ abilities.show
Activation("", condition, duration, cooldown, abilities) -> condition ++ " -> for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
Activation(precondition, condition, duration, _, abilities) | !duration.is-pos -> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show
Activation(precondition, condition, duration, cooldown, abilities) | cooldown >= 500.decimal -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s, " ++ abilities.show
Activation(precondition, condition, duration, cooldown, abilities) -> precondition ++ " -> " ++ condition ++ " -> for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown, " ++ abilities.show
// Effects of activating a skill.
pub struct ability
ability-type: ability-type
value-usage: value-usage
target: target
pub fun ability/show(a: ability, ?character/show: (character-id) -> string): string
match a
Ability(t, Direct, Self) -> t.show
Ability(t, Direct, target) -> t.show ++ " " ++ target.show
Ability(t, v, Self) -> t.show ++ " " ++ v.show
Ability(t, v, target) -> t.show ++ " " ++ target.show ++ " " ++ v.show
// Skill ability effects.
pub type ability-type
Passive-Speed(bonus: decimal)
Passive-Stamina(bonus: decimal)
Passive-Power(bonus: decimal)
Passive-Guts(bonus: decimal)
Passive-Wit(bonus: decimal)
Great-Escape
Vision(bonus: decimal)
HP(rate: decimal)
Gate-Delay(rate: decimal)
Frenzy(add: decimal)
Current-Speed(add: decimal)
Target-Speed(add: decimal)
Lane-Speed(add: decimal)
Accel(add: decimal)
Lane-Change(add: decimal)
pub fun ability-type/show(a: ability-type): string
match a
Passive-Speed(bonus) -> bonus.show ++ " Speed"
Passive-Stamina(bonus) -> bonus.show ++ " Stamina"
Passive-Power(bonus) -> bonus.show ++ " Power"
Passive-Guts(bonus) -> bonus.show ++ " Guts"
Passive-Wit(bonus) -> bonus.show ++ " Wit"
Great-Escape -> "enable Great Escape style"
Vision(bonus) -> bonus.show ++ " vision"
HP(rate) | rate.is-pos -> show(rate * 100.decimal) ++ "% HP recovery"
HP(rate) -> show(rate * 100.decimal) ++ "% HP loss"
Gate-Delay(rate) -> rate.show ++ "× gate delay"
Frenzy(add) -> add.show ++ "s longer Rushed"
Current-Speed(rate) -> rate.show ++ "m/s current speed"
Target-Speed(rate) -> rate.show ++ "m/s target speed"
Lane-Speed(rate) -> rate.show ++ "m/s lane change speed"
Accel(rate) -> rate.show ++ "m/s² acceleration"
Lane-Change(rate) -> rate.show ++ " course width movement"
// Special scaling types for skill abilities.
pub type value-usage
Direct
Team-Speed
Team-Stamina
Team-Power
Team-Guts
Team-Wit
Multiply-Random
Multiply-Random2
Climax
Max-Stat
Passive-Count
Front-Distance-Add
Midrace-Side-Block-Time
Speed-Scaling
Speed-Scaling2
Arc-Global-Potential
Max-Lead-Distance
pub fun value-usage/show(v: value-usage): string
match v
Direct -> "with no scaling"
Team-Speed -> "scaling with team Speed"
Team-Stamina -> "scaling with team Stamina"
Team-Power -> "scaling with team Power"
Team-Guts -> "scaling with team Guts"
Team-Wit -> "scaling with team Wit"
Multiply-Random -> "scaling with a random multiplier (0×, 0.02×, or 0.04×)"
Multiply-Random2 -> "scaling with a random multiplier (0×, 0.02×, or 0.04×)"
Climax -> "scaling with the number of races won during training"
Max-Stat -> "scaling with the value of the user's highest stat"
Passive-Count -> "scaling with the number of Passive skills activated"
Front-Distance-Add -> "scaling with distance from the leader"
Midrace-Side-Block-Time -> "scaling with mid-race phase blocked side time"
Speed-Scaling -> "scaling with overall speed"
Speed-Scaling2 -> "scaling with overall speed"
Arc-Global-Potential -> "scaling with L'Arc global potential"
Max-Lead-Distance -> "scaling with the distance of the longest lead obtained in the first two thirds of the race"
// Who a skill ability targets.
pub type target
Self
Sympathizers
In-View
Frontmost(limit: int)
Ahead(limit: int)
Behind(limit: int)
All-Teammates
Style(style: style)
Rushing-Ahead(limit: int)
Rushing-Behind(limit: int)
Rushing-Style(style: style)
Specific-Character(who: character-id)
Triggering
pub fun target/show(t: target, ?character/show: (character-id) -> string): string
match t
Self -> "self"
Sympathizers -> "others with Sympathy"
In-View -> "others in field of view"
Frontmost(limit) -> "frontmost " ++ limit.show
Ahead(limit) | limit >= 18 -> "others ahead"
Ahead(limit) -> "next " ++ limit.show ++ " others ahead"
Behind(limit) | limit >= 18 -> "others behind"
Behind(limit) -> "next " ++ limit.show ++ " others behind"
All-Teammates -> "all teammates"
Style(s) -> "other " ++ s.show ++ "s"
Rushing-Ahead(limit) | limit >= 18 -> "others rushing ahead"
Rushing-Ahead(limit) -> "next " ++ limit.show ++ " others rushing ahead"
Rushing-Behind(limit) | limit >= 18 -> "others rushing behind"
Rushing-Behind(limit) -> "next " ++ limit.show ++ " others rushing behind"
Rushing-Style(s) -> "rushing " ++ s.show ++ "s"
Specific-Character(who) -> match who.show
"" -> "character with ID " ++ who.show
name -> name
Triggering -> "whosoever triggered this skill"