Compare commits
4 Commits
5bf2588d41
...
542d4198e7
| Author | SHA1 | Date | |
|---|---|---|---|
| 542d4198e7 | |||
| 98afe7384a | |||
| e890108591 | |||
| 0126101b1b |
8
generate.sh
Executable file
8
generate.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
go run ./horsegen "$@"
|
||||
go generate ./horse/...
|
||||
go fmt ./...
|
||||
go test ./...
|
||||
17
horse/character.kk
Normal file
17
horse/character.kk
Normal file
@@ -0,0 +1,17 @@
|
||||
module horse/character
|
||||
|
||||
import horse/game-id
|
||||
|
||||
pub struct character-detail
|
||||
character-id: character-id
|
||||
name: string
|
||||
|
||||
pub fun detail(
|
||||
c: character-id,
|
||||
?character/show: (character-id) -> string
|
||||
): character-detail
|
||||
Character-detail(c, c.show)
|
||||
|
||||
pub fun character-detail/show(d: character-detail): string
|
||||
val Character-detail(Character-id(id), name) = d
|
||||
name ++ " (ID " ++ id.show ++ ")"
|
||||
49
horse/game-id.kk
Normal file
49
horse/game-id.kk
Normal file
@@ -0,0 +1,49 @@
|
||||
module horse/game-id
|
||||
|
||||
// Game ID for characters, cards, skills, races, &c.
|
||||
// Values for different categories may overlap.
|
||||
alias game-id = int
|
||||
|
||||
// Specific game ID types.
|
||||
// I've already made mistakes with ID categories and I haven't even committed this file yet.
|
||||
|
||||
// Game ID for characters.
|
||||
// Generally numbers in the range 1000-9999.
|
||||
pub struct character-id
|
||||
game-id: game-id
|
||||
|
||||
// Game ID for trainees, i.e. costume instances of characters.
|
||||
// Generally a character ID with two digits appended.
|
||||
pub struct trainee-id
|
||||
game-id: game-id
|
||||
|
||||
// Game ID for skills.
|
||||
pub struct skill-id
|
||||
game-id: game-id
|
||||
|
||||
// Game ID for skill groups.
|
||||
pub struct skill-group-id
|
||||
game-id: game-id
|
||||
|
||||
// Game ID for skill icons.
|
||||
pub struct skill-icon-id
|
||||
game-id: game-id
|
||||
|
||||
// order2 comparison between any game ID types.
|
||||
pub inline fun order2(x: a, y: a, ?a/game-id: (a) -> game-id): order2<a>
|
||||
match x.game-id.cmp(y.game-id)
|
||||
Lt -> Lt2(x, y)
|
||||
Eq -> Eq2(x)
|
||||
Gt -> Gt2(x, y)
|
||||
|
||||
// Comparison between any game ID types.
|
||||
pub inline fun cmp(x: a, y: a, ?a/game-id: (a) -> game-id): order
|
||||
x.game-id.cmp(y.game-id)
|
||||
|
||||
// Equality between any game ID types.
|
||||
pub inline fun (==)(x: a, y: a, ?a/game-id: (a) -> game-id): bool
|
||||
x.game-id == y.game-id
|
||||
|
||||
// Check whether a game ID is valid, i.e. nonzero.
|
||||
pub inline fun is-valid(x: a, ?a/game-id: (a) -> game-id): bool
|
||||
x.game-id != 0
|
||||
@@ -4,8 +4,11 @@ module horse/global/character
|
||||
|
||||
import std/core/vector
|
||||
import std/core-extras
|
||||
import std/data/rb-map
|
||||
import horse/game-id
|
||||
pub import horse/character
|
||||
|
||||
// Character identity.
|
||||
// Enumeration of all characters for type-safe programming.
|
||||
pub type character
|
||||
Special-Week
|
||||
Silence-Suzuka
|
||||
@@ -58,8 +61,62 @@ pub type character
|
||||
Nice-Nature
|
||||
King-Halo
|
||||
|
||||
// The list of all characters in order by ID, for easy iterating.
|
||||
pub val character/all = [
|
||||
// Get the character ID for a character.
|
||||
pub fun character-id(c: character): character-id
|
||||
match c
|
||||
Special-Week -> Character-id(1001)
|
||||
Silence-Suzuka -> Character-id(1002)
|
||||
Tokai-Teio -> Character-id(1003)
|
||||
Maruzensky -> Character-id(1004)
|
||||
Fuji-Kiseki -> Character-id(1005)
|
||||
Oguri-Cap -> Character-id(1006)
|
||||
Gold-Ship -> Character-id(1007)
|
||||
Vodka -> Character-id(1008)
|
||||
Daiwa-Scarlet -> Character-id(1009)
|
||||
Taiki-Shuttle -> Character-id(1010)
|
||||
Grass-Wonder -> Character-id(1011)
|
||||
Hishi-Amazon -> Character-id(1012)
|
||||
Mejiro-McQueen -> Character-id(1013)
|
||||
El-Condor-Pasa -> Character-id(1014)
|
||||
TM-Opera-O -> Character-id(1015)
|
||||
Narita-Brian -> Character-id(1016)
|
||||
Symboli-Rudolf -> Character-id(1017)
|
||||
Air-Groove -> Character-id(1018)
|
||||
Agnes-Digital -> Character-id(1019)
|
||||
Seiun-Sky -> Character-id(1020)
|
||||
Tamamo-Cross -> Character-id(1021)
|
||||
Fine-Motion -> Character-id(1022)
|
||||
Biwa-Hayahide -> Character-id(1023)
|
||||
Mayano-Top-Gun -> Character-id(1024)
|
||||
Manhattan-Cafe -> Character-id(1025)
|
||||
Mihono-Bourbon -> Character-id(1026)
|
||||
Mejiro-Ryan -> Character-id(1027)
|
||||
Hishi-Akebono -> Character-id(1028)
|
||||
Rice-Shower -> Character-id(1030)
|
||||
Agnes-Tachyon -> Character-id(1032)
|
||||
Admire-Vega -> Character-id(1033)
|
||||
Inari-One -> Character-id(1034)
|
||||
Winning-Ticket -> Character-id(1035)
|
||||
Eishin-Flash -> Character-id(1037)
|
||||
Curren-Chan -> Character-id(1038)
|
||||
Kawakami-Princess -> Character-id(1039)
|
||||
Gold-City -> Character-id(1040)
|
||||
Sakura-Bakushin-O -> Character-id(1041)
|
||||
Sweep-Tosho -> Character-id(1044)
|
||||
Super-Creek -> Character-id(1045)
|
||||
Smart-Falcon -> Character-id(1046)
|
||||
Tosen-Jordan -> Character-id(1048)
|
||||
Narita-Taishin -> Character-id(1050)
|
||||
Nishino-Flower -> Character-id(1051)
|
||||
Haru-Urara -> Character-id(1052)
|
||||
Matikanefukukitaru -> Character-id(1056)
|
||||
Meisho-Doto -> Character-id(1058)
|
||||
Mejiro-Dober -> Character-id(1059)
|
||||
Nice-Nature -> Character-id(1060)
|
||||
King-Halo -> Character-id(1061)
|
||||
|
||||
// List of all characters in ID order for easy iterating.
|
||||
pub val all = [
|
||||
Special-Week,
|
||||
Silence-Suzuka,
|
||||
Tokai-Teio,
|
||||
@@ -112,429 +169,172 @@ pub val character/all = [
|
||||
King-Halo,
|
||||
]
|
||||
|
||||
// Get the character for a character ID.
|
||||
// Generally, these are four digit numbers in the range 1000-1999.
|
||||
pub fun character/from-id(id: int): maybe<character>
|
||||
match id
|
||||
1001 -> Just(Special-Week)
|
||||
1002 -> Just(Silence-Suzuka)
|
||||
1003 -> Just(Tokai-Teio)
|
||||
1004 -> Just(Maruzensky)
|
||||
1005 -> Just(Fuji-Kiseki)
|
||||
1006 -> Just(Oguri-Cap)
|
||||
1007 -> Just(Gold-Ship)
|
||||
1008 -> Just(Vodka)
|
||||
1009 -> Just(Daiwa-Scarlet)
|
||||
1010 -> Just(Taiki-Shuttle)
|
||||
1011 -> Just(Grass-Wonder)
|
||||
1012 -> Just(Hishi-Amazon)
|
||||
1013 -> Just(Mejiro-McQueen)
|
||||
1014 -> Just(El-Condor-Pasa)
|
||||
1015 -> Just(TM-Opera-O)
|
||||
1016 -> Just(Narita-Brian)
|
||||
1017 -> Just(Symboli-Rudolf)
|
||||
1018 -> Just(Air-Groove)
|
||||
1019 -> Just(Agnes-Digital)
|
||||
1020 -> Just(Seiun-Sky)
|
||||
1021 -> Just(Tamamo-Cross)
|
||||
1022 -> Just(Fine-Motion)
|
||||
1023 -> Just(Biwa-Hayahide)
|
||||
1024 -> Just(Mayano-Top-Gun)
|
||||
1025 -> Just(Manhattan-Cafe)
|
||||
1026 -> Just(Mihono-Bourbon)
|
||||
1027 -> Just(Mejiro-Ryan)
|
||||
1028 -> Just(Hishi-Akebono)
|
||||
1030 -> Just(Rice-Shower)
|
||||
1032 -> Just(Agnes-Tachyon)
|
||||
1033 -> Just(Admire-Vega)
|
||||
1034 -> Just(Inari-One)
|
||||
1035 -> Just(Winning-Ticket)
|
||||
1037 -> Just(Eishin-Flash)
|
||||
1038 -> Just(Curren-Chan)
|
||||
1039 -> Just(Kawakami-Princess)
|
||||
1040 -> Just(Gold-City)
|
||||
1041 -> Just(Sakura-Bakushin-O)
|
||||
1044 -> Just(Sweep-Tosho)
|
||||
1045 -> Just(Super-Creek)
|
||||
1046 -> Just(Smart-Falcon)
|
||||
1048 -> Just(Tosen-Jordan)
|
||||
1050 -> Just(Narita-Taishin)
|
||||
1051 -> Just(Nishino-Flower)
|
||||
1052 -> Just(Haru-Urara)
|
||||
1056 -> Just(Matikanefukukitaru)
|
||||
1058 -> Just(Meisho-Doto)
|
||||
1059 -> Just(Mejiro-Dober)
|
||||
1060 -> Just(Nice-Nature)
|
||||
1061 -> Just(King-Halo)
|
||||
_ -> Nothing
|
||||
val name2id: rbmap<string, character-id> = rb-map/empty()
|
||||
.set("Special Week", Character-id(1001))
|
||||
.set("Silence Suzuka", Character-id(1002))
|
||||
.set("Tokai Teio", Character-id(1003))
|
||||
.set("Maruzensky", Character-id(1004))
|
||||
.set("Fuji Kiseki", Character-id(1005))
|
||||
.set("Oguri Cap", Character-id(1006))
|
||||
.set("Gold Ship", Character-id(1007))
|
||||
.set("Vodka", Character-id(1008))
|
||||
.set("Daiwa Scarlet", Character-id(1009))
|
||||
.set("Taiki Shuttle", Character-id(1010))
|
||||
.set("Grass Wonder", Character-id(1011))
|
||||
.set("Hishi Amazon", Character-id(1012))
|
||||
.set("Mejiro McQueen", Character-id(1013))
|
||||
.set("El Condor Pasa", Character-id(1014))
|
||||
.set("T.M. Opera O", Character-id(1015))
|
||||
.set("Narita Brian", Character-id(1016))
|
||||
.set("Symboli Rudolf", Character-id(1017))
|
||||
.set("Air Groove", Character-id(1018))
|
||||
.set("Agnes Digital", Character-id(1019))
|
||||
.set("Seiun Sky", Character-id(1020))
|
||||
.set("Tamamo Cross", Character-id(1021))
|
||||
.set("Fine Motion", Character-id(1022))
|
||||
.set("Biwa Hayahide", Character-id(1023))
|
||||
.set("Mayano Top Gun", Character-id(1024))
|
||||
.set("Manhattan Cafe", Character-id(1025))
|
||||
.set("Mihono Bourbon", Character-id(1026))
|
||||
.set("Mejiro Ryan", Character-id(1027))
|
||||
.set("Hishi Akebono", Character-id(1028))
|
||||
.set("Rice Shower", Character-id(1030))
|
||||
.set("Agnes Tachyon", Character-id(1032))
|
||||
.set("Admire Vega", Character-id(1033))
|
||||
.set("Inari One", Character-id(1034))
|
||||
.set("Winning Ticket", Character-id(1035))
|
||||
.set("Eishin Flash", Character-id(1037))
|
||||
.set("Curren Chan", Character-id(1038))
|
||||
.set("Kawakami Princess", Character-id(1039))
|
||||
.set("Gold City", Character-id(1040))
|
||||
.set("Sakura Bakushin O", Character-id(1041))
|
||||
.set("Sweep Tosho", Character-id(1044))
|
||||
.set("Super Creek", Character-id(1045))
|
||||
.set("Smart Falcon", Character-id(1046))
|
||||
.set("Tosen Jordan", Character-id(1048))
|
||||
.set("Narita Taishin", Character-id(1050))
|
||||
.set("Nishino Flower", Character-id(1051))
|
||||
.set("Haru Urara", Character-id(1052))
|
||||
.set("Matikanefukukitaru", Character-id(1056))
|
||||
.set("Meisho Doto", Character-id(1058))
|
||||
.set("Mejiro Dober", Character-id(1059))
|
||||
.set("Nice Nature", Character-id(1060))
|
||||
.set("King Halo", Character-id(1061))
|
||||
|
||||
// Get the ID for a character.
|
||||
pub fun character/character-id(c: character): int
|
||||
match c
|
||||
Special-Week -> 1001
|
||||
Silence-Suzuka -> 1002
|
||||
Tokai-Teio -> 1003
|
||||
Maruzensky -> 1004
|
||||
Fuji-Kiseki -> 1005
|
||||
Oguri-Cap -> 1006
|
||||
Gold-Ship -> 1007
|
||||
Vodka -> 1008
|
||||
Daiwa-Scarlet -> 1009
|
||||
Taiki-Shuttle -> 1010
|
||||
Grass-Wonder -> 1011
|
||||
Hishi-Amazon -> 1012
|
||||
Mejiro-McQueen -> 1013
|
||||
El-Condor-Pasa -> 1014
|
||||
TM-Opera-O -> 1015
|
||||
Narita-Brian -> 1016
|
||||
Symboli-Rudolf -> 1017
|
||||
Air-Groove -> 1018
|
||||
Agnes-Digital -> 1019
|
||||
Seiun-Sky -> 1020
|
||||
Tamamo-Cross -> 1021
|
||||
Fine-Motion -> 1022
|
||||
Biwa-Hayahide -> 1023
|
||||
Mayano-Top-Gun -> 1024
|
||||
Manhattan-Cafe -> 1025
|
||||
Mihono-Bourbon -> 1026
|
||||
Mejiro-Ryan -> 1027
|
||||
Hishi-Akebono -> 1028
|
||||
Rice-Shower -> 1030
|
||||
Agnes-Tachyon -> 1032
|
||||
Admire-Vega -> 1033
|
||||
Inari-One -> 1034
|
||||
Winning-Ticket -> 1035
|
||||
Eishin-Flash -> 1037
|
||||
Curren-Chan -> 1038
|
||||
Kawakami-Princess -> 1039
|
||||
Gold-City -> 1040
|
||||
Sakura-Bakushin-O -> 1041
|
||||
Sweep-Tosho -> 1044
|
||||
Super-Creek -> 1045
|
||||
Smart-Falcon -> 1046
|
||||
Tosen-Jordan -> 1048
|
||||
Narita-Taishin -> 1050
|
||||
Nishino-Flower -> 1051
|
||||
Haru-Urara -> 1052
|
||||
Matikanefukukitaru -> 1056
|
||||
Meisho-Doto -> 1058
|
||||
Mejiro-Dober -> 1059
|
||||
Nice-Nature -> 1060
|
||||
King-Halo -> 1061
|
||||
// Get the character ID that has the given exact name.
|
||||
// If no character matches the name, the result is an invalid ID.
|
||||
pub fun from-name(name: string): character-id
|
||||
name2id.lookup(name).default(Character-id(0))
|
||||
|
||||
// Get the name of a character.
|
||||
pub fun character/show(c: character): string
|
||||
match c
|
||||
Special-Week -> "Special Week"
|
||||
Silence-Suzuka -> "Silence Suzuka"
|
||||
Tokai-Teio -> "Tokai Teio"
|
||||
Maruzensky -> "Maruzensky"
|
||||
Fuji-Kiseki -> "Fuji Kiseki"
|
||||
Oguri-Cap -> "Oguri Cap"
|
||||
Gold-Ship -> "Gold Ship"
|
||||
Vodka -> "Vodka"
|
||||
Daiwa-Scarlet -> "Daiwa Scarlet"
|
||||
Taiki-Shuttle -> "Taiki Shuttle"
|
||||
Grass-Wonder -> "Grass Wonder"
|
||||
Hishi-Amazon -> "Hishi Amazon"
|
||||
Mejiro-McQueen -> "Mejiro McQueen"
|
||||
El-Condor-Pasa -> "El Condor Pasa"
|
||||
TM-Opera-O -> "T.M. Opera O"
|
||||
Narita-Brian -> "Narita Brian"
|
||||
Symboli-Rudolf -> "Symboli Rudolf"
|
||||
Air-Groove -> "Air Groove"
|
||||
Agnes-Digital -> "Agnes Digital"
|
||||
Seiun-Sky -> "Seiun Sky"
|
||||
Tamamo-Cross -> "Tamamo Cross"
|
||||
Fine-Motion -> "Fine Motion"
|
||||
Biwa-Hayahide -> "Biwa Hayahide"
|
||||
Mayano-Top-Gun -> "Mayano Top Gun"
|
||||
Manhattan-Cafe -> "Manhattan Cafe"
|
||||
Mihono-Bourbon -> "Mihono Bourbon"
|
||||
Mejiro-Ryan -> "Mejiro Ryan"
|
||||
Hishi-Akebono -> "Hishi Akebono"
|
||||
Rice-Shower -> "Rice Shower"
|
||||
Agnes-Tachyon -> "Agnes Tachyon"
|
||||
Admire-Vega -> "Admire Vega"
|
||||
Inari-One -> "Inari One"
|
||||
Winning-Ticket -> "Winning Ticket"
|
||||
Eishin-Flash -> "Eishin Flash"
|
||||
Curren-Chan -> "Curren Chan"
|
||||
Kawakami-Princess -> "Kawakami Princess"
|
||||
Gold-City -> "Gold City"
|
||||
Sakura-Bakushin-O -> "Sakura Bakushin O"
|
||||
Sweep-Tosho -> "Sweep Tosho"
|
||||
Super-Creek -> "Super Creek"
|
||||
Smart-Falcon -> "Smart Falcon"
|
||||
Tosen-Jordan -> "Tosen Jordan"
|
||||
Narita-Taishin -> "Narita Taishin"
|
||||
Nishino-Flower -> "Nishino Flower"
|
||||
Haru-Urara -> "Haru Urara"
|
||||
Matikanefukukitaru -> "Matikanefukukitaru"
|
||||
Meisho-Doto -> "Meisho Doto"
|
||||
Mejiro-Dober -> "Mejiro Dober"
|
||||
Nice-Nature -> "Nice Nature"
|
||||
King-Halo -> "King Halo"
|
||||
// Get the name for a character.
|
||||
// If no character matches the ID, the result is the numeric ID.
|
||||
pub fun show(c: character-id): string
|
||||
match c.game-id
|
||||
1001 -> "Special Week"
|
||||
1002 -> "Silence Suzuka"
|
||||
1003 -> "Tokai Teio"
|
||||
1004 -> "Maruzensky"
|
||||
1005 -> "Fuji Kiseki"
|
||||
1006 -> "Oguri Cap"
|
||||
1007 -> "Gold Ship"
|
||||
1008 -> "Vodka"
|
||||
1009 -> "Daiwa Scarlet"
|
||||
1010 -> "Taiki Shuttle"
|
||||
1011 -> "Grass Wonder"
|
||||
1012 -> "Hishi Amazon"
|
||||
1013 -> "Mejiro McQueen"
|
||||
1014 -> "El Condor Pasa"
|
||||
1015 -> "T.M. Opera O"
|
||||
1016 -> "Narita Brian"
|
||||
1017 -> "Symboli Rudolf"
|
||||
1018 -> "Air Groove"
|
||||
1019 -> "Agnes Digital"
|
||||
1020 -> "Seiun Sky"
|
||||
1021 -> "Tamamo Cross"
|
||||
1022 -> "Fine Motion"
|
||||
1023 -> "Biwa Hayahide"
|
||||
1024 -> "Mayano Top Gun"
|
||||
1025 -> "Manhattan Cafe"
|
||||
1026 -> "Mihono Bourbon"
|
||||
1027 -> "Mejiro Ryan"
|
||||
1028 -> "Hishi Akebono"
|
||||
1030 -> "Rice Shower"
|
||||
1032 -> "Agnes Tachyon"
|
||||
1033 -> "Admire Vega"
|
||||
1034 -> "Inari One"
|
||||
1035 -> "Winning Ticket"
|
||||
1037 -> "Eishin Flash"
|
||||
1038 -> "Curren Chan"
|
||||
1039 -> "Kawakami Princess"
|
||||
1040 -> "Gold City"
|
||||
1041 -> "Sakura Bakushin O"
|
||||
1044 -> "Sweep Tosho"
|
||||
1045 -> "Super Creek"
|
||||
1046 -> "Smart Falcon"
|
||||
1048 -> "Tosen Jordan"
|
||||
1050 -> "Narita Taishin"
|
||||
1051 -> "Nishino Flower"
|
||||
1052 -> "Haru Urara"
|
||||
1056 -> "Matikanefukukitaru"
|
||||
1058 -> "Meisho Doto"
|
||||
1059 -> "Mejiro Dober"
|
||||
1060 -> "Nice Nature"
|
||||
1061 -> "King Halo"
|
||||
x -> "character " ++ x.show
|
||||
|
||||
// Compare two characters.
|
||||
pub fip fun character/order2(a: character, b: character): order2<character>
|
||||
match (a, b)
|
||||
(Special-Week, Special-Week) -> Eq2(Special-Week)
|
||||
(Special-Week, b') -> Lt2(Special-Week, b')
|
||||
(a', Special-Week) -> Gt2(Special-Week, a')
|
||||
(Silence-Suzuka, Silence-Suzuka) -> Eq2(Silence-Suzuka)
|
||||
(Silence-Suzuka, b') -> Lt2(Silence-Suzuka, b')
|
||||
(a', Silence-Suzuka) -> Gt2(Silence-Suzuka, a')
|
||||
(Tokai-Teio, Tokai-Teio) -> Eq2(Tokai-Teio)
|
||||
(Tokai-Teio, b') -> Lt2(Tokai-Teio, b')
|
||||
(a', Tokai-Teio) -> Gt2(Tokai-Teio, a')
|
||||
(Maruzensky, Maruzensky) -> Eq2(Maruzensky)
|
||||
(Maruzensky, b') -> Lt2(Maruzensky, b')
|
||||
(a', Maruzensky) -> Gt2(Maruzensky, a')
|
||||
(Fuji-Kiseki, Fuji-Kiseki) -> Eq2(Fuji-Kiseki)
|
||||
(Fuji-Kiseki, b') -> Lt2(Fuji-Kiseki, b')
|
||||
(a', Fuji-Kiseki) -> Gt2(Fuji-Kiseki, a')
|
||||
(Oguri-Cap, Oguri-Cap) -> Eq2(Oguri-Cap)
|
||||
(Oguri-Cap, b') -> Lt2(Oguri-Cap, b')
|
||||
(a', Oguri-Cap) -> Gt2(Oguri-Cap, a')
|
||||
(Gold-Ship, Gold-Ship) -> Eq2(Gold-Ship)
|
||||
(Gold-Ship, b') -> Lt2(Gold-Ship, b')
|
||||
(a', Gold-Ship) -> Gt2(Gold-Ship, a')
|
||||
(Vodka, Vodka) -> Eq2(Vodka)
|
||||
(Vodka, b') -> Lt2(Vodka, b')
|
||||
(a', Vodka) -> Gt2(Vodka, a')
|
||||
(Daiwa-Scarlet, Daiwa-Scarlet) -> Eq2(Daiwa-Scarlet)
|
||||
(Daiwa-Scarlet, b') -> Lt2(Daiwa-Scarlet, b')
|
||||
(a', Daiwa-Scarlet) -> Gt2(Daiwa-Scarlet, a')
|
||||
(Taiki-Shuttle, Taiki-Shuttle) -> Eq2(Taiki-Shuttle)
|
||||
(Taiki-Shuttle, b') -> Lt2(Taiki-Shuttle, b')
|
||||
(a', Taiki-Shuttle) -> Gt2(Taiki-Shuttle, a')
|
||||
(Grass-Wonder, Grass-Wonder) -> Eq2(Grass-Wonder)
|
||||
(Grass-Wonder, b') -> Lt2(Grass-Wonder, b')
|
||||
(a', Grass-Wonder) -> Gt2(Grass-Wonder, a')
|
||||
(Hishi-Amazon, Hishi-Amazon) -> Eq2(Hishi-Amazon)
|
||||
(Hishi-Amazon, b') -> Lt2(Hishi-Amazon, b')
|
||||
(a', Hishi-Amazon) -> Gt2(Hishi-Amazon, a')
|
||||
(Mejiro-McQueen, Mejiro-McQueen) -> Eq2(Mejiro-McQueen)
|
||||
(Mejiro-McQueen, b') -> Lt2(Mejiro-McQueen, b')
|
||||
(a', Mejiro-McQueen) -> Gt2(Mejiro-McQueen, a')
|
||||
(El-Condor-Pasa, El-Condor-Pasa) -> Eq2(El-Condor-Pasa)
|
||||
(El-Condor-Pasa, b') -> Lt2(El-Condor-Pasa, b')
|
||||
(a', El-Condor-Pasa) -> Gt2(El-Condor-Pasa, a')
|
||||
(TM-Opera-O, TM-Opera-O) -> Eq2(TM-Opera-O)
|
||||
(TM-Opera-O, b') -> Lt2(TM-Opera-O, b')
|
||||
(a', TM-Opera-O) -> Gt2(TM-Opera-O, a')
|
||||
(Narita-Brian, Narita-Brian) -> Eq2(Narita-Brian)
|
||||
(Narita-Brian, b') -> Lt2(Narita-Brian, b')
|
||||
(a', Narita-Brian) -> Gt2(Narita-Brian, a')
|
||||
(Symboli-Rudolf, Symboli-Rudolf) -> Eq2(Symboli-Rudolf)
|
||||
(Symboli-Rudolf, b') -> Lt2(Symboli-Rudolf, b')
|
||||
(a', Symboli-Rudolf) -> Gt2(Symboli-Rudolf, a')
|
||||
(Air-Groove, Air-Groove) -> Eq2(Air-Groove)
|
||||
(Air-Groove, b') -> Lt2(Air-Groove, b')
|
||||
(a', Air-Groove) -> Gt2(Air-Groove, a')
|
||||
(Agnes-Digital, Agnes-Digital) -> Eq2(Agnes-Digital)
|
||||
(Agnes-Digital, b') -> Lt2(Agnes-Digital, b')
|
||||
(a', Agnes-Digital) -> Gt2(Agnes-Digital, a')
|
||||
(Seiun-Sky, Seiun-Sky) -> Eq2(Seiun-Sky)
|
||||
(Seiun-Sky, b') -> Lt2(Seiun-Sky, b')
|
||||
(a', Seiun-Sky) -> Gt2(Seiun-Sky, a')
|
||||
(Tamamo-Cross, Tamamo-Cross) -> Eq2(Tamamo-Cross)
|
||||
(Tamamo-Cross, b') -> Lt2(Tamamo-Cross, b')
|
||||
(a', Tamamo-Cross) -> Gt2(Tamamo-Cross, a')
|
||||
(Fine-Motion, Fine-Motion) -> Eq2(Fine-Motion)
|
||||
(Fine-Motion, b') -> Lt2(Fine-Motion, b')
|
||||
(a', Fine-Motion) -> Gt2(Fine-Motion, a')
|
||||
(Biwa-Hayahide, Biwa-Hayahide) -> Eq2(Biwa-Hayahide)
|
||||
(Biwa-Hayahide, b') -> Lt2(Biwa-Hayahide, b')
|
||||
(a', Biwa-Hayahide) -> Gt2(Biwa-Hayahide, a')
|
||||
(Mayano-Top-Gun, Mayano-Top-Gun) -> Eq2(Mayano-Top-Gun)
|
||||
(Mayano-Top-Gun, b') -> Lt2(Mayano-Top-Gun, b')
|
||||
(a', Mayano-Top-Gun) -> Gt2(Mayano-Top-Gun, a')
|
||||
(Manhattan-Cafe, Manhattan-Cafe) -> Eq2(Manhattan-Cafe)
|
||||
(Manhattan-Cafe, b') -> Lt2(Manhattan-Cafe, b')
|
||||
(a', Manhattan-Cafe) -> Gt2(Manhattan-Cafe, a')
|
||||
(Mihono-Bourbon, Mihono-Bourbon) -> Eq2(Mihono-Bourbon)
|
||||
(Mihono-Bourbon, b') -> Lt2(Mihono-Bourbon, b')
|
||||
(a', Mihono-Bourbon) -> Gt2(Mihono-Bourbon, a')
|
||||
(Mejiro-Ryan, Mejiro-Ryan) -> Eq2(Mejiro-Ryan)
|
||||
(Mejiro-Ryan, b') -> Lt2(Mejiro-Ryan, b')
|
||||
(a', Mejiro-Ryan) -> Gt2(Mejiro-Ryan, a')
|
||||
(Hishi-Akebono, Hishi-Akebono) -> Eq2(Hishi-Akebono)
|
||||
(Hishi-Akebono, b') -> Lt2(Hishi-Akebono, b')
|
||||
(a', Hishi-Akebono) -> Gt2(Hishi-Akebono, a')
|
||||
(Rice-Shower, Rice-Shower) -> Eq2(Rice-Shower)
|
||||
(Rice-Shower, b') -> Lt2(Rice-Shower, b')
|
||||
(a', Rice-Shower) -> Gt2(Rice-Shower, a')
|
||||
(Agnes-Tachyon, Agnes-Tachyon) -> Eq2(Agnes-Tachyon)
|
||||
(Agnes-Tachyon, b') -> Lt2(Agnes-Tachyon, b')
|
||||
(a', Agnes-Tachyon) -> Gt2(Agnes-Tachyon, a')
|
||||
(Admire-Vega, Admire-Vega) -> Eq2(Admire-Vega)
|
||||
(Admire-Vega, b') -> Lt2(Admire-Vega, b')
|
||||
(a', Admire-Vega) -> Gt2(Admire-Vega, a')
|
||||
(Inari-One, Inari-One) -> Eq2(Inari-One)
|
||||
(Inari-One, b') -> Lt2(Inari-One, b')
|
||||
(a', Inari-One) -> Gt2(Inari-One, a')
|
||||
(Winning-Ticket, Winning-Ticket) -> Eq2(Winning-Ticket)
|
||||
(Winning-Ticket, b') -> Lt2(Winning-Ticket, b')
|
||||
(a', Winning-Ticket) -> Gt2(Winning-Ticket, a')
|
||||
(Eishin-Flash, Eishin-Flash) -> Eq2(Eishin-Flash)
|
||||
(Eishin-Flash, b') -> Lt2(Eishin-Flash, b')
|
||||
(a', Eishin-Flash) -> Gt2(Eishin-Flash, a')
|
||||
(Curren-Chan, Curren-Chan) -> Eq2(Curren-Chan)
|
||||
(Curren-Chan, b') -> Lt2(Curren-Chan, b')
|
||||
(a', Curren-Chan) -> Gt2(Curren-Chan, a')
|
||||
(Kawakami-Princess, Kawakami-Princess) -> Eq2(Kawakami-Princess)
|
||||
(Kawakami-Princess, b') -> Lt2(Kawakami-Princess, b')
|
||||
(a', Kawakami-Princess) -> Gt2(Kawakami-Princess, a')
|
||||
(Gold-City, Gold-City) -> Eq2(Gold-City)
|
||||
(Gold-City, b') -> Lt2(Gold-City, b')
|
||||
(a', Gold-City) -> Gt2(Gold-City, a')
|
||||
(Sakura-Bakushin-O, Sakura-Bakushin-O) -> Eq2(Sakura-Bakushin-O)
|
||||
(Sakura-Bakushin-O, b') -> Lt2(Sakura-Bakushin-O, b')
|
||||
(a', Sakura-Bakushin-O) -> Gt2(Sakura-Bakushin-O, a')
|
||||
(Sweep-Tosho, Sweep-Tosho) -> Eq2(Sweep-Tosho)
|
||||
(Sweep-Tosho, b') -> Lt2(Sweep-Tosho, b')
|
||||
(a', Sweep-Tosho) -> Gt2(Sweep-Tosho, a')
|
||||
(Super-Creek, Super-Creek) -> Eq2(Super-Creek)
|
||||
(Super-Creek, b') -> Lt2(Super-Creek, b')
|
||||
(a', Super-Creek) -> Gt2(Super-Creek, a')
|
||||
(Smart-Falcon, Smart-Falcon) -> Eq2(Smart-Falcon)
|
||||
(Smart-Falcon, b') -> Lt2(Smart-Falcon, b')
|
||||
(a', Smart-Falcon) -> Gt2(Smart-Falcon, a')
|
||||
(Tosen-Jordan, Tosen-Jordan) -> Eq2(Tosen-Jordan)
|
||||
(Tosen-Jordan, b') -> Lt2(Tosen-Jordan, b')
|
||||
(a', Tosen-Jordan) -> Gt2(Tosen-Jordan, a')
|
||||
(Narita-Taishin, Narita-Taishin) -> Eq2(Narita-Taishin)
|
||||
(Narita-Taishin, b') -> Lt2(Narita-Taishin, b')
|
||||
(a', Narita-Taishin) -> Gt2(Narita-Taishin, a')
|
||||
(Nishino-Flower, Nishino-Flower) -> Eq2(Nishino-Flower)
|
||||
(Nishino-Flower, b') -> Lt2(Nishino-Flower, b')
|
||||
(a', Nishino-Flower) -> Gt2(Nishino-Flower, a')
|
||||
(Haru-Urara, Haru-Urara) -> Eq2(Haru-Urara)
|
||||
(Haru-Urara, b') -> Lt2(Haru-Urara, b')
|
||||
(a', Haru-Urara) -> Gt2(Haru-Urara, a')
|
||||
(Matikanefukukitaru, Matikanefukukitaru) -> Eq2(Matikanefukukitaru)
|
||||
(Matikanefukukitaru, b') -> Lt2(Matikanefukukitaru, b')
|
||||
(a', Matikanefukukitaru) -> Gt2(Matikanefukukitaru, a')
|
||||
(Meisho-Doto, Meisho-Doto) -> Eq2(Meisho-Doto)
|
||||
(Meisho-Doto, b') -> Lt2(Meisho-Doto, b')
|
||||
(a', Meisho-Doto) -> Gt2(Meisho-Doto, a')
|
||||
(Mejiro-Dober, Mejiro-Dober) -> Eq2(Mejiro-Dober)
|
||||
(Mejiro-Dober, b') -> Lt2(Mejiro-Dober, b')
|
||||
(a', Mejiro-Dober) -> Gt2(Mejiro-Dober, a')
|
||||
(Nice-Nature, Nice-Nature) -> Eq2(Nice-Nature)
|
||||
(Nice-Nature, b') -> Lt2(Nice-Nature, b')
|
||||
(a', Nice-Nature) -> Gt2(Nice-Nature, a')
|
||||
(King-Halo, King-Halo) -> Eq2(King-Halo)
|
||||
|
||||
// Character equality.
|
||||
pub fun character/(==)(a: character, b: character): bool
|
||||
match (a, b)
|
||||
(Special-Week, Special-Week) -> True
|
||||
(Silence-Suzuka, Silence-Suzuka) -> True
|
||||
(Tokai-Teio, Tokai-Teio) -> True
|
||||
(Maruzensky, Maruzensky) -> True
|
||||
(Fuji-Kiseki, Fuji-Kiseki) -> True
|
||||
(Oguri-Cap, Oguri-Cap) -> True
|
||||
(Gold-Ship, Gold-Ship) -> True
|
||||
(Vodka, Vodka) -> True
|
||||
(Daiwa-Scarlet, Daiwa-Scarlet) -> True
|
||||
(Taiki-Shuttle, Taiki-Shuttle) -> True
|
||||
(Grass-Wonder, Grass-Wonder) -> True
|
||||
(Hishi-Amazon, Hishi-Amazon) -> True
|
||||
(Mejiro-McQueen, Mejiro-McQueen) -> True
|
||||
(El-Condor-Pasa, El-Condor-Pasa) -> True
|
||||
(TM-Opera-O, TM-Opera-O) -> True
|
||||
(Narita-Brian, Narita-Brian) -> True
|
||||
(Symboli-Rudolf, Symboli-Rudolf) -> True
|
||||
(Air-Groove, Air-Groove) -> True
|
||||
(Agnes-Digital, Agnes-Digital) -> True
|
||||
(Seiun-Sky, Seiun-Sky) -> True
|
||||
(Tamamo-Cross, Tamamo-Cross) -> True
|
||||
(Fine-Motion, Fine-Motion) -> True
|
||||
(Biwa-Hayahide, Biwa-Hayahide) -> True
|
||||
(Mayano-Top-Gun, Mayano-Top-Gun) -> True
|
||||
(Manhattan-Cafe, Manhattan-Cafe) -> True
|
||||
(Mihono-Bourbon, Mihono-Bourbon) -> True
|
||||
(Mejiro-Ryan, Mejiro-Ryan) -> True
|
||||
(Hishi-Akebono, Hishi-Akebono) -> True
|
||||
(Rice-Shower, Rice-Shower) -> True
|
||||
(Agnes-Tachyon, Agnes-Tachyon) -> True
|
||||
(Admire-Vega, Admire-Vega) -> True
|
||||
(Inari-One, Inari-One) -> True
|
||||
(Winning-Ticket, Winning-Ticket) -> True
|
||||
(Eishin-Flash, Eishin-Flash) -> True
|
||||
(Curren-Chan, Curren-Chan) -> True
|
||||
(Kawakami-Princess, Kawakami-Princess) -> True
|
||||
(Gold-City, Gold-City) -> True
|
||||
(Sakura-Bakushin-O, Sakura-Bakushin-O) -> True
|
||||
(Sweep-Tosho, Sweep-Tosho) -> True
|
||||
(Super-Creek, Super-Creek) -> True
|
||||
(Smart-Falcon, Smart-Falcon) -> True
|
||||
(Tosen-Jordan, Tosen-Jordan) -> True
|
||||
(Narita-Taishin, Narita-Taishin) -> True
|
||||
(Nishino-Flower, Nishino-Flower) -> True
|
||||
(Haru-Urara, Haru-Urara) -> True
|
||||
(Matikanefukukitaru, Matikanefukukitaru) -> True
|
||||
(Meisho-Doto, Meisho-Doto) -> True
|
||||
(Mejiro-Dober, Mejiro-Dober) -> True
|
||||
(Nice-Nature, Nice-Nature) -> True
|
||||
(King-Halo, King-Halo) -> True
|
||||
_ -> False
|
||||
|
||||
fip fun character/index(^c: character): int
|
||||
match c
|
||||
Special-Week -> 0
|
||||
Silence-Suzuka -> 1
|
||||
Tokai-Teio -> 2
|
||||
Maruzensky -> 3
|
||||
Fuji-Kiseki -> 4
|
||||
Oguri-Cap -> 5
|
||||
Gold-Ship -> 6
|
||||
Vodka -> 7
|
||||
Daiwa-Scarlet -> 8
|
||||
Taiki-Shuttle -> 9
|
||||
Grass-Wonder -> 10
|
||||
Hishi-Amazon -> 11
|
||||
Mejiro-McQueen -> 12
|
||||
El-Condor-Pasa -> 13
|
||||
TM-Opera-O -> 14
|
||||
Narita-Brian -> 15
|
||||
Symboli-Rudolf -> 16
|
||||
Air-Groove -> 17
|
||||
Agnes-Digital -> 18
|
||||
Seiun-Sky -> 19
|
||||
Tamamo-Cross -> 20
|
||||
Fine-Motion -> 21
|
||||
Biwa-Hayahide -> 22
|
||||
Mayano-Top-Gun -> 23
|
||||
Manhattan-Cafe -> 24
|
||||
Mihono-Bourbon -> 25
|
||||
Mejiro-Ryan -> 26
|
||||
Hishi-Akebono -> 27
|
||||
Rice-Shower -> 28
|
||||
Agnes-Tachyon -> 29
|
||||
Admire-Vega -> 30
|
||||
Inari-One -> 31
|
||||
Winning-Ticket -> 32
|
||||
Eishin-Flash -> 33
|
||||
Curren-Chan -> 34
|
||||
Kawakami-Princess -> 35
|
||||
Gold-City -> 36
|
||||
Sakura-Bakushin-O -> 37
|
||||
Sweep-Tosho -> 38
|
||||
Super-Creek -> 39
|
||||
Smart-Falcon -> 40
|
||||
Tosen-Jordan -> 41
|
||||
Narita-Taishin -> 42
|
||||
Nishino-Flower -> 43
|
||||
Haru-Urara -> 44
|
||||
Matikanefukukitaru -> 45
|
||||
Meisho-Doto -> 46
|
||||
Mejiro-Dober -> 47
|
||||
Nice-Nature -> 48
|
||||
King-Halo -> 49
|
||||
fun character/index(c: character-id): int
|
||||
match c.game-id
|
||||
1001 -> 0
|
||||
1002 -> 1
|
||||
1003 -> 2
|
||||
1004 -> 3
|
||||
1005 -> 4
|
||||
1006 -> 5
|
||||
1007 -> 6
|
||||
1008 -> 7
|
||||
1009 -> 8
|
||||
1010 -> 9
|
||||
1011 -> 10
|
||||
1012 -> 11
|
||||
1013 -> 12
|
||||
1014 -> 13
|
||||
1015 -> 14
|
||||
1016 -> 15
|
||||
1017 -> 16
|
||||
1018 -> 17
|
||||
1019 -> 18
|
||||
1020 -> 19
|
||||
1021 -> 20
|
||||
1022 -> 21
|
||||
1023 -> 22
|
||||
1024 -> 23
|
||||
1025 -> 24
|
||||
1026 -> 25
|
||||
1027 -> 26
|
||||
1028 -> 27
|
||||
1030 -> 28
|
||||
1032 -> 29
|
||||
1033 -> 30
|
||||
1034 -> 31
|
||||
1035 -> 32
|
||||
1037 -> 33
|
||||
1038 -> 34
|
||||
1039 -> 35
|
||||
1040 -> 36
|
||||
1041 -> 37
|
||||
1044 -> 38
|
||||
1045 -> 39
|
||||
1046 -> 40
|
||||
1048 -> 41
|
||||
1050 -> 42
|
||||
1051 -> 43
|
||||
1052 -> 44
|
||||
1056 -> 45
|
||||
1058 -> 46
|
||||
1059 -> 47
|
||||
1060 -> 48
|
||||
1061 -> 49
|
||||
_ -> -99999999
|
||||
|
||||
// Create the table of all pair affinities.
|
||||
// The affinity is the value at a.index*count + b.index.
|
||||
@@ -544,7 +344,7 @@ extern global/create-pair-table(): vector<int>
|
||||
val global/pair-table = global/create-pair-table()
|
||||
|
||||
// Base affinity between a pair using the global ruleset.
|
||||
pub fun global/pair-affinity(a: character, b: character): int
|
||||
pub fun global/pair-affinity(a: character-id, b: character-id): int
|
||||
global/pair-table.at(a.index * 50 + b.index).default(0)
|
||||
|
||||
// Create the table of all trio affinities.
|
||||
@@ -555,5 +355,5 @@ extern global/create-trio-table(): vector<int>
|
||||
val global/trio-table = global/create-trio-table()
|
||||
|
||||
// Base affinity for a trio using the global ruleset.
|
||||
pub fun global/trio-affinity(a: character, b: character, c: character): int
|
||||
pub fun global/trio-affinity(a: character-id, b: character-id, c: character-id): int
|
||||
global/trio-table.at(a.index * 50 * 50 + b.index * 50 + c.index).default(0)
|
||||
File diff suppressed because it is too large
Load Diff
17167
horse/global/skill.kk
17167
horse/global/skill.kk
File diff suppressed because it is too large
Load Diff
104
horse/movement.kk
Normal file
104
horse/movement.kk
Normal file
@@ -0,0 +1,104 @@
|
||||
module horse/movement
|
||||
|
||||
// Running styles.
|
||||
pub type style
|
||||
Front-Runner
|
||||
Pace-Chaser
|
||||
Late-Surger
|
||||
End-Closer
|
||||
|
||||
// Automatically generated.
|
||||
// Equality comparison of the `style` type.
|
||||
pub fun style/(==)(this : style, other : style) : e bool
|
||||
match (this, other)
|
||||
(Front-Runner, Front-Runner) -> True
|
||||
(Pace-Chaser, Pace-Chaser) -> True
|
||||
(Late-Surger, Late-Surger) -> True
|
||||
(End-Closer, End-Closer) -> True
|
||||
(_, _) -> False
|
||||
|
||||
// Shows a string representation of the `style` type.
|
||||
pub fun style/show(this : style) : e string
|
||||
match this
|
||||
Front-Runner -> "Front Runner"
|
||||
Pace-Chaser -> "Pace Chaser"
|
||||
Late-Surger -> "Late Surger"
|
||||
End-Closer -> "End Closer"
|
||||
|
||||
// Starting aptitude levels.
|
||||
pub type level
|
||||
G
|
||||
F
|
||||
E
|
||||
D
|
||||
C
|
||||
B
|
||||
A
|
||||
S
|
||||
|
||||
// Automatically generated.
|
||||
// Comparison of the `level` type.
|
||||
pub fun level/cmp(this : level, other : level) : e order
|
||||
match (this, other)
|
||||
(G, G) -> Eq
|
||||
(G, _) -> Lt
|
||||
(_, G) -> Gt
|
||||
(F, F) -> Eq
|
||||
(F, _) -> Lt
|
||||
(_, F) -> Gt
|
||||
(E, E) -> Eq
|
||||
(E, _) -> Lt
|
||||
(_, E) -> Gt
|
||||
(D, D) -> Eq
|
||||
(D, _) -> Lt
|
||||
(_, D) -> Gt
|
||||
(C, C) -> Eq
|
||||
(C, _) -> Lt
|
||||
(_, C) -> Gt
|
||||
(B, B) -> Eq
|
||||
(B, _) -> Lt
|
||||
(_, B) -> Gt
|
||||
(A, A) -> Eq
|
||||
(A, _) -> Lt
|
||||
(_, A) -> Gt
|
||||
(S, S) -> Eq
|
||||
|
||||
// Automatically generated.
|
||||
// Fip comparison of the `level` type.
|
||||
pub fun level/order2(this : level, other : level) : order2<level>
|
||||
match (this, other)
|
||||
(G, G) -> Eq2(G)
|
||||
(G, other') -> Lt2(G, other')
|
||||
(this', G) -> Gt2(G, this')
|
||||
(F, F) -> Eq2(F)
|
||||
(F, other') -> Lt2(F, other')
|
||||
(this', F) -> Gt2(F, this')
|
||||
(E, E) -> Eq2(E)
|
||||
(E, other') -> Lt2(E, other')
|
||||
(this', E) -> Gt2(E, this')
|
||||
(D, D) -> Eq2(D)
|
||||
(D, other') -> Lt2(D, other')
|
||||
(this', D) -> Gt2(D, this')
|
||||
(C, C) -> Eq2(C)
|
||||
(C, other') -> Lt2(C, other')
|
||||
(this', C) -> Gt2(C, this')
|
||||
(B, B) -> Eq2(B)
|
||||
(B, other') -> Lt2(B, other')
|
||||
(this', B) -> Gt2(B, this')
|
||||
(A, A) -> Eq2(A)
|
||||
(A, other') -> Lt2(A, other')
|
||||
(this', A) -> Gt2(A, this')
|
||||
(S, S) -> Eq2(S)
|
||||
|
||||
// Automatically generated.
|
||||
// Shows a string representation of the `level` type.
|
||||
pub fun level/show(this : level) : string
|
||||
match this
|
||||
G -> "G"
|
||||
F -> "F"
|
||||
E -> "E"
|
||||
D -> "D"
|
||||
C -> "C"
|
||||
B -> "B"
|
||||
A -> "A"
|
||||
S -> "S"
|
||||
226
horse/skill.kk
Normal file
226
horse/skill.kk
Normal 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"
|
||||
@@ -1,70 +1,16 @@
|
||||
module horse/trainee
|
||||
|
||||
import std/data/rb-map
|
||||
import horse/movement
|
||||
|
||||
// Aptitudes of an umamusume being trained.
|
||||
pub struct uma
|
||||
turf: aptitudes
|
||||
dirt: aptitudes
|
||||
sprint: aptitudes
|
||||
mile: aptitudes
|
||||
medium: aptitudes
|
||||
long: aptitudes
|
||||
front-runner: aptitudes
|
||||
pace-chaser: aptitudes
|
||||
late-surger: aptitudes
|
||||
end-closer: aptitudes
|
||||
|
||||
// Aptitude level distribution.
|
||||
pub alias aptitudes = rbmap<level, float64>
|
||||
|
||||
// Starting aptitude levels.
|
||||
pub type level
|
||||
G
|
||||
F
|
||||
E
|
||||
D
|
||||
C
|
||||
B
|
||||
A
|
||||
S
|
||||
|
||||
// Automatically generated.
|
||||
// Fip comparison of the `level` type.
|
||||
pub fun level/order2(this : level, other : level) : order2<level>
|
||||
match (this, other)
|
||||
(G, G) -> Eq2(G)
|
||||
(G, other') -> Lt2(G, other')
|
||||
(this', G) -> Gt2(G, this')
|
||||
(F, F) -> Eq2(F)
|
||||
(F, other') -> Lt2(F, other')
|
||||
(this', F) -> Gt2(F, this')
|
||||
(E, E) -> Eq2(E)
|
||||
(E, other') -> Lt2(E, other')
|
||||
(this', E) -> Gt2(E, this')
|
||||
(D, D) -> Eq2(D)
|
||||
(D, other') -> Lt2(D, other')
|
||||
(this', D) -> Gt2(D, this')
|
||||
(C, C) -> Eq2(C)
|
||||
(C, other') -> Lt2(C, other')
|
||||
(this', C) -> Gt2(C, this')
|
||||
(B, B) -> Eq2(B)
|
||||
(B, other') -> Lt2(B, other')
|
||||
(this', B) -> Gt2(B, this')
|
||||
(A, A) -> Eq2(A)
|
||||
(A, other') -> Lt2(A, other')
|
||||
(this', A) -> Gt2(A, this')
|
||||
(S, S) -> Eq2(S)
|
||||
|
||||
// Automatically generated.
|
||||
// Shows a string representation of the `level` type.
|
||||
pub fun level/show(this : level) : string
|
||||
match this
|
||||
G -> "G"
|
||||
F -> "F"
|
||||
E -> "E"
|
||||
D -> "D"
|
||||
C -> "C"
|
||||
B -> "B"
|
||||
A -> "A"
|
||||
S -> "S"
|
||||
// Details of a trainee.
|
||||
pub struct trainee-detail
|
||||
turf: level
|
||||
dirt: level
|
||||
sprint: level
|
||||
mile: level
|
||||
medium: level
|
||||
long: level
|
||||
front-runner: level
|
||||
pace-chaser: level
|
||||
late-surger: level
|
||||
end-closer: level
|
||||
|
||||
@@ -5,67 +5,55 @@ module horse/{{ $.Region }}/character
|
||||
|
||||
import std/core/vector
|
||||
import std/core-extras
|
||||
import std/data/rb-map
|
||||
import horse/game-id
|
||||
pub import horse/character
|
||||
|
||||
// Character identity.
|
||||
// Enumeration of all characters for type-safe programming.
|
||||
pub type character
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }}
|
||||
{{- end }}
|
||||
|
||||
// The list of all characters in order by ID, for easy iterating.
|
||||
pub val character/all = [
|
||||
// Get the character ID for a character.
|
||||
pub fun character-id(c: character): character-id
|
||||
match c
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }} -> Character-id({{ $uma.ID }})
|
||||
{{- end }}
|
||||
|
||||
// List of all characters in ID order for easy iterating.
|
||||
pub val all = [
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }},
|
||||
{{- end }}
|
||||
]
|
||||
|
||||
// Get the character for a character ID.
|
||||
// Generally, these are four digit numbers in the range 1000-1999.
|
||||
pub fun character/from-id(id: int): maybe<character>
|
||||
match id
|
||||
val name2id: rbmap<string, character-id> = rb-map/empty()
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ $uma.ID }} -> Just( {{- kkenum $uma.Name -}} )
|
||||
.set({{ printf "%q" $uma.Name }}, Character-id({{ $uma.ID}}))
|
||||
{{- end }}
|
||||
_ -> Nothing
|
||||
|
||||
// Get the ID for a character.
|
||||
pub fun character/character-id(c: character): int
|
||||
match c
|
||||
// Get the character ID that has the given exact name.
|
||||
// If no character matches the name, the result is an invalid ID.
|
||||
pub fun from-name(name: string): character-id
|
||||
name2id.lookup(name).default(Character-id(0))
|
||||
|
||||
// Get the name for a character.
|
||||
// If no character matches the ID, the result is the numeric ID.
|
||||
pub fun show(c: character-id): string
|
||||
match c.game-id
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }} -> {{ $uma.ID }}
|
||||
{{ $uma.ID }} -> {{ printf "%q" $uma.Name }}
|
||||
{{- end }}
|
||||
x -> "character " ++ x.show
|
||||
|
||||
// Get the name of a character.
|
||||
pub fun character/show(c: character): string
|
||||
match c
|
||||
fun character/index(c: character-id): int
|
||||
match c.game-id
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }} -> {{ printf "%q" $uma.Name }}
|
||||
{{- end }}
|
||||
|
||||
// Compare two characters.
|
||||
pub fip fun character/order2(a: character, b: character): order2<character>
|
||||
match (a, b)
|
||||
{{- range $uma := $.Characters }}{{ $e := kkenum $uma.Name }}
|
||||
( {{- $e }}, {{ $e -}} ) -> Eq2( {{- $e -}} )
|
||||
{{- if ne $uma.ID $.MaxID }}
|
||||
( {{- $e }}, b') -> Lt2( {{- $e }}, b')
|
||||
(a', {{ $e -}} ) -> Gt2( {{- $e }}, a')
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
// Character equality.
|
||||
pub fun character/(==)(a: character, b: character): bool
|
||||
match (a, b)
|
||||
{{- range $uma := $.Characters }}{{ $e := kkenum $uma.Name }}
|
||||
( {{- $e }}, {{ $e -}} ) -> True
|
||||
{{- end }}
|
||||
_ -> False
|
||||
|
||||
fip fun character/index(^c: character): int
|
||||
match c
|
||||
{{- range $uma := $.Characters }}
|
||||
{{ kkenum $uma.Name }} -> {{ $uma.Index }}
|
||||
{{ $uma.ID }} -> {{ $uma.Index }}
|
||||
{{- end }}
|
||||
_ -> -99999999
|
||||
|
||||
// Create the table of all pair affinities.
|
||||
// The affinity is the value at a.index*count + b.index.
|
||||
@@ -87,7 +75,7 @@ extern global/create-pair-table(): vector<int>
|
||||
val global/pair-table = global/create-pair-table()
|
||||
|
||||
// Base affinity between a pair using the global ruleset.
|
||||
pub fun global/pair-affinity(a: character, b: character): int
|
||||
pub fun global/pair-affinity(a: character-id, b: character-id): int
|
||||
global/pair-table.at(a.index * {{ $.Count }} + b.index).default(0)
|
||||
|
||||
// Create the table of all trio affinities.
|
||||
@@ -114,7 +102,7 @@ extern global/create-trio-table(): vector<int>
|
||||
val global/trio-table = global/create-trio-table()
|
||||
|
||||
// Base affinity for a trio using the global ruleset.
|
||||
pub fun global/trio-affinity(a: character, b: character, c: character): int
|
||||
pub fun global/trio-affinity(a: character-id, b: character-id, c: character-id): int
|
||||
global/trio-table.at(a.index * {{ $.Count }} * {{ $.Count }} + b.index * {{ $.Count }} + c.index).default(0)
|
||||
|
||||
{{- end }}
|
||||
|
||||
@@ -93,15 +93,6 @@ func ExecSkill(t *template.Template, region string, kk, g io.Writer, groups []Na
|
||||
return err
|
||||
}
|
||||
|
||||
func ExecSkillGroupKK(t *template.Template, region string, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
|
||||
data := struct {
|
||||
Region string
|
||||
Groups []NamedID[SkillGroup]
|
||||
Skills []Skill
|
||||
}{region, g, s}
|
||||
return t.ExecuteTemplate(w, "koka-skill-group", &data)
|
||||
}
|
||||
|
||||
const wordSeps = " ,!?/-+();#○☆♡'=♪∀゚∴"
|
||||
|
||||
var (
|
||||
@@ -159,6 +150,7 @@ func kkenum(name string) string {
|
||||
}
|
||||
name = strings.ToUpper(name[:1]) + name[1:]
|
||||
if !unicode.IsLetter(rune(name[0])) {
|
||||
//lint:ignore ST1005 proper name
|
||||
panic(fmt.Errorf("Koka enum variant %q (from %q) starts with a non-letter", name, orig))
|
||||
}
|
||||
for _, c := range name {
|
||||
|
||||
@@ -191,6 +191,7 @@ type Skill struct {
|
||||
Activations [2]SkillActivation
|
||||
SPCost int
|
||||
InheritID int
|
||||
UniqueOwnerID int
|
||||
UniqueOwner string
|
||||
IconID int
|
||||
Index int
|
||||
@@ -305,9 +306,10 @@ func Skills(ctx context.Context, db *sqlitex.Pool) ([]Skill, error) {
|
||||
},
|
||||
SPCost: stmt.ColumnInt(47),
|
||||
InheritID: stmt.ColumnInt(48),
|
||||
UniqueOwner: stmt.ColumnText(49),
|
||||
IconID: stmt.ColumnInt(50),
|
||||
Index: stmt.ColumnInt(51),
|
||||
UniqueOwnerID: stmt.ColumnInt(49),
|
||||
UniqueOwner: stmt.ColumnText(50),
|
||||
IconID: stmt.ColumnInt(51),
|
||||
Index: stmt.ColumnInt(52),
|
||||
}
|
||||
r = append(r, s)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func main() {
|
||||
region string
|
||||
)
|
||||
flag.StringVar(&mdb, "mdb", os.ExpandEnv(`$USERPROFILE\AppData\LocalLow\Cygames\Umamusume\master\master.mdb`), "`path` to Umamusume master.mdb")
|
||||
flag.StringVar(&out, "o", `.\horse`, "`dir`ectory for output files")
|
||||
flag.StringVar(&out, "o", `horse`, "`dir`ectory for output files")
|
||||
flag.StringVar(®ion, "region", "global", "region the database is for (global, jp)")
|
||||
flag.Parse()
|
||||
|
||||
@@ -110,16 +110,11 @@ func main() {
|
||||
return err
|
||||
}
|
||||
gf, err := os.Create(filepath.Join(out, region, "skill.go"))
|
||||
slog.Info("write skills")
|
||||
return ExecSkill(t, region, sf, gf, sg, skills)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
sf, err := os.Create(filepath.Join(out, region, "skill-group.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.Info("write skill groups")
|
||||
return ExecSkillGroupKK(t, region, sf, sg, skills)
|
||||
slog.Info("write skills")
|
||||
return ExecSkill(t, region, sf, gf, sg, skills)
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
slog.Error("generate", slog.Any("err", err))
|
||||
|
||||
@@ -1,347 +1,233 @@
|
||||
{{- define "koka-skill-group" -}}
|
||||
module horse/{{ $.Region }}/skill-group
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
// Skill groups.
|
||||
// A skill group may contain white, circle, double-circle, gold, and purple skills
|
||||
// for the same effect.
|
||||
// Sparks that grant skills refer to a skill group.
|
||||
pub type skill-group
|
||||
{{- range $g := $.Groups }}
|
||||
{{ kkenum $g.Name }}
|
||||
{{- end }}
|
||||
|
||||
// Map a skill group to its ID.
|
||||
pub fip fun skill-group/group-id(^sg: skill-group): int
|
||||
match sg
|
||||
{{- range $g := $.Groups }}
|
||||
{{ kkenum $g.Name }} -> {{ $g.ID }}
|
||||
{{- end }}
|
||||
|
||||
// Get the skill group for an ID.
|
||||
pub fip(1) fun skill-group/from-id(^id: int): maybe<skill-group>
|
||||
match id
|
||||
{{- range $g := $.Groups }}
|
||||
{{ $g.ID }} -> Just( {{- kkenum $g.Name -}} )
|
||||
{{- end }}
|
||||
_ -> Nothing
|
||||
|
||||
// Get the name for a skill group.
|
||||
// Skill group names are the name of the base skill in the group.
|
||||
pub fun skill-group/show(sg: skill-group): string
|
||||
match sg
|
||||
{{- range $g := $.Groups }}
|
||||
{{ kkenum $g.Name }} -> {{ printf "%q" $g.Name }}
|
||||
{{- end }}
|
||||
|
||||
// Compare two skill groups by ID order.
|
||||
pub fip fun skill-group/order2(a: skill-group, b: skill-group): order2<skill-group>
|
||||
match cmp(a.group-id, b.group-id)
|
||||
Lt -> Lt2(a, b)
|
||||
Eq -> Eq2(a)
|
||||
Gt -> Gt2(a, b)
|
||||
|
||||
pub fun skill-group/(==)(a: skill-group, b: skill-group): bool
|
||||
a.group-id == b.group-id
|
||||
|
||||
{{- end -}}
|
||||
|
||||
{{- define "koka-skill" -}}
|
||||
module horse/{{ $.Region }}/skill
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
import std/data/rb-map
|
||||
import std/num/decimal
|
||||
pub import horse/{{ $.Region }}/skill-group
|
||||
import horse/game-id
|
||||
import horse/movement
|
||||
pub import horse/skill
|
||||
|
||||
// Skill instances.
|
||||
// Enumeration of all skills for type-safe programming.
|
||||
pub type skill
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }}{{ if ne $s.InheritID 0 }}-Inherit{{ end -}}
|
||||
{{ kkenum $s.Name }}{{ if $s.InheritID }}-Inherit{{ end }}
|
||||
{{- end }}
|
||||
|
||||
// Map a skill to its ID.
|
||||
pub fip fun skill/skill-id(^s: skill): int
|
||||
// Get the skill ID for a skill.
|
||||
pub fun skill-id(s: skill): skill-id
|
||||
match s
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }}{{ if ne $s.InheritID 0 }}-Inherit{{ end }} -> {{ $s.ID }}
|
||||
{{ kkenum $s.Name }}{{ if $s.InheritID }}-Inherit{{ end }} -> Skill-id({{ $s.ID }})
|
||||
{{- end }}
|
||||
|
||||
// Get the skill for an ID.
|
||||
pub fip(1) fun skill/from-id(^id: int): maybe<skill>
|
||||
match id
|
||||
// List of all skills in ID order for easy iterating.
|
||||
pub val all = [
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> Just( {{- kkenum $s.Name -}}{{ if ne $s.InheritID 0 }}-Inherit{{ end -}} )
|
||||
{{ kkenum $s.Name }}{{ if $s.InheritID }}-Inherit{{ end }},
|
||||
{{- end }}
|
||||
]
|
||||
|
||||
val name2id: rbmap<string, skill-id> = rb-map/empty()
|
||||
{{- range $s := $.Skills }}
|
||||
.set({{ printf "%q" $s.Name }}{{ if $s.InheritID }} ++ " (Inherited)"{{ end }}, Skill-id({{ $s.ID }}))
|
||||
{{- end }}
|
||||
|
||||
// Get the skill ID that has the given exact name.
|
||||
// Inherited skills have `" (Inherited)"` appended to their names.
|
||||
// If no skill matches the name, the result is an invalid ID.
|
||||
pub fun from-name(name: string): skill-id
|
||||
name2id.lookup(name).default(Skill-id(0))
|
||||
|
||||
// Get the name for a skill.
|
||||
// Inherited skills have `" (Inherited)"` appended to their names.
|
||||
// If no skill matches the ID, the result is the numeric ID.
|
||||
pub fun show(s: skill-id): string
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ printf "%q" $s.Name }}{{ if $s.InheritID }} ++ " (Inherited)"{{ end }}
|
||||
{{- end }}
|
||||
x -> "skill " ++ x.show
|
||||
|
||||
// Get the description for a skill.
|
||||
// If no skill matches the ID, the result is the empty string.
|
||||
pub fun description(s: skill-id): string
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ printf "%q" $s.Description }}
|
||||
{{- end }}
|
||||
_ -> ""
|
||||
|
||||
// Get the skill group ID for a skill.
|
||||
// If no skill matches the ID, the result is an invalid ID.
|
||||
pub fun group(s: skill-id): skill-group-id
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> Skill-group-id( {{- $s.GroupID -}} )
|
||||
{{- end }}
|
||||
_ -> Skill-group-id(0)
|
||||
|
||||
// Get the rarity of a skill.
|
||||
// If no skill matches the ID, the result is Common.
|
||||
pub fun rarity(s: skill-id): rarity
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ if eq $s.Rarity 1 }}Common{{ else if eq $s.Rarity 2 }}Rare{{ else if eq $s.Rarity 3 }}Unique-Low{{ else if eq $s.Rarity 4 }}Unique-Upgraded{{ else if eq $s.Rarity 5 }}Unique{{ else }}??? $s.Rarity={{ $s.Rarity }}{{ end }}
|
||||
{{- end }}
|
||||
_ -> Common
|
||||
|
||||
// Get the group rate of a skill.
|
||||
// If no skill matches the ID, the result is 0.
|
||||
pub fun group-rate(s: skill-id): int
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ $s.GroupRate }}
|
||||
{{- end }}
|
||||
_ -> 0
|
||||
|
||||
// Get the grade value of a skill.
|
||||
// If no skill matches the ID, the result is 0.
|
||||
pub fun grade-value(s: skill-id): int
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ $s.GradeValue }}
|
||||
{{- end }}
|
||||
_ -> 0
|
||||
|
||||
// Get whether a skill is a wit check.
|
||||
// If no skill matches the ID, the result is False.
|
||||
pub fun wit-check(s: skill-id): bool
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> {{ if $s.WitCheck }}True{{ else }}False{{ end }}
|
||||
{{- end }}
|
||||
_ -> False
|
||||
|
||||
// Get the activations of a skill.
|
||||
// If no skill matches the ID, the result is an empty list.
|
||||
pub fun activations(s: skill-id): list<activation>
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> [
|
||||
{{- range $a := $s.Activations }}
|
||||
{{- if $a.Condition }}
|
||||
Activation(
|
||||
precondition = {{ printf "%q" $a.Precondition }},
|
||||
condition = {{ printf "%q" $a.Condition }},
|
||||
duration = {{ $a.Duration }}.decimal{{ if gt $a.Duration 0 }}(-4){{ end }},
|
||||
cooldown = {{ $a.Cooldown }}.decimal{{ if gt $a.Cooldown 0 }}(-4){{ end }},
|
||||
abilities = [
|
||||
{{- range $abil := $a.Abilities }}
|
||||
{{- if $abil.Type }}
|
||||
Ability(
|
||||
ability-type = {{ if eq $abil.Type 1 }}Passive-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 2 }}Passive-Stamina({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 3 }}Passive-Power({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 4 }}Passive-Guts({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 5 }}Passive-Wit({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 6 }}Great-Escape
|
||||
{{- else if eq $abil.Type 8 }}Vision({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 9 }}HP({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 10 }}Gate-Delay({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 13 }}Frenzy({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 21 }}Current-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 27 }}Target-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 28 }}Lane-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 31 }}Accel({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 35 }}Lane-Change({{ $abil.Value }}.decimal(-4))
|
||||
{{- else }}??? $abil.Type={{$abil.Type}}
|
||||
{{- end }},
|
||||
value-usage = {{ if eq $abil.ValueUsage 1 }}Direct
|
||||
{{- else if eq $abil.ValueUsage 3 }}Team-Speed
|
||||
{{- else if eq $abil.ValueUsage 4 }}Team-Stamina
|
||||
{{- else if eq $abil.ValueUsage 5 }}Team-Power
|
||||
{{- else if eq $abil.ValueUsage 6 }}Team-Guts
|
||||
{{- else if eq $abil.ValueUsage 7 }}Team-Wit
|
||||
{{- else if eq $abil.ValueUsage 8 }}Multiply-Random
|
||||
{{- else if eq $abil.ValueUsage 9 }}Multiply-Random2
|
||||
{{- else if eq $abil.ValueUsage 10 }}Climax
|
||||
{{- else if eq $abil.ValueUsage 13 }}Max-Stat
|
||||
{{- else if eq $abil.ValueUsage 14 }}Passive-Count
|
||||
{{- else if eq $abil.ValueUsage 19 }}Front-Distance-Add
|
||||
{{- else if eq $abil.ValueUsage 20 }}Midrace-Side-Block-Time
|
||||
{{- else if eq $abil.ValueUsage 22 }}Speed-Scaling
|
||||
{{- else if eq $abil.ValueUsage 23 }}Speed-Scaling2
|
||||
{{- else if eq $abil.ValueUsage 24 }}Arc-Global-Potential
|
||||
{{- else if eq $abil.ValueUsage 25 }}Max-Lead-Distance
|
||||
{{- else }}??? $abil.ValueUsage={{ $abil.ValueUsage }}
|
||||
{{- end }},
|
||||
target = {{ if eq $abil.Target 1}}Self
|
||||
{{- else if eq $abil.Target 4 }}Sympathizers
|
||||
{{- else if eq $abil.Target 4 }}In-View
|
||||
{{- else if eq $abil.Target 4 }}Frontmost
|
||||
{{- else if eq $abil.Target 9 }}Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 10 }}Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 4 }}All-Teammates
|
||||
{{- else if eq $abil.Target 18 }}Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- else if eq $abil.Target 19 }}Rushing-Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 20 }}Rushing-Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 21 }}Rushing-Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- else if eq $abil.Target 22 }}Specific-Character(Character-id({{ $abil.TargetValue }}))
|
||||
{{- else if eq $abil.Target 23 }}Triggering
|
||||
{{- end }}
|
||||
),
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
]
|
||||
),
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
]
|
||||
{{- end }}
|
||||
_ -> Nil
|
||||
|
||||
// Get the owner of a unique skill.
|
||||
// If the skill is not unique, or if there is no skill with the given ID,
|
||||
// the result is Nothing.
|
||||
pub fun unique-owner(s: skill-id): maybe<trainee-id>
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{- if $s.UniqueOwnerID }}
|
||||
{{ $s.ID }} -> Just(Trainee-id({{ $s.UniqueOwnerID }}))
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
_ -> Nothing
|
||||
|
||||
// Get the name of a skill.
|
||||
// Inherited skills have the same names as their original counterparts.
|
||||
pub fun skill/show(s: skill): string
|
||||
match s
|
||||
// Get the SP cost of a skill.
|
||||
// If there is no skill with the given ID, the result is 0.
|
||||
pub fun sp-cost(s: skill-id): int
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }}{{ if ne $s.InheritID 0 }}-Inherit{{ end }} -> {{ printf "%q" $s.Name }}
|
||||
{{ $s.ID }} -> {{ $s.SPCost }}
|
||||
{{- end }}
|
||||
_ -> 0
|
||||
|
||||
// Compare two skills by ID order.
|
||||
pub fip fun skill/order2(a: skill, b: skill): order2<skill>
|
||||
match cmp(a.skill-id, b.skill-id)
|
||||
Lt -> Lt2(a, b)
|
||||
Eq -> Eq2(a)
|
||||
Gt -> Gt2(a, b)
|
||||
// Get the icon ID of a skill.
|
||||
// If there is no skill with the given ID, the result is an invalid ID.
|
||||
pub fun icon-id(s: skill-id): skill-icon-id
|
||||
match s.game-id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> Skill-icon-id({{ $s.IconID }})
|
||||
{{- end }}
|
||||
_ -> Skill-icon-id(0)
|
||||
|
||||
pub fun skill/(==)(a: skill, b: skill): bool
|
||||
a.skill-id == b.skill-id
|
||||
|
||||
// Get the skills in a skill group.
|
||||
pub fun skill-group/skills(g: skill-group): list<skill>
|
||||
match g
|
||||
// Get the name for a skill group.
|
||||
// Skill group names are the name of the base skill in the group.
|
||||
// If there is no skill group with the given ID, the result is the numeric ID.
|
||||
pub fun skill-group/show(sg: skill-group-id): string
|
||||
match sg.game-id
|
||||
{{- range $g := $.Groups }}
|
||||
{{ kkenum $g.Name }} -> [ {{- range $s := index $.Related $g.ID }}{{ kkenum $s.Name }}{{ if ne $s.InheritID 0 }}-Inherit{{ end }}, {{ end }}]
|
||||
{{ $g.ID }} -> {{- printf "%q" $g.Name -}}
|
||||
{{- end }}
|
||||
x -> "skill group " ++ x.show
|
||||
|
||||
// Get complete skill info.
|
||||
pub fun skill/detail(^s: skill): skill-detail
|
||||
match s
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }}{{ if ne $s.InheritID 0 }}-Inherit{{ end }} -> {{ template "kk-render-skill-detail" $s }}
|
||||
// Get the list of skills in a skill group.
|
||||
pub fun skill-group/skills(sg: skill-group-id): list<skill-id>
|
||||
match sg.game-id
|
||||
{{- range $g := $.Groups }}
|
||||
{{ $g.ID }} -> [ {{- range $s := index $.Related $g.ID }}Skill-id({{ $s.ID }}), {{ end -}} ]
|
||||
{{- end }}
|
||||
_ -> Nil
|
||||
|
||||
// Details about a skill.
|
||||
pub struct skill-detail
|
||||
skill-id: int
|
||||
name: string
|
||||
description: string
|
||||
group: maybe<skill-group>
|
||||
rarity: rarity
|
||||
group-rate: int
|
||||
grade-value: int
|
||||
wit-check: bool
|
||||
activations: list<activation>
|
||||
sp-cost: int
|
||||
icon-id: int
|
||||
|
||||
// Automatically generated.
|
||||
// Shows a string representation of the `skill-detail` type.
|
||||
pub fun skill-detail/show(this : skill-detail) : e string
|
||||
match this
|
||||
Skill-detail(skill-id, name, description, group, rarity, group-rate, grade-value, wit-check, activations, sp-cost, icon-id) -> "Skill-detail(skill-id: " ++ skill-id.show ++ ", name: " ++ name.show ++ ", description: " ++ description.show ++ ", group: " ++ group.show ++ ", rarity: " ++ rarity.show ++ ", group-rate: " ++ group-rate.show ++ ", grade-value: " ++ grade-value.show ++ ", wit-check: " ++ wit-check.show ++ ", activations: " ++ activations.show ++ ", sp-cost: " ++ sp-cost.show ++ ", icon-id: " ++ icon-id.show ++ ")"
|
||||
|
||||
// Skill rarity.
|
||||
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): string
|
||||
match a
|
||||
Activation("", condition, duration, _, abilities) | duration <= 0.decimal -> condition ++ " -> " ++ abilities.show
|
||||
Activation("", condition, duration, cooldown, abilities) | cooldown >= 500.decimal -> condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s"
|
||||
Activation("", condition, duration, cooldown, abilities) -> condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown"
|
||||
Activation(precondition, condition, duration, _, abilities) | duration <= 0.decimal -> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show
|
||||
Activation(precondition, condition, duration, cooldown, abilities) | cooldown >= 500.decimal -> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s"
|
||||
Activation(precondition, condition, duration, cooldown, abilities) -> precondition ++ "-> " ++ condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown"
|
||||
|
||||
// Effects of activating a skill.
|
||||
pub struct ability
|
||||
ability-type: ability-type
|
||||
value-usage: value-usage
|
||||
target: target
|
||||
|
||||
pub fun ability/show(a: ability): string
|
||||
match a
|
||||
Ability(t, Direct, Self) -> t.show
|
||||
Ability(t, Direct, target) -> t.show ++ " " ++ target.show
|
||||
Ability(t, v, Self) -> t.show ++ " scaling by " ++ v.show
|
||||
Ability(t, v, target) -> t.show ++ " " ++ target.show ++ " scaling by " ++ v.show
|
||||
|
||||
// Target of a skill activation effect.
|
||||
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(rate: decimal)
|
||||
Target-Speed(rate: decimal)
|
||||
Lane-Speed(rate: decimal)
|
||||
Accel(rate: decimal)
|
||||
Lane-Change(rate: decimal)
|
||||
|
||||
pub fun ability-type/show(a: ability-type): string
|
||||
match a
|
||||
Passive-Speed(bonus) -> "passive " ++ bonus.show ++ " Speed"
|
||||
Passive-Stamina(bonus) -> "passive " ++ bonus.show ++ " Stamina"
|
||||
Passive-Power(bonus) -> "passive " ++ bonus.show ++ " Power"
|
||||
Passive-Guts(bonus) -> "passive " ++ bonus.show ++ " Guts"
|
||||
Passive-Wit(bonus) -> "passive " ++ bonus.show ++ " Wit"
|
||||
Great-Escape -> "enable Great Escape style"
|
||||
Vision(bonus) -> bonus.show ++ " vision"
|
||||
HP(rate) | rate >= 0.decimal -> 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) -> show(rate * 100.decimal) ++ "% current speed"
|
||||
Target-Speed(rate) -> show(rate * 100.decimal) ++ "% target speed"
|
||||
Lane-Speed(rate) -> show(rate * 100.decimal) ++ "% lane speed"
|
||||
Accel(rate) -> show(rate * 100.decimal) ++ "% acceleration"
|
||||
Lane-Change(rate) -> rate.show ++ " course width movement"
|
||||
|
||||
// Special scaling for skill activation effects.
|
||||
pub type value-usage
|
||||
Direct
|
||||
Team-Speed
|
||||
Team-Stamina
|
||||
Team-Power
|
||||
Team-Guts
|
||||
Team-Wit
|
||||
Multiply-Random
|
||||
|
||||
pub fun value-usage/show(v: value-usage): string
|
||||
match v
|
||||
Direct -> "no scaling"
|
||||
Team-Speed -> "team's Speed"
|
||||
Team-Stamina -> "team's Stamina"
|
||||
Team-Power -> "team's Power"
|
||||
Team-Guts -> "team's Guts"
|
||||
Team-Wit -> "team's Wit"
|
||||
Multiply-Random -> "random multiplier (0×, 0.02×, or 0.04×)"
|
||||
|
||||
// Who a skill activation targets.
|
||||
pub type target
|
||||
Self
|
||||
In-View
|
||||
Ahead(limit: int)
|
||||
Behind(limit: int)
|
||||
Style(style: style)
|
||||
Rushing-Ahead(limit: int)
|
||||
Rushing-Behind(limit: int)
|
||||
Rushing-Style(style: style)
|
||||
|
||||
pub fun target/show(t: target): string
|
||||
match t
|
||||
Self -> "self"
|
||||
In-View -> "others in field of view"
|
||||
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"
|
||||
Style(Front-Runner) -> "other Front Runners"
|
||||
Style(Pace-Chaser) -> "other Pace Chasers"
|
||||
Style(Late-Surger) -> "other Late Surgers"
|
||||
Style(End-Closer) -> "other End Closers"
|
||||
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(Front-Runner) -> "rushing Front Runners"
|
||||
Rushing-Style(Pace-Chaser) -> "rushing Pace Chasers"
|
||||
Rushing-Style(Late-Surger) -> "rushing Late Surgers"
|
||||
Rushing-Style(End-Closer) -> "rushing End Closers"
|
||||
|
||||
// Running style for skill targets.
|
||||
{{- /* TODO(zeph): there is definitely a better place for this to live */}}
|
||||
pub type style
|
||||
Front-Runner
|
||||
Pace-Chaser
|
||||
Late-Surger
|
||||
End-Closer
|
||||
|
||||
{{- end -}}
|
||||
|
||||
{{ define "kk-render-skill-detail" }}
|
||||
{{- /* Call with Skill structure as argument. */ -}}
|
||||
Skill-detail(skill-id = {{ $.ID -}}
|
||||
, name = {{ printf "%q" $.Name -}}
|
||||
, description = {{ printf "%q" $.Description -}}
|
||||
, group = {{ if ne $.GroupName "" }}Just({{ kkenum $.GroupName }}){{ else }}Nothing{{ end -}}
|
||||
, rarity = {{ if eq $.Rarity 1 }}Common{{ else if eq $.Rarity 2 }}Rare{{ else if eq $.Rarity 3 }}Unique-Low{{ else if eq $.Rarity 4 }}Unique-Upgraded{{ else if eq $.Rarity 5 }}Unique{{ else }}??? $.Rarity={{ $.Rarity }}{{ end -}}
|
||||
, group-rate = {{ $.GroupRate -}}
|
||||
, grade-value = {{ $.GradeValue -}}
|
||||
, wit-check = {{ if $.WitCheck }}True{{ else }}False{{ end -}}
|
||||
, activations = [
|
||||
{{- range $a := $.Activations -}}
|
||||
{{- if ne $a.Condition "" -}}
|
||||
Activation(precondition = {{ printf "%q" $a.Precondition -}}
|
||||
, condition = {{ printf "%q" $a.Condition -}}
|
||||
, duration = {{ $a.Duration -}}{{ if gt $a.Duration 0 }}.decimal(-4){{ else }}.decimal{{ end -}}
|
||||
, cooldown = {{ $a.Cooldown -}}{{ if gt $a.Cooldown 0 }}.decimal(-4){{ else }}.decimal{{ end -}}
|
||||
, abilities = [
|
||||
{{- range $abil := $a.Abilities -}}
|
||||
{{- if ne $abil.Type 0 -}}
|
||||
Ability(ability-type =
|
||||
{{- if eq $abil.Type 1 -}}Passive-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 2 -}}Passive-Stamina({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 3 -}}Passive-Power({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 4 -}}Passive-Guts({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 5 -}}Passive-Wit({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 6 -}}Great-Escape
|
||||
{{- else if eq $abil.Type 8 -}}Vision({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 9 -}}HP({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 10 -}}Gate-Delay({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 13 -}}Frenzy({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 21 -}}Current-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 27 -}}Target-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 28 -}}Lane-Speed({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 31 -}}Accel({{ $abil.Value }}.decimal(-4))
|
||||
{{- else if eq $abil.Type 35 -}}Lane-Change({{ $abil.Value }}.decimal(-4))
|
||||
{{- else -}}??? $abil.Type={{$abil.Type}}
|
||||
{{- end -}}
|
||||
, value-usage =
|
||||
{{- if eq $abil.ValueUsage 1 -}}Direct
|
||||
{{- else if eq $abil.ValueUsage 3 -}}Team-Speed
|
||||
{{- else if eq $abil.ValueUsage 4 -}}Team-Stamina
|
||||
{{- else if eq $abil.ValueUsage 5 -}}Team-Power
|
||||
{{- else if eq $abil.ValueUsage 6 -}}Team-Guts
|
||||
{{- else if eq $abil.ValueUsage 7 -}}Team-Wit
|
||||
{{- else if eq $abil.ValueUsage 8 -}}Multiply-Random
|
||||
{{- else -}}??? $abil.ValueUsage={{ $abil.ValueUsage }}
|
||||
{{- end -}}
|
||||
, target =
|
||||
{{- if eq $abil.Target 1 -}}Self
|
||||
{{- else if eq $abil.Target 4 -}}In-View
|
||||
{{- else if eq $abil.Target 9 -}}Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 10 -}}Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 18 -}}Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- else if eq $abil.Target 19 -}}Rushing-Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 20 -}}Rushing-Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 21 -}}Rushing-Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- end -}}
|
||||
),
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
]),
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
], sp-cost = {{ $.SPCost -}}
|
||||
, icon-id = {{ $.IconID -}}
|
||||
)
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
@@ -21,6 +21,7 @@ WITH skill_names AS (
|
||||
), card_unique AS (
|
||||
SELECT DISTINCT
|
||||
ss.skill_id1 AS unique_id,
|
||||
card_name.id AS owner_id,
|
||||
card_name.name
|
||||
FROM card_data card
|
||||
JOIN card_name ON card.id = card_name.id
|
||||
@@ -81,6 +82,7 @@ SELECT
|
||||
d.target_value_2_3,
|
||||
IFNULL(p.need_skill_point, 0) AS sp_cost,
|
||||
d.unique_skill_id_1,
|
||||
COALESCE(u.owner_id, iu.owner_id, 0) AS unique_owner_id,
|
||||
COALESCE(u.name, iu.name, '') AS unique_owner,
|
||||
d.icon_id,
|
||||
ROW_NUMBER() OVER (ORDER BY d.id) - 1 AS "index"
|
||||
|
||||
Reference in New Issue
Block a user