Compare commits

12 Commits

19 changed files with 164717 additions and 1227 deletions

View File

@@ -84,7 +84,8 @@ func main() {
r.Route("/skill", func(r handler.Router) { r.Route("/skill", func(r handler.Router) {
r.SlashCommand("/", skillSrv.slash) r.SlashCommand("/", skillSrv.slash)
r.Autocomplete("/", skillSrv.autocomplete) r.Autocomplete("/", skillSrv.autocomplete)
r.ButtonComponent("/{id}", skillSrv.button) r.SelectMenuComponent("/swap", skillSrv.menu)
r.ButtonComponent("/swap/{id}", skillSrv.button)
}) })
opts := []bot.ConfigOpt{bot.WithDefaultGateway(), bot.WithEventListeners(r)} opts := []bot.ConfigOpt{bot.WithDefaultGateway(), bot.WithEventListeners(r)}
@@ -143,6 +144,10 @@ var commands = []discord.ApplicationCommandCreate{
Required: true, Required: true,
Autocomplete: true, Autocomplete: true,
}, },
discord.ApplicationCommandOptionBool{
Name: "share",
Description: "Share the skill info",
},
}, },
}, },
} }

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"log/slog"
"strconv" "strconv"
"strings" "strings"
@@ -28,15 +29,17 @@ func newSkillServer(skills []horse.Skill, groups []horse.SkillGroup) *skillServe
for _, skill := range skills { for _, skill := range skills {
s.skills[skill.ID] = skill s.skills[skill.ID] = skill
s.byName[skill.Name] = skill.ID s.byName[skill.Name] = skill.ID
switch {
case skill.UniqueOwner == "":
s.autocom.Add(skill.Name, discord.AutocompleteChoiceString{Name: skill.Name, Value: strconv.Itoa(int(skill.ID))})
case skill.Rarity >= 3:
s.autocom.Add(skill.Name, discord.AutocompleteChoiceString{Name: skill.Name, Value: skill.Name}) s.autocom.Add(skill.Name, discord.AutocompleteChoiceString{Name: skill.Name, Value: skill.Name})
if skill.UniqueOwner != "" { s.autocom.Add(skill.UniqueOwner, discord.AutocompleteChoiceString{Name: "Unique: " + skill.UniqueOwner, Value: strconv.Itoa(int(skill.ID))})
if skill.Rarity >= 3 { default:
s.autocom.Add(skill.UniqueOwner, discord.AutocompleteChoiceString{Name: "Unique: " + skill.UniqueOwner, Value: skill.Name}) s.autocom.Add(skill.Name, discord.AutocompleteChoiceString{Name: skill.Name + " (Inherited)", Value: strconv.Itoa(int(skill.ID))})
} else {
s.autocom.Add(skill.UniqueOwner, discord.AutocompleteChoiceString{Name: "Inherited unique: " + skill.UniqueOwner, Value: skill.Name}) s.autocom.Add(skill.UniqueOwner, discord.AutocompleteChoiceString{Name: "Inherited unique: " + skill.UniqueOwner, Value: skill.Name})
} }
} }
}
for _, g := range groups { for _, g := range groups {
s.groups[g.ID] = g s.groups[g.ID] = g
} }
@@ -67,6 +70,9 @@ func (s *skillServer) slash(data discord.SlashCommandInteractionData, e *handler
Components: []discord.LayoutComponent{s.render(horse.SkillID(id))}, Components: []discord.LayoutComponent{s.render(horse.SkillID(id))},
Flags: discord.MessageFlagIsComponentsV2, Flags: discord.MessageFlagIsComponentsV2,
} }
if !data.Bool("share") {
m.Flags |= discord.MessageFlagEphemeral
}
return e.CreateMessage(m) return e.CreateMessage(m)
} }
@@ -91,22 +97,38 @@ func (s *skillServer) button(data discord.ButtonInteractionData, e *handler.Comp
return e.UpdateMessage(m) return e.UpdateMessage(m)
} }
func (s *skillServer) menu(data discord.SelectMenuInteractionData, e *handler.ComponentEvent) error {
d, ok := data.(discord.StringSelectMenuInteractionData)
if !ok {
return fmt.Errorf("wrong select menu type %T", data)
}
if len(d.Values) != 1 {
return fmt.Errorf("wrong number of values: %q", d.Values)
}
id, err := strconv.ParseInt(d.Values[0], 10, 32)
if err != nil {
return err
}
m := discord.MessageUpdate{
Components: &[]discord.LayoutComponent{s.render(horse.SkillID(id))},
}
return e.UpdateMessage(m)
}
func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent { func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent {
skill, ok := s.skills[id] skill, ok := s.skills[id]
if !ok { if !ok {
return discord.NewContainer(discord.NewTextDisplayf("invalid skill ID %v made it to RenderSkill", id)) slog.Error("invalid skill id", slog.Int("id", int(id)))
return discord.NewContainer(discord.NewTextDisplayf("invalid skill ID %v made it to render", id))
} }
thumburl := fmt.Sprintf("https://gametora.com/images/umamusume/skill_icons/utx_ico_skill_%d.png", skill.IconID) top := "### " + skill.Name
top := "## " + skill.Name
if skill.UniqueOwner != "" { if skill.UniqueOwner != "" {
top += "\n-# " + skill.UniqueOwner top += "\n-# " + skill.UniqueOwner
} }
r := discord.NewContainer( r := discord.NewContainer(
discord.NewSection(
discord.NewTextDisplay(top), discord.NewTextDisplay(top),
discord.NewTextDisplay(skill.Description), discord.NewSmallSeparator(),
).WithAccessory(discord.NewThumbnail(thumburl)),
) )
var skilltype string var skilltype string
switch { switch {
@@ -138,7 +160,6 @@ func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent {
r.AccentColor = 0xcccccc r.AccentColor = 0xcccccc
skilltype = "Common Skill" skilltype = "Common Skill"
} }
r.Components = append(r.Components, discord.NewSmallSeparator())
text := make([]string, 0, 3) text := make([]string, 0, 3)
abils := make([]string, 0, 3) abils := make([]string, 0, 3)
for _, act := range skill.Activations { for _, act := range skill.Activations {
@@ -181,15 +202,30 @@ func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent {
} }
} }
if len(rel) > 1 { if len(rel) > 1 {
buttons := make([]discord.InteractiveComponent, 0, 4) opts := make([]discord.StringSelectMenuOption, 0, 4)
for _, rs := range rel { for _, rs := range rel {
b := discord.NewSecondaryButton(rs.Name, fmt.Sprintf("/skill/%d", rs.ID)) name := rs.Name
if rs.ID == id { emoji := "⚪"
b = b.AsDisabled() switch rs.Rarity {
case 1:
if rs.UniqueOwner != "" {
name += " (Inherited)"
} }
buttons = append(buttons, b) case 2:
emoji = "🟡"
case 3, 4, 5:
emoji = "🟣"
default:
emoji = "⁉️"
} }
r.Components = append(r.Components, discord.NewActionRow(buttons...)) b := discord.NewStringSelectMenuOption(name, strconv.Itoa(int(rs.ID))).WithEmoji(discord.NewComponentEmoji(emoji))
if rs.ID == skill.ID {
b = b.WithDefault(true)
}
opts = append(opts, b)
}
row := discord.NewActionRow(discord.NewStringSelectMenu("/skill/swap", "Related skills", opts...))
r.Components = append(r.Components, row)
} }
return r return r
} }

View File

@@ -223,6 +223,18 @@ func main() {
Value2: s.ColumnInt32(4), Value2: s.ColumnInt32(4),
} }
}) })
convos := load(ctx1, loadgroup, db, "lobby conversations", conversationSQL, func(s *sqlite.Stmt) horse.Conversation {
return horse.Conversation{
CharacterID: horse.CharacterID(s.ColumnInt(0)),
Number: s.ColumnInt(1),
Location: horse.LobbyConversationLocationID(s.ColumnInt(2)),
LocationName: horse.LobbyConversationLocationID(s.ColumnInt(2)).String(),
Chara1: horse.CharacterID(s.ColumnInt(3)),
Chara2: horse.CharacterID(s.ColumnInt(4)),
Chara3: horse.CharacterID(s.ColumnInt(5)),
ConditionType: s.ColumnInt(6),
}
})
if err := os.MkdirAll(filepath.Join(out, region), 0775); err != nil { if err := os.MkdirAll(filepath.Join(out, region), 0775); err != nil {
slog.Error("create output dir", slog.Any("err", err)) slog.Error("create output dir", slog.Any("err", err))
@@ -239,6 +251,7 @@ func main() {
writegroup.Go(func() error { return write(ctx2, out, region, "saddle.json", saddles) }) writegroup.Go(func() error { return write(ctx2, out, region, "saddle.json", saddles) })
writegroup.Go(func() error { return write(ctx2, out, region, "scenario.json", scenarios) }) writegroup.Go(func() error { return write(ctx2, out, region, "scenario.json", scenarios) })
writegroup.Go(func() error { return write(ctx2, out, region, "spark.json", mergesparks(sparks, sparkeffs)) }) writegroup.Go(func() error { return write(ctx2, out, region, "spark.json", mergesparks(sparks, sparkeffs)) })
writegroup.Go(func() error { return write(ctx2, out, region, "conversation.json", convos) })
if err := writegroup.Wait(); err != nil { if err := writegroup.Wait(); err != nil {
slog.ErrorContext(ctx, "write", slog.Any("err", err)) slog.ErrorContext(ctx, "write", slog.Any("err", err))
os.Exit(1) os.Exit(1)
@@ -268,6 +281,8 @@ var (
sparkSQL string sparkSQL string
//go:embed sql/spark-effect.sql //go:embed sql/spark-effect.sql
sparkEffectSQL string sparkEffectSQL string
//go:embed sql/conversation.sql
conversationSQL string
) )
func load[T any](ctx context.Context, group *errgroup.Group, db *sqlitex.Pool, kind, sql string, row func(*sqlite.Stmt) T) func() ([]T, error) { func load[T any](ctx context.Context, group *errgroup.Group, db *sqlitex.Pool, kind, sql string, row func(*sqlite.Stmt) T) func() ([]T, error) {

View File

@@ -0,0 +1,10 @@
SELECT
gallery_chara_id,
disp_order,
pos_id,
chara_id_1,
chara_id_2,
chara_id_3,
condition_type
FROM home_story_trigger
ORDER BY gallery_chara_id, disp_order

View File

@@ -3,8 +3,8 @@ WITH skill_groups AS (
) )
SELECT SELECT
g.group_id, g.group_id,
IFNULL(s1.id, 0) AS skill1, COALESCE(inh_from.id, s1.id, 0) AS skill1,
IFNULL(s2.id, 0) AS skill2, COALESCE(inh_to.id, s2.id, 0) AS skill2,
IFNULL(s3.id, 0) AS skill3, IFNULL(s3.id, 0) AS skill3,
IFNULL(m1.id, 0) AS skill_bad IFNULL(m1.id, 0) AS skill_bad
FROM skill_groups g FROM skill_groups g
@@ -12,4 +12,6 @@ FROM skill_groups g
LEFT JOIN skill_data s2 ON g.group_id = s2.group_id AND s2.group_rate = 2 LEFT JOIN skill_data s2 ON g.group_id = s2.group_id AND s2.group_rate = 2
LEFT JOIN skill_data s3 ON g.group_id = s3.group_id AND s3.group_rate = 3 LEFT JOIN skill_data s3 ON g.group_id = s3.group_id AND s3.group_rate = 3
LEFT JOIN skill_data m1 ON g.group_id = m1.group_id AND m1.group_rate = -1 LEFT JOIN skill_data m1 ON g.group_id = m1.group_id AND m1.group_rate = -1
LEFT JOIN skill_data inh_to ON s1.id = inh_to.unique_skill_id_1
LEFT JOIN skill_data inh_from ON s2.unique_skill_id_1 = inh_from.id
ORDER BY g.group_id ORDER BY g.group_id

137122
doc/2026-03-12-global.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ This file is my notes from exploring the database.
- 33 is race names by race id, 28 is race names by race instance id, 31 is race courses, 111 is saddle names - 33 is race names by race id, 28 is race names by race instance id, 31 is race courses, 111 is saddle names
- 65 is player titles, 66 is title descriptions - ties with honor_data? - 65 is player titles, 66 is title descriptions - ties with honor_data?
- 119 is scenario full titles (e.g. The Beginning: URA Finale), 120 is scenario descriptions, 237 is scenario names (e.g. URA Finale) - 119 is scenario full titles (e.g. The Beginning: URA Finale), 120 is scenario descriptions, 237 is scenario names (e.g. URA Finale)
- 130 is epithet names, 131 is epithet descriptions
# succession factor (sparks) # succession factor (sparks)
@@ -192,12 +193,41 @@ target types:
- 22 specific character, target value is character id - 22 specific character, target value is character id
- 23 other who triggered the skill - 23 other who triggered the skill
TODO target types only in jp: 2, 7, 11, 22, 23
ability_value_usage can be 1 for plain or 2-6 for aoharu stat skill stat scaling ability_value_usage can be 1 for plain or 2-6 for aoharu stat skill stat scaling
seems to be activate_lot = 1 means wit check, 0 means guaranteed seems to be activate_lot = 1 means wit check, 0 means guaranteed
tag_id is a slash-separated list of numeric IDs that roughly describe all effects relevant to the skill.
- 101..104 style front, pace, late, end
- 201..204 distance sprint, mile, medium, long
- 301..303 timing early, mid, late race
- 401 affects speed stat or target speed
- 402 affects stamina stat or hp
- 403 affects power stat or acceleration
- 404 affects guts stat
- 405 affects wit stat or vision
- 406 is a debuff of any type, or is a main story self-debuff (creeping anxiety, blatant fear), or is Behold Thine Emperor's Divine Might (both own unique and inherited versions are tagged only 406??)
- 407 modifies gate delay
- 501..502 turf/dirt
- 801..812 scenario skill
600 series applies to skills available in global but are only used in jp.
- 601 ground condition passive
- 602 weather passive
- 603 season passive
- 604 race track passive
- 605 time of day passive
- 606 exchange race passive (kawasaki, funabashi, morioka, ooi)
- 607 distance passive (non/standard)
- 608 track direction or corner count passive
- 609 gate position passive
- 610 ground type passive
- 611 popularity passive
- 612 running style passive
- 613 passive depending on other horses' styles or skills
- 614 base stat threshold passive
- 615 mood passive
# races # races
- group 1, grade: g1 100, g2 200, g3 300, op 400, pre-op 700 - group 1, grade: g1 100, g2 200, g3 300, op 400, pre-op 700

File diff suppressed because it is too large Load Diff

View File

@@ -199,6 +199,14 @@
"chara_id": 1061, "chara_id": 1061,
"name": "King Halo" "name": "King Halo"
}, },
{
"chara_id": 1062,
"name": "Matikanetannhauser"
},
{
"chara_id": 1067,
"name": "Satono Diamond"
},
{ {
"chara_id": 1068, "chara_id": 1068,
"name": "Kitasan Black" "name": "Kitasan Black"

2326
global/conversation.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -8,5 +8,10 @@
"scenario_id": 2, "scenario_id": 2,
"name": "Unity Cup", "name": "Unity Cup",
"title": "Unity Cup: Shine On, Team Spirit!" "title": "Unity Cup: Shine On, Team Spirit!"
},
{
"scenario_id": 4,
"name": "TS Climax",
"title": "Trackblazer: Start of the Climax"
} }
] ]

View File

@@ -63,282 +63,370 @@
"skill_group": 1061, "skill_group": 1061,
"skill1": 10611 "skill1": 10611
}, },
{
"skill_group": 1062,
"skill1": 10621
},
{ {
"skill_group": 10001, "skill_group": 10001,
"skill1": 100011 "skill1": 100011,
"skill2": 900011
}, },
{ {
"skill_group": 10002, "skill_group": 10002,
"skill1": 100021 "skill1": 100021,
"skill2": 900021
}, },
{ {
"skill_group": 10003, "skill_group": 10003,
"skill1": 100031 "skill1": 100031,
"skill2": 900031
}, },
{ {
"skill_group": 10004, "skill_group": 10004,
"skill1": 100041 "skill1": 100041,
"skill2": 900041
}, },
{ {
"skill_group": 10005, "skill_group": 10005,
"skill1": 100051 "skill1": 100051,
"skill2": 900051
}, },
{ {
"skill_group": 10006, "skill_group": 10006,
"skill1": 100061 "skill1": 100061,
"skill2": 900061
}, },
{ {
"skill_group": 10007, "skill_group": 10007,
"skill1": 100071 "skill1": 100071,
"skill2": 900071
}, },
{ {
"skill_group": 10008, "skill_group": 10008,
"skill1": 100081 "skill1": 100081,
"skill2": 900081
}, },
{ {
"skill_group": 10009, "skill_group": 10009,
"skill1": 100091 "skill1": 100091,
"skill2": 900091
}, },
{ {
"skill_group": 10010, "skill_group": 10010,
"skill1": 100101 "skill1": 100101,
"skill2": 900101
}, },
{ {
"skill_group": 10011, "skill_group": 10011,
"skill1": 100111 "skill1": 100111,
"skill2": 900111
}, },
{ {
"skill_group": 10012, "skill_group": 10012,
"skill1": 100121 "skill1": 100121,
"skill2": 900121
}, },
{ {
"skill_group": 10013, "skill_group": 10013,
"skill1": 100131 "skill1": 100131,
"skill2": 900131
}, },
{ {
"skill_group": 10014, "skill_group": 10014,
"skill1": 100141 "skill1": 100141,
"skill2": 900141
}, },
{ {
"skill_group": 10015, "skill_group": 10015,
"skill1": 100151 "skill1": 100151,
"skill2": 900151
}, },
{ {
"skill_group": 10016, "skill_group": 10016,
"skill1": 100161 "skill1": 100161,
"skill2": 900161
}, },
{ {
"skill_group": 10017, "skill_group": 10017,
"skill1": 100171 "skill1": 100171,
"skill2": 900171
}, },
{ {
"skill_group": 10018, "skill_group": 10018,
"skill1": 100181 "skill1": 100181,
"skill2": 900181
}, },
{ {
"skill_group": 10019, "skill_group": 10019,
"skill1": 100191 "skill1": 100191,
"skill2": 900191
}, },
{ {
"skill_group": 10020, "skill_group": 10020,
"skill1": 100201 "skill1": 100201,
"skill2": 900201
}, },
{ {
"skill_group": 10021, "skill_group": 10021,
"skill1": 100211 "skill1": 100211,
"skill2": 900211
}, },
{ {
"skill_group": 10022, "skill_group": 10022,
"skill1": 100221 "skill1": 100221,
"skill2": 900221
}, },
{ {
"skill_group": 10023, "skill_group": 10023,
"skill1": 100231 "skill1": 100231,
"skill2": 900231
}, },
{ {
"skill_group": 10024, "skill_group": 10024,
"skill1": 100241 "skill1": 100241,
"skill2": 900241
}, },
{ {
"skill_group": 10025, "skill_group": 10025,
"skill1": 100251 "skill1": 100251,
"skill2": 900251
}, },
{ {
"skill_group": 10026, "skill_group": 10026,
"skill1": 100261 "skill1": 100261,
"skill2": 900261
}, },
{ {
"skill_group": 10027, "skill_group": 10027,
"skill1": 100271 "skill1": 100271,
"skill2": 900271
}, },
{ {
"skill_group": 10028, "skill_group": 10028,
"skill1": 100281 "skill1": 100281,
"skill2": 900281
}, },
{ {
"skill_group": 10030, "skill_group": 10030,
"skill1": 100301 "skill1": 100301,
"skill2": 900301
}, },
{ {
"skill_group": 10032, "skill_group": 10032,
"skill1": 100321 "skill1": 100321,
"skill2": 900321
}, },
{ {
"skill_group": 10033, "skill_group": 10033,
"skill1": 100331 "skill1": 100331,
"skill2": 900331
}, },
{ {
"skill_group": 10035, "skill_group": 10035,
"skill1": 100351 "skill1": 100351,
"skill2": 900351
}, },
{ {
"skill_group": 10037, "skill_group": 10037,
"skill1": 100371 "skill1": 100371,
"skill2": 900371
}, },
{ {
"skill_group": 10038, "skill_group": 10038,
"skill1": 100381 "skill1": 100381,
"skill2": 900381
}, },
{ {
"skill_group": 10039, "skill_group": 10039,
"skill1": 100391 "skill1": 100391,
"skill2": 900391
}, },
{ {
"skill_group": 10040, "skill_group": 10040,
"skill1": 100401 "skill1": 100401,
"skill2": 900401
}, },
{ {
"skill_group": 10041, "skill_group": 10041,
"skill1": 100411 "skill1": 100411,
"skill2": 900411
}, },
{ {
"skill_group": 10045, "skill_group": 10045,
"skill1": 100451 "skill1": 100451,
"skill2": 900451
}, },
{ {
"skill_group": 10046, "skill_group": 10046,
"skill1": 100461 "skill1": 100461,
"skill2": 900461
}, },
{ {
"skill_group": 10048, "skill_group": 10048,
"skill1": 100481 "skill1": 100481,
"skill2": 900481
}, },
{ {
"skill_group": 10050, "skill_group": 10050,
"skill1": 100501 "skill1": 100501,
"skill2": 900501
}, },
{ {
"skill_group": 10052, "skill_group": 10052,
"skill1": 100521 "skill1": 100521,
"skill2": 900521
}, },
{ {
"skill_group": 10056, "skill_group": 10056,
"skill1": 100561 "skill1": 100561,
"skill2": 900561
}, },
{ {
"skill_group": 10058, "skill_group": 10058,
"skill1": 100581 "skill1": 100581,
"skill2": 900581
}, },
{ {
"skill_group": 10059, "skill_group": 10059,
"skill1": 100591 "skill1": 100591,
"skill2": 900591
}, },
{ {
"skill_group": 10060, "skill_group": 10060,
"skill1": 100601 "skill1": 100601,
"skill2": 900601
}, },
{ {
"skill_group": 10061, "skill_group": 10061,
"skill1": 100611 "skill1": 100611,
"skill2": 900611
},
{
"skill_group": 10062,
"skill1": 100621,
"skill2": 900621
},
{
"skill_group": 10067,
"skill1": 100671,
"skill2": 900671
},
{
"skill_group": 10068,
"skill1": 100681,
"skill2": 900681
}, },
{ {
"skill_group": 10069, "skill_group": 10069,
"skill1": 100691 "skill1": 100691,
"skill2": 900691
}, },
{ {
"skill_group": 10071, "skill_group": 10071,
"skill1": 100711 "skill1": 100711,
"skill2": 900711
}, },
{ {
"skill_group": 11001, "skill_group": 11001,
"skill1": 110011 "skill1": 110011,
"skill2": 910011
}, },
{ {
"skill_group": 11003, "skill_group": 11003,
"skill1": 110031 "skill1": 110031,
"skill2": 910031
}, },
{ {
"skill_group": 11004, "skill_group": 11004,
"skill1": 110041 "skill1": 110041,
"skill2": 910041
}, },
{ {
"skill_group": 11006, "skill_group": 11006,
"skill1": 110061 "skill1": 110061,
"skill2": 910061
}, },
{ {
"skill_group": 11011, "skill_group": 11011,
"skill1": 110111 "skill1": 110111,
"skill2": 910111
}, },
{ {
"skill_group": 11013, "skill_group": 11013,
"skill1": 110131 "skill1": 110131,
"skill2": 910131
}, },
{ {
"skill_group": 11014, "skill_group": 11014,
"skill1": 110141 "skill1": 110141,
"skill2": 910141
}, },
{ {
"skill_group": 11015, "skill_group": 11015,
"skill1": 110151 "skill1": 110151,
"skill2": 910151
}, },
{ {
"skill_group": 11017, "skill_group": 11017,
"skill1": 110171 "skill1": 110171,
"skill2": 910171
}, },
{ {
"skill_group": 11018, "skill_group": 11018,
"skill1": 110181 "skill1": 110181,
"skill2": 910181
}, },
{ {
"skill_group": 11023, "skill_group": 11023,
"skill1": 110231 "skill1": 110231,
"skill2": 910231
}, },
{ {
"skill_group": 11024, "skill_group": 11024,
"skill1": 110241 "skill1": 110241,
"skill2": 910241
}, },
{ {
"skill_group": 11026, "skill_group": 11026,
"skill1": 110261 "skill1": 110261,
"skill2": 910261
}, },
{ {
"skill_group": 11030, "skill_group": 11030,
"skill1": 110301 "skill1": 110301,
"skill2": 910301
}, },
{ {
"skill_group": 11037, "skill_group": 11037,
"skill1": 110371 "skill1": 110371,
"skill2": 910371
}, },
{ {
"skill_group": 11040, "skill_group": 11040,
"skill1": 110401 "skill1": 110401,
"skill2": 910401
}, },
{ {
"skill_group": 11045, "skill_group": 11045,
"skill1": 110451 "skill1": 110451,
"skill2": 910451
}, },
{ {
"skill_group": 11052, "skill_group": 11052,
"skill1": 110521 "skill1": 110521,
"skill2": 910521
}, },
{ {
"skill_group": 11056, "skill_group": 11056,
"skill1": 110561 "skill1": 110561,
"skill2": 910561
}, },
{ {
"skill_group": 20001, "skill_group": 20001,
"skill1": 200012, "skill1": 200012,
"skill2": 200011, "skill2": 200011,
"skill3": 200014,
"skill_bad": 200013 "skill_bad": 200013
}, },
{ {
@@ -424,6 +512,7 @@
"skill_group": 20015, "skill_group": 20015,
"skill1": 200152, "skill1": 200152,
"skill2": 200151, "skill2": 200151,
"skill3": 200154,
"skill_bad": 200153 "skill_bad": 200153
}, },
{ {
@@ -926,7 +1015,8 @@
{ {
"skill_group": 20117, "skill_group": 20117,
"skill1": 201172, "skill1": 201172,
"skill2": 201171 "skill2": 201171,
"skill3": 201173
}, },
{ {
"skill_group": 20118, "skill_group": 20118,
@@ -1244,6 +1334,11 @@
"skill1": 210052, "skill1": 210052,
"skill2": 210051 "skill2": 210051
}, },
{
"skill_group": 21006,
"skill1": 210062,
"skill2": 210061
},
{ {
"skill_group": 30001, "skill_group": 30001,
"skill1": 300011 "skill1": 300011
@@ -1286,274 +1381,357 @@
}, },
{ {
"skill_group": 90001, "skill_group": 90001,
"skill1": 100011,
"skill2": 900011 "skill2": 900011
}, },
{ {
"skill_group": 90002, "skill_group": 90002,
"skill1": 100021,
"skill2": 900021 "skill2": 900021
}, },
{ {
"skill_group": 90003, "skill_group": 90003,
"skill1": 100031,
"skill2": 900031 "skill2": 900031
}, },
{ {
"skill_group": 90004, "skill_group": 90004,
"skill1": 100041,
"skill2": 900041 "skill2": 900041
}, },
{ {
"skill_group": 90005, "skill_group": 90005,
"skill1": 100051,
"skill2": 900051 "skill2": 900051
}, },
{ {
"skill_group": 90006, "skill_group": 90006,
"skill1": 100061,
"skill2": 900061 "skill2": 900061
}, },
{ {
"skill_group": 90007, "skill_group": 90007,
"skill1": 100071,
"skill2": 900071 "skill2": 900071
}, },
{ {
"skill_group": 90008, "skill_group": 90008,
"skill1": 100081,
"skill2": 900081 "skill2": 900081
}, },
{ {
"skill_group": 90009, "skill_group": 90009,
"skill1": 100091,
"skill2": 900091 "skill2": 900091
}, },
{ {
"skill_group": 90010, "skill_group": 90010,
"skill1": 100101,
"skill2": 900101 "skill2": 900101
}, },
{ {
"skill_group": 90011, "skill_group": 90011,
"skill1": 100111,
"skill2": 900111 "skill2": 900111
}, },
{ {
"skill_group": 90012, "skill_group": 90012,
"skill1": 100121,
"skill2": 900121 "skill2": 900121
}, },
{ {
"skill_group": 90013, "skill_group": 90013,
"skill1": 100131,
"skill2": 900131 "skill2": 900131
}, },
{ {
"skill_group": 90014, "skill_group": 90014,
"skill1": 100141,
"skill2": 900141 "skill2": 900141
}, },
{ {
"skill_group": 90015, "skill_group": 90015,
"skill1": 100151,
"skill2": 900151 "skill2": 900151
}, },
{ {
"skill_group": 90016, "skill_group": 90016,
"skill1": 100161,
"skill2": 900161 "skill2": 900161
}, },
{ {
"skill_group": 90017, "skill_group": 90017,
"skill1": 100171,
"skill2": 900171 "skill2": 900171
}, },
{ {
"skill_group": 90018, "skill_group": 90018,
"skill1": 100181,
"skill2": 900181 "skill2": 900181
}, },
{ {
"skill_group": 90019, "skill_group": 90019,
"skill1": 100191,
"skill2": 900191 "skill2": 900191
}, },
{ {
"skill_group": 90020, "skill_group": 90020,
"skill1": 100201,
"skill2": 900201 "skill2": 900201
}, },
{ {
"skill_group": 90021, "skill_group": 90021,
"skill1": 100211,
"skill2": 900211 "skill2": 900211
}, },
{ {
"skill_group": 90022, "skill_group": 90022,
"skill1": 100221,
"skill2": 900221 "skill2": 900221
}, },
{ {
"skill_group": 90023, "skill_group": 90023,
"skill1": 100231,
"skill2": 900231 "skill2": 900231
}, },
{ {
"skill_group": 90024, "skill_group": 90024,
"skill1": 100241,
"skill2": 900241 "skill2": 900241
}, },
{ {
"skill_group": 90025, "skill_group": 90025,
"skill1": 100251,
"skill2": 900251 "skill2": 900251
}, },
{ {
"skill_group": 90026, "skill_group": 90026,
"skill1": 100261,
"skill2": 900261 "skill2": 900261
}, },
{ {
"skill_group": 90027, "skill_group": 90027,
"skill1": 100271,
"skill2": 900271 "skill2": 900271
}, },
{ {
"skill_group": 90028, "skill_group": 90028,
"skill1": 100281,
"skill2": 900281 "skill2": 900281
}, },
{ {
"skill_group": 90030, "skill_group": 90030,
"skill1": 100301,
"skill2": 900301 "skill2": 900301
}, },
{ {
"skill_group": 90032, "skill_group": 90032,
"skill1": 100321,
"skill2": 900321 "skill2": 900321
}, },
{ {
"skill_group": 90033, "skill_group": 90033,
"skill1": 100331,
"skill2": 900331 "skill2": 900331
}, },
{ {
"skill_group": 90035, "skill_group": 90035,
"skill1": 100351,
"skill2": 900351 "skill2": 900351
}, },
{ {
"skill_group": 90037, "skill_group": 90037,
"skill1": 100371,
"skill2": 900371 "skill2": 900371
}, },
{ {
"skill_group": 90038, "skill_group": 90038,
"skill1": 100381,
"skill2": 900381 "skill2": 900381
}, },
{ {
"skill_group": 90039, "skill_group": 90039,
"skill1": 100391,
"skill2": 900391 "skill2": 900391
}, },
{ {
"skill_group": 90040, "skill_group": 90040,
"skill1": 100401,
"skill2": 900401 "skill2": 900401
}, },
{ {
"skill_group": 90041, "skill_group": 90041,
"skill1": 100411,
"skill2": 900411 "skill2": 900411
}, },
{ {
"skill_group": 90045, "skill_group": 90045,
"skill1": 100451,
"skill2": 900451 "skill2": 900451
}, },
{ {
"skill_group": 90046, "skill_group": 90046,
"skill1": 100461,
"skill2": 900461 "skill2": 900461
}, },
{ {
"skill_group": 90048, "skill_group": 90048,
"skill1": 100481,
"skill2": 900481 "skill2": 900481
}, },
{ {
"skill_group": 90050, "skill_group": 90050,
"skill1": 100501,
"skill2": 900501 "skill2": 900501
}, },
{ {
"skill_group": 90052, "skill_group": 90052,
"skill1": 100521,
"skill2": 900521 "skill2": 900521
}, },
{ {
"skill_group": 90056, "skill_group": 90056,
"skill1": 100561,
"skill2": 900561 "skill2": 900561
}, },
{ {
"skill_group": 90058, "skill_group": 90058,
"skill1": 100581,
"skill2": 900581 "skill2": 900581
}, },
{ {
"skill_group": 90059, "skill_group": 90059,
"skill1": 100591,
"skill2": 900591 "skill2": 900591
}, },
{ {
"skill_group": 90060, "skill_group": 90060,
"skill1": 100601,
"skill2": 900601 "skill2": 900601
}, },
{ {
"skill_group": 90061, "skill_group": 90061,
"skill1": 100611,
"skill2": 900611 "skill2": 900611
}, },
{
"skill_group": 90062,
"skill1": 100621,
"skill2": 900621
},
{
"skill_group": 90067,
"skill1": 100671,
"skill2": 900671
},
{
"skill_group": 90068,
"skill1": 100681,
"skill2": 900681
},
{ {
"skill_group": 90069, "skill_group": 90069,
"skill1": 100691,
"skill2": 900691 "skill2": 900691
}, },
{ {
"skill_group": 90071, "skill_group": 90071,
"skill1": 100711,
"skill2": 900711 "skill2": 900711
}, },
{ {
"skill_group": 91001, "skill_group": 91001,
"skill1": 110011,
"skill2": 910011 "skill2": 910011
}, },
{ {
"skill_group": 91003, "skill_group": 91003,
"skill1": 110031,
"skill2": 910031 "skill2": 910031
}, },
{ {
"skill_group": 91004, "skill_group": 91004,
"skill1": 110041,
"skill2": 910041 "skill2": 910041
}, },
{ {
"skill_group": 91006, "skill_group": 91006,
"skill1": 110061,
"skill2": 910061 "skill2": 910061
}, },
{ {
"skill_group": 91011, "skill_group": 91011,
"skill1": 110111,
"skill2": 910111 "skill2": 910111
}, },
{ {
"skill_group": 91013, "skill_group": 91013,
"skill1": 110131,
"skill2": 910131 "skill2": 910131
}, },
{ {
"skill_group": 91014, "skill_group": 91014,
"skill1": 110141,
"skill2": 910141 "skill2": 910141
}, },
{ {
"skill_group": 91015, "skill_group": 91015,
"skill1": 110151,
"skill2": 910151 "skill2": 910151
}, },
{ {
"skill_group": 91017, "skill_group": 91017,
"skill1": 110171,
"skill2": 910171 "skill2": 910171
}, },
{ {
"skill_group": 91018, "skill_group": 91018,
"skill1": 110181,
"skill2": 910181 "skill2": 910181
}, },
{ {
"skill_group": 91023, "skill_group": 91023,
"skill1": 110231,
"skill2": 910231 "skill2": 910231
}, },
{ {
"skill_group": 91024, "skill_group": 91024,
"skill1": 110241,
"skill2": 910241 "skill2": 910241
}, },
{ {
"skill_group": 91026, "skill_group": 91026,
"skill1": 110261,
"skill2": 910261 "skill2": 910261
}, },
{ {
"skill_group": 91030, "skill_group": 91030,
"skill1": 110301,
"skill2": 910301 "skill2": 910301
}, },
{ {
"skill_group": 91037, "skill_group": 91037,
"skill1": 110371,
"skill2": 910371 "skill2": 910371
}, },
{ {
"skill_group": 91040, "skill_group": 91040,
"skill1": 110401,
"skill2": 910401 "skill2": 910401
}, },
{ {
"skill_group": 91045, "skill_group": 91045,
"skill1": 110451,
"skill2": 910451 "skill2": 910451
}, },
{ {
"skill_group": 91052, "skill_group": 91052,
"skill1": 110521,
"skill2": 910521 "skill2": 910521
}, },
{ {
"skill_group": 91056, "skill_group": 91056,
"skill1": 110561,
"skill2": 910561 "skill2": 910561
}, },
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -28997,6 +28997,141 @@
] ]
] ]
}, },
{
"spark_id": 2100601,
"name": "Glittering Star",
"description": "A Spark that gives a skill hint for \"Glittering Star\".",
"spark_group": 21006,
"rarity": 1,
"type": 4,
"effects": [
[
{
"target": 41,
"value1": 210062,
"value2": 1
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 2
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 3
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 4
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 5
}
]
]
},
{
"spark_id": 2100602,
"name": "Glittering Star",
"description": "A Spark that gives a skill hint for \"Glittering Star\".",
"spark_group": 21006,
"rarity": 2,
"type": 4,
"effects": [
[
{
"target": 41,
"value1": 210062,
"value2": 1
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 2
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 3
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 4
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 5
}
]
]
},
{
"spark_id": 2100603,
"name": "Glittering Star",
"description": "A Spark that gives a skill hint for \"Glittering Star\".",
"spark_group": 21006,
"rarity": 3,
"type": 4,
"effects": [
[
{
"target": 41,
"value1": 210062,
"value2": 1
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 2
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 3
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 4
}
],
[
{
"target": 41,
"value1": 210062,
"value2": 5
}
]
]
},
{ {
"spark_id": 3000101, "spark_id": 3000101,
"name": "URA Finale", "name": "URA Finale",
@@ -29237,6 +29372,126 @@
] ]
] ]
}, },
{
"spark_id": 3000301,
"name": "TS Climax Scenario",
"description": "A Spark that increases Stamina and Guts.",
"spark_group": 30003,
"rarity": 1,
"type": 6,
"effects": [
[
{
"target": 2,
"value1": 10
},
{
"target": 4,
"value1": 10
}
],
[
{
"target": 2,
"value1": 20
},
{
"target": 4,
"value1": 20
}
],
[
{
"target": 2,
"value1": 30
},
{
"target": 4,
"value1": 30
}
]
]
},
{
"spark_id": 3000302,
"name": "TS Climax Scenario",
"description": "A Spark that increases Stamina and Guts.",
"spark_group": 30003,
"rarity": 2,
"type": 6,
"effects": [
[
{
"target": 2,
"value1": 10
},
{
"target": 4,
"value1": 10
}
],
[
{
"target": 2,
"value1": 20
},
{
"target": 4,
"value1": 20
}
],
[
{
"target": 2,
"value1": 30
},
{
"target": 4,
"value1": 30
}
]
]
},
{
"spark_id": 3000303,
"name": "TS Climax Scenario",
"description": "A Spark that increases Stamina and Guts.",
"spark_group": 30003,
"rarity": 3,
"type": 6,
"effects": [
[
{
"target": 2,
"value1": 10
},
{
"target": 4,
"value1": 10
}
],
[
{
"target": 2,
"value1": 20
},
{
"target": 4,
"value1": 20
}
],
[
{
"target": 2,
"value1": 30
},
{
"target": 4,
"value1": 30
}
]
]
},
{ {
"spark_id": 10010101, "spark_id": 10010101,
"name": "Shooting Star", "name": "Shooting Star",
@@ -35375,6 +35630,285 @@
] ]
] ]
}, },
{
"spark_id": 10620101,
"name": "Go, Go, Mun!",
"description": "A Spark that gives a skill hint for \"Go, Go, Mun!\".",
"spark_group": 106201,
"rarity": 1,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900621,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 3
}
]
]
},
{
"spark_id": 10620102,
"name": "Go, Go, Mun!",
"description": "A Spark that gives a skill hint for \"Go, Go, Mun!\".",
"spark_group": 106201,
"rarity": 2,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900621,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 3
}
]
]
},
{
"spark_id": 10620103,
"name": "Go, Go, Mun!",
"description": "A Spark that gives a skill hint for \"Go, Go, Mun!\".",
"spark_group": 106201,
"rarity": 3,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900621,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900621,
"value2": 3
}
]
]
},
{
"spark_id": 10670101,
"name": "Eternal Encompassing Shine",
"description": "A Spark that gives a skill hint for \"Eternal Encompassing Shine\".",
"spark_group": 106701,
"rarity": 1,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900671,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 3
}
]
]
},
{
"spark_id": 10670102,
"name": "Eternal Encompassing Shine",
"description": "A Spark that gives a skill hint for \"Eternal Encompassing Shine\".",
"spark_group": 106701,
"rarity": 2,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900671,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 3
}
]
]
},
{
"spark_id": 10670103,
"name": "Eternal Encompassing Shine",
"description": "A Spark that gives a skill hint for \"Eternal Encompassing Shine\".",
"spark_group": 106701,
"rarity": 3,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900671,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900671,
"value2": 3
}
]
]
},
{
"spark_id": 10680101,
"name": "Victory Cheer!",
"description": "A Spark that gives a skill hint for \"Victory Cheer!\".",
"spark_group": 106801,
"rarity": 1,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900681,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 3
}
]
]
},
{
"spark_id": 10680102,
"name": "Victory Cheer!",
"description": "A Spark that gives a skill hint for \"Victory Cheer!\".",
"spark_group": 106801,
"rarity": 2,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900681,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 3
}
]
]
},
{
"spark_id": 10680103,
"name": "Victory Cheer!",
"description": "A Spark that gives a skill hint for \"Victory Cheer!\".",
"spark_group": 106801,
"rarity": 3,
"type": 3,
"effects": [
[
{
"target": 41,
"value1": 900681,
"value2": 1
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 2
}
],
[
{
"target": 41,
"value1": 900681,
"value2": 3
}
]
]
},
{ {
"spark_id": 10690101, "spark_id": 10690101,
"name": "Ambition to Surpass the Sakura", "name": "Ambition to Surpass the Sakura",

View File

@@ -1583,6 +1583,78 @@
"skill_pl4": 201072, "skill_pl4": 201072,
"skill_pl5": 201431 "skill_pl5": 201431
}, },
{
"chara_card_id": 106201,
"chara_id": 1062,
"name": "[Clippety-Tippety-Clop] Matikanetannhauser",
"variant": "[Clippety-Tippety-Clop]",
"sprint": 0,
"mile": 4,
"medium": 7,
"long": 7,
"front": 2,
"pace": 7,
"late": 7,
"end": 3,
"turf": 7,
"dirt": 1,
"unique": 100621,
"skill1": 200482,
"skill2": 201212,
"skill3": 200602,
"skill_pl2": 201621,
"skill_pl3": 200481,
"skill_pl4": 200512,
"skill_pl5": 201211
},
{
"chara_card_id": 106701,
"chara_id": 1067,
"name": "[Natural Brilliance] Satono Diamond",
"variant": "[Natural Brilliance]",
"sprint": 0,
"mile": 5,
"medium": 7,
"long": 7,
"front": 1,
"pace": 6,
"late": 7,
"end": 4,
"turf": 7,
"dirt": 1,
"unique": 100671,
"skill1": 200012,
"skill2": 201692,
"skill3": 201102,
"skill_pl2": 202012,
"skill_pl3": 201691,
"skill_pl4": 200152,
"skill_pl5": 200014
},
{
"chara_card_id": 106801,
"chara_id": 1068,
"name": "[Gilded Shrine to Glory] Kitasan Black",
"variant": "[Gilded Shrine to Glory]",
"sprint": 0,
"mile": 5,
"medium": 7,
"long": 7,
"front": 7,
"pace": 6,
"late": 5,
"end": 1,
"turf": 7,
"dirt": 1,
"unique": 100681,
"skill1": 200432,
"skill2": 201172,
"skill3": 200532,
"skill_pl2": 201102,
"skill_pl3": 200531,
"skill_pl4": 201272,
"skill_pl5": 201173
},
{ {
"chara_card_id": 106901, "chara_card_id": 106901,
"chara_id": 1069, "chara_id": 1069,

View File

@@ -17,3 +17,43 @@ type AffinityRelation struct {
IDC int `json:"chara_c,omitzero"` IDC int `json:"chara_c,omitzero"`
Affinity int `json:"affinity"` Affinity int `json:"affinity"`
} }
// Conversation describes a lobby conversation.
type Conversation struct {
// CharacterID is the ID of the character who has the conversation as
// a gallery entry.
CharacterID CharacterID `json:"chara_id"`
// Number is the conversation number within the character's gallery.
Number int `json:"number"`
// Location is the ID of the location the conversation occurs in the lobby.
Location LobbyConversationLocationID `json:"location"`
// LocationName is the name of the lobby location, for convenience.
LocationName string `json:"location_name"`
// Chara1 is the first conversation participant ID.
// It does not necessarily match CharacterID.
Chara1 CharacterID `json:"chara_1"`
// Chara2 is the second conversation participant ID.
Chara2 CharacterID `json:"chara_2,omitzero"`
// Chara3 is the third conversation participant ID.
Chara3 CharacterID `json:"chara_3,omitzero"`
// ConditionType is a complete mystery to me.
ConditionType int `json:"condition_type"`
}
type LobbyConversationLocationID int
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type LobbyConversationLocationID -trimprefix Lobby -linecomment
const (
LobbyRightFront1 LobbyConversationLocationID = 110 // right side front
LobbyRightFront2 LobbyConversationLocationID = 120 // right side front
LobbyRightFront3 LobbyConversationLocationID = 130 // right side front
LobbyLeftTable1 LobbyConversationLocationID = 210 // left side table
LobbyLeftTable2 LobbyConversationLocationID = 220 // left side table
LobbyBackSeat LobbyConversationLocationID = 310 // center back seat
LobbyPosters1 LobbyConversationLocationID = 410 // center posters
LobbyPosters2 LobbyConversationLocationID = 420 // center posters
LobbyPosters3 LobbyConversationLocationID = 430 // center posters
LobbySchoolMap1 LobbyConversationLocationID = 510 // left side school map
LobbySchoolMap2 LobbyConversationLocationID = 520 // left side school map
LobbySchoolMap3 LobbyConversationLocationID = 530 // left side school map
)

View File

@@ -0,0 +1,47 @@
// Code generated by "stringer -type LobbyConversationLocationID -trimprefix Lobby -linecomment"; DO NOT EDIT.
package horse
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[LobbyRightFront1-110]
_ = x[LobbyRightFront2-120]
_ = x[LobbyRightFront3-130]
_ = x[LobbyLeftTable1-210]
_ = x[LobbyLeftTable2-220]
_ = x[LobbyBackSeat-310]
_ = x[LobbyPosters1-410]
_ = x[LobbyPosters2-420]
_ = x[LobbyPosters3-430]
_ = x[LobbySchoolMap1-510]
_ = x[LobbySchoolMap2-520]
_ = x[LobbySchoolMap3-530]
}
const _LobbyConversationLocationID_name = "right side frontright side frontright side frontleft side tableleft side tablecenter back seatcenter posterscenter posterscenter postersleft side school mapleft side school mapleft side school map"
var _LobbyConversationLocationID_map = map[LobbyConversationLocationID]string{
110: _LobbyConversationLocationID_name[0:16],
120: _LobbyConversationLocationID_name[16:32],
130: _LobbyConversationLocationID_name[32:48],
210: _LobbyConversationLocationID_name[48:63],
220: _LobbyConversationLocationID_name[63:78],
310: _LobbyConversationLocationID_name[78:94],
410: _LobbyConversationLocationID_name[94:108],
420: _LobbyConversationLocationID_name[108:122],
430: _LobbyConversationLocationID_name[122:136],
510: _LobbyConversationLocationID_name[136:156],
520: _LobbyConversationLocationID_name[156:176],
530: _LobbyConversationLocationID_name[176:196],
}
func (i LobbyConversationLocationID) String() string {
if str, ok := _LobbyConversationLocationID_map[i]; ok {
return str
}
return "LobbyConversationLocationID(" + strconv.FormatInt(int64(i), 10) + ")"
}

View File

@@ -46,7 +46,7 @@ type Activation struct {
Precondition string `json:"precondition,omitzero"` Precondition string `json:"precondition,omitzero"`
Condition string `json:"condition"` Condition string `json:"condition"`
Duration TenThousandths `json:"duration,omitzero"` Duration TenThousandths `json:"duration,omitzero"`
DurScale DurScale `json:"dur_scale,omitzero"` DurScale DurScale `json:"dur_scale"`
Cooldown TenThousandths `json:"cooldown,omitzero"` Cooldown TenThousandths `json:"cooldown,omitzero"`
Abilities []Ability `json:"abilities"` Abilities []Ability `json:"abilities"`
} }
@@ -57,7 +57,7 @@ type Ability struct {
ValueUsage AbilityValueUsage `json:"value_usage"` ValueUsage AbilityValueUsage `json:"value_usage"`
Value TenThousandths `json:"value"` Value TenThousandths `json:"value"`
Target AbilityTarget `json:"target"` Target AbilityTarget `json:"target"`
TargetValue int32 `json:"target_value"` TargetValue int32 `json:"target_value,omitzero"`
} }
func (a Ability) String() string { func (a Ability) String() string {
@@ -211,6 +211,9 @@ type SkillGroupID int32
// skill with the corresponding group rate. // skill with the corresponding group rate.
// Some skill groups contain only Skill2 or SkillBad, while others may have all // Some skill groups contain only Skill2 or SkillBad, while others may have all
// four skills. // four skills.
//
// As a special case, horsegen lists both unique skills and their inherited
// versions in the skill groups for both.
type SkillGroup struct { type SkillGroup struct {
ID SkillGroupID `json:"skill_group"` ID SkillGroupID `json:"skill_group"`
// Skill1 is the base version of the skill, either a common (white) skill // Skill1 is the base version of the skill, either a common (white) skill

420
schema/schema.ts Normal file
View File

@@ -0,0 +1,420 @@
/**
* TypeScript schema for JSON files generated by horsegen.
*/
/**
* Character definitions.
*/
export interface Character {
/**
* Character ID.
*/
chara_id: number;
/**
* Regional name of the character.
* E.g., Special Week for Global, or スペシャルウィーク for JP.
*/
name: string;
}
/**
* Precomputed character pair and trio affinity.
*/
export interface Affinity {
/**
* First character in the relation.
*/
chara_a: number;
/**
* Second character in the relation.
* chara_a < chara_b is an invariant.
*/
chara_b: number;
/**
* Third character in the relation, if it is a trio relation.
* If defined, chara_b < chara_c is an invariant.
*/
chara_c?: number;
/**
* Total base compatibility between characters in the relation.
*/
affinity: number;
}
/**
* Uma or character card definitions.
*/
export interface Uma {
/**
* Uma ID.
*/
chara_card_id: number;
/**
* Character ID that the Uma is a variant of.
*/
chara_id: number;
/**
* Regional name of the Uma, comprised of the variant name and the character name.
* E.g. "[Special Dreamer] Special Week".
*/
name: string;
/**
* Regional variant name.
* E.g. "[Special Dreamer]".
*/
variant: string;
sprint: AptitudeLevel;
mile: AptitudeLevel;
medium: AptitudeLevel;
long: AptitudeLevel;
front: AptitudeLevel;
pace: AptitudeLevel;
late: AptitudeLevel;
end: AptitudeLevel;
turf: AptitudeLevel;
dirt: AptitudeLevel;
/**
* ID of the Uma's unique skill.
*/
unique: number;
/**
* ID of the Uma's first built-in skill.
*/
skill1: number;
/**
* ID of the Uma's second built-in skill.
*/
skill2: number;
/**
* ID of the Uma's third built-in skill.
*/
skill3: number;
/**
* ID of the skill unlocked at potential level 2.
*/
skill_pl2: number;
/**
* ID of the skill unlocked at potential level 3.
*/
skill_pl3: number;
/**
* ID of the skill unlocked at potential level 4.
*/
skill_pl4: number;
/**
* ID of the skill unlocked at potential level 5.
*/
skill_pl5: number;
}
export type AptitudeLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
/**
* Race data.
*/
export interface Race {
/**
* Race ID.
*/
race_id: number;
/**
* Regional name of the race.
*/
name: string;
/**
* Thumbnail asset ID number.
*/
thumbnail: number;
/**
* Primary race ID.
* For most races, this is the same as race_id. Some races are alternate
* versions for certain careers; this holds the ID of the normal version of
* the race.
*/
primary: number;
}
/**
* Race saddle data.
*/
export interface Saddle {
/**
* Saddle ID.
*/
saddle_id: number;
/**
* Regional name of the saddle.
*/
name: string;
/**
* IDs of race wins required to earn the saddle.
*/
races: number[];
/**
* Saddle type: 0 for multi-race honors, 3 for G1, 2 for G2, 1 for G3.
*/
type: 0 | 1 | 2 | 3;
/**
* Primary saddle ID.
* Respective for races.
*/
primary: number;
}
/**
* Scenario data.
*/
export interface Scenario {
/**
* Scenario ID.
*/
scenario_id: number;
/**
* Regional scenario name, e.g. "TS Climax".
*/
name: string;
/**
* Regional full title, e.g. "Trackblazer: Start of the Climax".
*/
title: string;
}
/**
* Skill data.
*/
export interface Skill {
/**
* Skill ID.
*/
skill_id: number;
/**
* Regional skill name.
*/
name: string;
/**
* Regional skil description.
*/
description: string;
/**
* Skill group ID.
*/
group: number;
/**
* Skill rarity. 3-5 are uniques for various star levels.
*/
rarity: 1 | 2 | 3 | 4 | 5;
/**
* Upgrade position within the skill's group.
* -1 is for negative (purple) skills.
*/
group_rate: 1 | 2 | 3 | -1;
/**
* Grade value, or the amount of rating gained for having the skill with
* appropriate aptitude.
*/
grade_value?: number;
/**
* Whether the skill requires a wit check.
*/
wit_check: boolean;
/**
* Conditions and results of skill activation.
*/
activations: [Activation] | [Activation, Activation];
/**
* Name of the Uma which owns this skill as a unique, if applicable.
*/
unique_owner?: string;
/**
* SP cost to purchase the skill, if applicable.
*/
sp_cost?: number;
/**
* Skill icon ID.
*/
icon_id: number;
}
/**
* Conditions and results of skill activation.
*/
export interface Activation {
/**
* Precondition which must be satisfied before the condition is checked.
*/
precondition?: string;
/**
* Activation conditions.
*/
condition: string;
/**
* Skill duration in ten thousandths of a second.
* Generally undefined for activations which only affect HP.
*/
duration?: number;
/**
* Special skill duration scaling mode.
*/
dur_scale: 1 | 2 | 3 | 4 | 5 | 7;
/**
* Skill cooldown in ten thousandths of a second.
* A value of 5000000 indicates that the cooldown is forever.
* Generally undefined for passive skills.
*/
cooldown?: number;
/**
* Results applied when the skill's conditions are met.
*/
abilities: [Ability] | [Ability, Ability] | [Ability, Ability, Ability];
}
/**
* Effects applied when a skill activates.
*/
export interface Ability {
/**
* Race mechanic affected by the ability.
*/
type: 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 13 | 21 | 27 | 28 | 31 | 35;
/**
* Special scaling type of the skill value.
*/
value_usage: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 19 | 20 | 22 | 23 | 24 | 25;
/**
* Amount that the skill modifies the race mechanic in ten thousandths of
* whatever is the appropriate unit.
*/
value: number;
/**
* Selector for horses targeted by the ability.
*/
target: 1 | 2 | 4 | 7 | 9 | 10 | 11 | 18 | 19 | 20 | 21 | 22 | 23;
/**
* Argument value for the ability target, when appropriate.
*/
target_value?: number;
}
/**
* Skill groups.
* Skills in a skill group replace each other when purchased.
*
* As a special case, horsegen lists both unique skills and their inherited
* versions in the skill groups for both.
*/
export interface SkillGroup {
/**
* Skill group ID.
*/
skill_group: number;
/**
* Base skill in the skill group, if any.
* Either a common (white) skill or an Uma's own unique.
*
* Some skill groups, e.g. for G1 Averseness, have no base skill.
*/
skill1?: number;
/**
* First upgraded version of a skill, if any.
* A rare (gold) skill, double circle skill, or an inherited unique skill.
*/
skill2?: number;
/**
* Highest upgraded version of a skill, if any.
* Gold version of a skill with a double circle version.
*/
skill3?: number;
/**
* Negative (purple) version of a skill, if any.
*/
skill_bad?: number;
}
/**
* Sparks, or succession factors.
*/
export interface Spark {
/**
* Spark ID.
*/
spark_id: number;
/**
* Regional spark name.
*/
name: string;
/**
* Regional spark description.
*/
description: string;
/**
* Spark group.
* Different star levels of a given spark are different spark IDs but
* share a spark group.
*/
spark_group: number;
/**
* Spark rarity, or star level.
*/
rarity: 1 | 2 | 3;
/**
* Spark type.
* Roughly the spark color, with extra subdivisions for white sparks.
*/
type: 1 | 2 | 5 | 4 | 6 | 7 | 10 | 8 | 11 | 9 | 3;
/**
* Possible effects applied by the spark during inspiration.
* A random element is selected from this list according to unknown
* distributions, then all effects in that selection are applied.
*/
effects: SparkEffect[][];
}
/**
* Effects that a spark can apply.
*/
export interface SparkEffect {
target: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 41 | 51 | 61 | 62 | 63 | 64 | 65;
value1?: number;
value2: number;
}
/**
* Lobby conversation data.
*/
export interface Conversation {
/**
* Character who owns the conversation as a gallery entry.
*/
chara_id: number;
/**
* Number of the conversation within the character's conversation gallery.
*/
number: number;
/**
* Location ID of the conversation.
*/
location: 110 | 120 | 130 | 210 | 220 | 310 | 410 | 420 | 430 | 510 | 520 | 530;
/**
* English name of the location, for convenience.
*/
location_name: string;
/**
* First character in the conversation.
* Not necessarily equal to chara_id.
*/
chara_1: number;
/**
* Second character, if present.
*/
chara_2?: number;
/**
* Third character, if present.
*/
chara_3?: number;
/**
* Some unknown number in the game's local database.
*/
condition_type: 0 | 1 | 2 | 3 | 4;
}