Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55aa03aa41 | ||
|
|
0ffd2c099a | ||
|
|
6828b1bd88 | ||
|
|
78aee43e5f | ||
|
|
745c9d01dd | ||
|
|
e00fe0965a | ||
|
|
caa19dd85a |
@@ -28,6 +28,8 @@ type AffinityDetail struct {
|
||||
|
||||
// Conversation describes a lobby conversation.
|
||||
type Conversation struct {
|
||||
// ID is the conversation ID.
|
||||
ID int32 `json:"id"`
|
||||
// CharacterID is the ID of the character who has the conversation as
|
||||
// a gallery entry.
|
||||
CharacterID CharacterID `json:"chara_id"`
|
||||
|
||||
+8
-7
@@ -89,13 +89,14 @@ func Umas(ctx context.Context, db *sqlitex.Pool) ([]horse.Uma, error) {
|
||||
func Conversations(ctx context.Context, db *sqlitex.Pool) ([]horse.Conversation, error) {
|
||||
return load(ctx, db, make([]horse.Conversation, 0, 1024), 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)),
|
||||
Chara1: horse.CharacterID(s.ColumnInt(3)),
|
||||
Chara2: horse.CharacterID(s.ColumnInt(4)),
|
||||
Chara3: horse.CharacterID(s.ColumnInt(5)),
|
||||
ConditionType: s.ColumnInt(6),
|
||||
ID: s.ColumnInt32(0),
|
||||
CharacterID: horse.CharacterID(s.ColumnInt(1)),
|
||||
Number: s.ColumnInt(2),
|
||||
Location: horse.LobbyConversationLocationID(s.ColumnInt(3)),
|
||||
Chara1: horse.CharacterID(s.ColumnInt(4)),
|
||||
Chara2: horse.CharacterID(s.ColumnInt(5)),
|
||||
Chara3: horse.CharacterID(s.ColumnInt(6)),
|
||||
ConditionType: s.ColumnInt(7),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -238,12 +238,14 @@ func TestConversations(t *testing.T) {
|
||||
}
|
||||
want := []horse.Conversation{
|
||||
{
|
||||
ID: 1,
|
||||
CharacterID: 1001,
|
||||
Number: 1,
|
||||
Location: 410,
|
||||
Chara1: 1001,
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
CharacterID: 1001,
|
||||
Number: 2,
|
||||
Location: 510,
|
||||
@@ -251,6 +253,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 1,
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
CharacterID: 1001,
|
||||
Number: 3,
|
||||
Location: 310,
|
||||
@@ -258,6 +261,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 1,
|
||||
},
|
||||
{
|
||||
ID: 76,
|
||||
CharacterID: 1001,
|
||||
Number: 4,
|
||||
Location: 120,
|
||||
@@ -266,6 +270,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 2,
|
||||
},
|
||||
{
|
||||
ID: 77,
|
||||
CharacterID: 1001,
|
||||
Number: 5,
|
||||
Location: 520,
|
||||
@@ -274,6 +279,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 3,
|
||||
},
|
||||
{
|
||||
ID: 126,
|
||||
CharacterID: 1001,
|
||||
Number: 6,
|
||||
Location: 430,
|
||||
@@ -283,12 +289,14 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 1,
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
CharacterID: 1002,
|
||||
Number: 1,
|
||||
Location: 310,
|
||||
Chara1: 1002,
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
CharacterID: 1002,
|
||||
Number: 2,
|
||||
Location: 210,
|
||||
@@ -296,6 +304,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 1,
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
CharacterID: 1002,
|
||||
Number: 3,
|
||||
Location: 110,
|
||||
@@ -303,6 +312,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 1,
|
||||
},
|
||||
{
|
||||
ID: 78,
|
||||
CharacterID: 1002,
|
||||
Number: 4,
|
||||
Location: 520,
|
||||
@@ -311,6 +321,7 @@ func TestConversations(t *testing.T) {
|
||||
ConditionType: 3,
|
||||
},
|
||||
{
|
||||
ID: 79,
|
||||
CharacterID: 1002,
|
||||
Number: 5,
|
||||
Location: 220,
|
||||
|
||||
+123
-77
@@ -18,6 +18,8 @@ var (
|
||||
skillGroupSQL string
|
||||
//go:embed sql/skill.sql
|
||||
skillSQL string
|
||||
//go:embed sql/skill-group-skills.sql
|
||||
skillGroupSkillsSQL string
|
||||
)
|
||||
|
||||
// SkillGroups retrieves all skill groups.
|
||||
@@ -35,84 +37,128 @@ func SkillGroups(ctx context.Context, db *sqlitex.Pool) ([]horse.SkillGroup, err
|
||||
|
||||
// Skills retrieves all skills.
|
||||
func Skills(ctx context.Context, db *sqlitex.Pool) ([]horse.Skill, error) {
|
||||
return load(ctx, db, nil, skillSQL, func(s *sqlite.Stmt) horse.Skill {
|
||||
return horse.Skill{
|
||||
ID: horse.SkillID(s.ColumnInt(0)),
|
||||
Name: s.ColumnText(1),
|
||||
Description: s.ColumnText(2),
|
||||
Group: horse.SkillGroupID(s.ColumnInt32(3)),
|
||||
Rarity: int8(s.ColumnInt(5)),
|
||||
GroupRate: int8(s.ColumnInt(6)),
|
||||
GradeValue: s.ColumnInt32(7),
|
||||
WitCheck: s.ColumnBool(8),
|
||||
Activations: trimActivations([]horse.Activation{
|
||||
{
|
||||
Precondition: s.ColumnText(9),
|
||||
Condition: s.ColumnText(10),
|
||||
Duration: horse.TenThousandths(s.ColumnInt(11)),
|
||||
DurScale: horse.DurScale(s.ColumnInt(12)),
|
||||
Cooldown: horse.TenThousandths(s.ColumnInt(13)),
|
||||
Abilities: trimAbilities([]horse.Ability{
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(14)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(15)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(16)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(17)),
|
||||
TargetValue: s.ColumnInt32(18),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(19)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(20)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(21)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(22)),
|
||||
TargetValue: s.ColumnInt32(23),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(24)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(25)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(26)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(27)),
|
||||
TargetValue: s.ColumnInt32(28),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Precondition: s.ColumnText(29),
|
||||
Condition: s.ColumnText(30),
|
||||
Duration: horse.TenThousandths(s.ColumnInt(31)),
|
||||
DurScale: horse.DurScale(s.ColumnInt(32)),
|
||||
Cooldown: horse.TenThousandths(s.ColumnInt(33)),
|
||||
Abilities: trimAbilities([]horse.Ability{
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(34)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(35)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(36)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(37)),
|
||||
TargetValue: s.ColumnInt32(38),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(39)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(40)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(41)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(42)),
|
||||
TargetValue: s.ColumnInt32(43),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(s.ColumnInt(44)),
|
||||
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(45)),
|
||||
Value: horse.TenThousandths(s.ColumnInt(46)),
|
||||
Target: horse.AbilityTarget(s.ColumnInt(47)),
|
||||
TargetValue: s.ColumnInt32(48),
|
||||
},
|
||||
}),
|
||||
},
|
||||
}),
|
||||
UniqueOwner: s.ColumnText(52), // TODO(zeph): should be id, not name
|
||||
Tags: parseTags(s.ColumnText(54)),
|
||||
SPCost: s.ColumnInt(49),
|
||||
IconID: s.ColumnInt(53),
|
||||
// We don't use func load here because we have multiple queries to run.
|
||||
conn, err := db.Take(ctx)
|
||||
defer db.Put(conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sk []horse.Skill
|
||||
{
|
||||
stmt := conn.Prep(skillSQL)
|
||||
defer stmt.Reset()
|
||||
for {
|
||||
ok, err := stmt.Step()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
s := horse.Skill{
|
||||
ID: horse.SkillID(stmt.ColumnInt(0)),
|
||||
Name: stmt.ColumnText(1),
|
||||
Description: stmt.ColumnText(2),
|
||||
GroupSkills: make([]horse.GroupSkill, 0, 3),
|
||||
Group: horse.SkillGroupID(stmt.ColumnInt32(3)),
|
||||
Rarity: int8(stmt.ColumnInt(5)),
|
||||
GroupRate: int8(stmt.ColumnInt(6)),
|
||||
GradeValue: stmt.ColumnInt32(7),
|
||||
WitCheck: stmt.ColumnBool(8),
|
||||
Activations: trimActivations([]horse.Activation{
|
||||
{
|
||||
Precondition: stmt.ColumnText(9),
|
||||
Condition: stmt.ColumnText(10),
|
||||
Duration: horse.TenThousandths(stmt.ColumnInt(11)),
|
||||
DurScale: horse.DurScale(stmt.ColumnInt(12)),
|
||||
Cooldown: horse.TenThousandths(stmt.ColumnInt(13)),
|
||||
Abilities: trimAbilities([]horse.Ability{
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(14)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(15)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(16)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(17)),
|
||||
TargetValue: stmt.ColumnInt32(18),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(19)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(20)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(21)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(22)),
|
||||
TargetValue: stmt.ColumnInt32(23),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(24)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(25)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(26)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(27)),
|
||||
TargetValue: stmt.ColumnInt32(28),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Precondition: stmt.ColumnText(29),
|
||||
Condition: stmt.ColumnText(30),
|
||||
Duration: horse.TenThousandths(stmt.ColumnInt(31)),
|
||||
DurScale: horse.DurScale(stmt.ColumnInt(32)),
|
||||
Cooldown: horse.TenThousandths(stmt.ColumnInt(33)),
|
||||
Abilities: trimAbilities([]horse.Ability{
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(34)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(35)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(36)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(37)),
|
||||
TargetValue: stmt.ColumnInt32(38),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(39)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(40)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(41)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(42)),
|
||||
TargetValue: stmt.ColumnInt32(43),
|
||||
},
|
||||
{
|
||||
Type: horse.AbilityType(stmt.ColumnInt(44)),
|
||||
ValueUsage: horse.AbilityValueUsage(stmt.ColumnInt(45)),
|
||||
Value: horse.TenThousandths(stmt.ColumnInt(46)),
|
||||
Target: horse.AbilityTarget(stmt.ColumnInt(47)),
|
||||
TargetValue: stmt.ColumnInt32(48),
|
||||
},
|
||||
}),
|
||||
},
|
||||
}),
|
||||
UniqueOwner: stmt.ColumnText(52), // TODO(zeph): should be id, not name
|
||||
Tags: parseTags(stmt.ColumnText(54)),
|
||||
SPCost: stmt.ColumnInt(49),
|
||||
IconID: stmt.ColumnInt(53),
|
||||
}
|
||||
sk = append(sk, s)
|
||||
}
|
||||
})
|
||||
}
|
||||
stmt := conn.Prep(skillGroupSkillsSQL)
|
||||
defer stmt.Reset()
|
||||
cur := sk
|
||||
for {
|
||||
ok, err := stmt.Step()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
// We sort skills by ID first, so we can add group skills in a single pass.
|
||||
id := stmt.ColumnInt(0)
|
||||
for len(cur) != 0 && cur[0].ID != horse.SkillID(id) {
|
||||
cur = cur[1:]
|
||||
}
|
||||
g := horse.GroupSkill{
|
||||
ID: horse.SkillID(stmt.ColumnInt(1)),
|
||||
GroupRate: int8(stmt.ColumnInt(2)),
|
||||
Rarity: int8(stmt.ColumnInt(3)),
|
||||
}
|
||||
cur[0].GroupSkills = append(cur[0].GroupSkills, g)
|
||||
}
|
||||
return sk, nil
|
||||
}
|
||||
|
||||
func parseTags(s string) []uint16 {
|
||||
|
||||
+182
-95
@@ -49,11 +49,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 10351,
|
||||
Name: "V Is for Victory!",
|
||||
Description: "Moderately increase velocity with winning ambition when positioned toward the front on the final straight after engaging in a challenge on the final corner or later.",
|
||||
Group: 1035,
|
||||
Rarity: 3,
|
||||
GroupRate: 1,
|
||||
GradeValue: 240,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 100351, GroupRate: 1, Rarity: 4},
|
||||
{ID: 10351, GroupRate: 1, Rarity: 3},
|
||||
{ID: 900351, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 1035,
|
||||
Rarity: 3,
|
||||
GroupRate: 1,
|
||||
GradeValue: 240,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "is_finalcorner==1&blocked_side_continuetime>=2",
|
||||
@@ -81,11 +86,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 100011,
|
||||
Name: "Shooting Star",
|
||||
Description: "Ride the momentum to increase velocity and very slightly increase acceleration after passing another runner toward the front late-race.",
|
||||
Group: 10001,
|
||||
Rarity: 5,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 100011, GroupRate: 1, Rarity: 5},
|
||||
{ID: 900011, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 10001,
|
||||
Rarity: 5,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -120,11 +129,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 100351,
|
||||
Name: "Our Ticket to Win!",
|
||||
Description: "Increase velocity with winning ambition when positioned toward the front on the final straight after engaging in a challenge on the final corner or later.",
|
||||
Group: 10035,
|
||||
Rarity: 4,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 100351, GroupRate: 1, Rarity: 4},
|
||||
{ID: 10351, GroupRate: 1, Rarity: 3},
|
||||
{ID: 900351, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 10035,
|
||||
Rarity: 4,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "is_finalcorner==1&blocked_side_continuetime>=2",
|
||||
@@ -152,11 +166,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 110241,
|
||||
Name: "Flowery☆Maneuver",
|
||||
Description: "Increase velocity when passing another runner toward the front on the final corner. If passing toward the back, increase acceleration instead.",
|
||||
Group: 11024,
|
||||
Rarity: 5,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 110241, GroupRate: 1, Rarity: 5},
|
||||
{ID: 910241, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 11024,
|
||||
Rarity: 5,
|
||||
GroupRate: 1,
|
||||
GradeValue: 340,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -200,11 +218,17 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200011,
|
||||
Name: "Right-Handed ◎",
|
||||
Description: "Increase performance on right-handed tracks.",
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 174,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200013, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200012, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200011, GroupRate: 2, Rarity: 1},
|
||||
{ID: 200014, GroupRate: 3, Rarity: 2},
|
||||
},
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 174,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -231,11 +255,17 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200012,
|
||||
Name: "Right-Handed ○",
|
||||
Description: "Moderately increase performance on right-handed tracks.",
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 129,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200013, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200012, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200011, GroupRate: 2, Rarity: 1},
|
||||
{ID: 200014, GroupRate: 3, Rarity: 2},
|
||||
},
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 129,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -262,11 +292,17 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200013,
|
||||
Name: "Right-Handed ×",
|
||||
Description: "Moderately decrease performance on right-handed tracks.",
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200013, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200012, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200011, GroupRate: 2, Rarity: 1},
|
||||
{ID: 200014, GroupRate: 3, Rarity: 2},
|
||||
},
|
||||
Group: 20001,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -293,11 +329,17 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200014,
|
||||
Name: "Right-Handed Demon",
|
||||
Description: "Increase proficiency in right-handed tracks, increasing Speed and Power.",
|
||||
Group: 20001,
|
||||
Rarity: 2,
|
||||
GroupRate: 3,
|
||||
GradeValue: 461,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200013, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200012, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200011, GroupRate: 2, Rarity: 1},
|
||||
{ID: 200014, GroupRate: 3, Rarity: 2},
|
||||
},
|
||||
Group: 20001,
|
||||
Rarity: 2,
|
||||
GroupRate: 3,
|
||||
GradeValue: 461,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -331,11 +373,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200021,
|
||||
Name: "Left-Handed ◎",
|
||||
Description: "Increase performance on left-handed tracks.",
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 174,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200023, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200022, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200021, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 174,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -362,11 +409,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200022,
|
||||
Name: "Left-Handed ○",
|
||||
Description: "Moderately increase performance on left-handed tracks.",
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 129,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200023, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200022, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200021, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 129,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -393,11 +445,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200023,
|
||||
Name: "Left-Handed ×",
|
||||
Description: "Moderately decrease performance on left-handed tracks.",
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200023, GroupRate: -1, Rarity: 1},
|
||||
{ID: 200022, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200021, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 20002,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -424,11 +481,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200361,
|
||||
Name: "Beeline Burst",
|
||||
Description: "Increase velocity on a straight.",
|
||||
Group: 20036,
|
||||
Rarity: 2,
|
||||
GroupRate: 2,
|
||||
GradeValue: 508,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200362, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200361, GroupRate: 2, Rarity: 2},
|
||||
},
|
||||
Group: 20036,
|
||||
Rarity: 2,
|
||||
GroupRate: 2,
|
||||
GradeValue: 508,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -455,11 +516,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200362,
|
||||
Name: "Straightaway Adept",
|
||||
Description: "Slightly increase velocity on a straight.",
|
||||
Group: 20036,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 217,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200362, GroupRate: 1, Rarity: 1},
|
||||
{ID: 200361, GroupRate: 2, Rarity: 2},
|
||||
},
|
||||
Group: 20036,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 217,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -486,11 +551,14 @@ func TestSkills(t *testing.T) {
|
||||
ID: 200831,
|
||||
Name: "Subdued Front Runners",
|
||||
Description: "Slightly increase fatigue for front runners early-race.",
|
||||
Group: 20083,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 217,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 200831, GroupRate: 1, Rarity: 1},
|
||||
},
|
||||
Group: 20083,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 217,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -517,11 +585,14 @@ func TestSkills(t *testing.T) {
|
||||
ID: 201801,
|
||||
Name: "♡ 3D Nail Art",
|
||||
Description: "Moderately decrease performance on firm ground.",
|
||||
Group: 20180,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 201801, GroupRate: -1, Rarity: 1},
|
||||
},
|
||||
Group: 20180,
|
||||
Rarity: 1,
|
||||
GroupRate: -1,
|
||||
GradeValue: -129,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -548,11 +619,14 @@ func TestSkills(t *testing.T) {
|
||||
ID: 300011,
|
||||
Name: "Unquenched Thirst",
|
||||
Description: "Moderately increase performance with the desire to race.",
|
||||
Group: 30001,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 0,
|
||||
WitCheck: false,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 300011, GroupRate: 1, Rarity: 1},
|
||||
},
|
||||
Group: 30001,
|
||||
Rarity: 1,
|
||||
GroupRate: 1,
|
||||
GradeValue: 0,
|
||||
WitCheck: false,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -579,11 +653,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 900011,
|
||||
Name: "Shooting Star",
|
||||
Description: "Slightly increase velocity and very minimally increase acceleration after passing another runner toward the front late-race.",
|
||||
Group: 10001,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 100011, GroupRate: 1, Rarity: 5},
|
||||
{ID: 900011, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 10001,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
@@ -618,11 +696,16 @@ func TestSkills(t *testing.T) {
|
||||
ID: 900351,
|
||||
Name: "Our Ticket to Win!",
|
||||
Description: "Slightly increase velocity when positioned toward the front on the final straight after engaging in a challenge on the final corner or later.",
|
||||
Group: 10035,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 100351, GroupRate: 1, Rarity: 4},
|
||||
{ID: 10351, GroupRate: 1, Rarity: 3},
|
||||
{ID: 900351, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 10035,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "is_finalcorner==1&blocked_side_continuetime>=2",
|
||||
@@ -650,11 +733,15 @@ func TestSkills(t *testing.T) {
|
||||
ID: 910241,
|
||||
Name: "Flowery☆Maneuver",
|
||||
Description: "Slightly increase velocity when passing another runner toward the front on the final corner. If passing toward the back, slightly increase acceleration instead.",
|
||||
Group: 11024,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
GroupSkills: []horse.GroupSkill{
|
||||
{ID: 110241, GroupRate: 1, Rarity: 5},
|
||||
{ID: 910241, GroupRate: 2, Rarity: 1},
|
||||
},
|
||||
Group: 11024,
|
||||
Rarity: 1,
|
||||
GroupRate: 2,
|
||||
GradeValue: 180,
|
||||
WitCheck: true,
|
||||
Activations: []horse.Activation{
|
||||
{
|
||||
Precondition: "",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
SELECT
|
||||
id,
|
||||
gallery_chara_id,
|
||||
disp_order,
|
||||
pos_id,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
WITH g AS (
|
||||
SELECT
|
||||
l.id AS l,
|
||||
r.id AS r,
|
||||
r.group_rate,
|
||||
r.rarity
|
||||
FROM skill_data l
|
||||
JOIN skill_data r ON l.group_id = r.group_id
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
s.id AS l,
|
||||
i.id AS r,
|
||||
i.group_rate,
|
||||
i.rarity
|
||||
FROM skill_data s
|
||||
JOIN skill_data i ON s.id IN (i.unique_skill_id_1, i.unique_skill_id_2)
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
s.id AS l,
|
||||
i.id AS r,
|
||||
i.group_rate,
|
||||
i.rarity
|
||||
FROM skill_data s
|
||||
JOIN skill_data i ON i.id IN (s.unique_skill_id_1, s.unique_skill_id_2)
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
l.id AS l,
|
||||
r.id AS r,
|
||||
r.group_rate,
|
||||
r.rarity
|
||||
FROM skill_data i
|
||||
JOIN skill_data l ON l.id IN (i.unique_skill_id_1, i.unique_skill_id_2)
|
||||
JOIN skill_data r ON r.id IN (i.unique_skill_id_1, i.unique_skill_id_2)
|
||||
WHERE l.id != r.id
|
||||
)
|
||||
SELECT * FROM g
|
||||
ORDER BY l, group_rate, rarity DESC
|
||||
@@ -30,6 +30,7 @@ type Skill struct {
|
||||
ID SkillID `json:"skill_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
GroupSkills []GroupSkill `json:"group_skills"`
|
||||
Group SkillGroupID `json:"group"`
|
||||
Rarity int8 `json:"rarity"`
|
||||
GroupRate int8 `json:"group_rate"`
|
||||
@@ -42,6 +43,12 @@ type Skill struct {
|
||||
IconID int `json:"icon_id"`
|
||||
}
|
||||
|
||||
type GroupSkill struct {
|
||||
ID SkillID `json:"skill_id"`
|
||||
GroupRate int8 `json:"group_rate"`
|
||||
Rarity int8 `json:"rarity"`
|
||||
}
|
||||
|
||||
// Activation is the parameters controlling when a skill activates.
|
||||
type Activation struct {
|
||||
Precondition string `json:"precondition,omitzero"`
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Code generated by "stringer -type CharaGradeType -linecomment -trimprefix CharaGrade"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[CharaGradeNone-0]
|
||||
_ = x[CharaGradeDebut-1]
|
||||
_ = x[CharaGradeNoWin-2]
|
||||
_ = x[CharaGradeOpen-3]
|
||||
_ = x[CharaGradeG3Silver-4]
|
||||
_ = x[CharaGradeG3Gold-5]
|
||||
_ = x[CharaGradeG2Silver-6]
|
||||
_ = x[CharaGradeG2Gold-7]
|
||||
_ = x[CharaGradeG1Bronze-8]
|
||||
_ = x[CharaGradeG1Silver-9]
|
||||
_ = x[CharaGradeG1Gold-10]
|
||||
_ = x[charaGradeMax-11]
|
||||
}
|
||||
|
||||
const _CharaGradeType_name = "NONEDebutNoWinOpenG3SilverG3GoldG2SilverG2GoldG1BronzeG1SilverG1GoldcharaGradeMax"
|
||||
|
||||
var _CharaGradeType_index = [...]uint8{0, 4, 9, 14, 18, 26, 32, 40, 46, 54, 62, 68, 81}
|
||||
|
||||
func (i CharaGradeType) String() string {
|
||||
idx := int(i) - 0
|
||||
if i < 0 || idx >= len(_CharaGradeType_index)-1 {
|
||||
return "CharaGradeType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _CharaGradeType_name[_CharaGradeType_index[idx]:_CharaGradeType_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type CourseDistanceType -linecomment -trimprefix Distance"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[DistanceSprint-1]
|
||||
_ = x[DistanceMile-2]
|
||||
_ = x[DistanceMedium-3]
|
||||
_ = x[DistanceLong-4]
|
||||
}
|
||||
|
||||
const _CourseDistanceType_name = "ShortMileMiddleLong"
|
||||
|
||||
var _CourseDistanceType_index = [...]uint8{0, 5, 9, 15, 19}
|
||||
|
||||
func (i CourseDistanceType) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_CourseDistanceType_index)-1 {
|
||||
return "CourseDistanceType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _CourseDistanceType_name[_CourseDistanceType_index[idx]:_CourseDistanceType_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type GroundCondition -linecomment"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[GroundFirm-1]
|
||||
_ = x[GroundGood-2]
|
||||
_ = x[GroundSoft-3]
|
||||
_ = x[GroundHeavy-4]
|
||||
}
|
||||
|
||||
const _GroundCondition_name = "GoodSoftHardBad"
|
||||
|
||||
var _GroundCondition_index = [...]uint8{0, 4, 8, 12, 15}
|
||||
|
||||
func (i GroundCondition) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_GroundCondition_index)-1 {
|
||||
return "GroundCondition(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _GroundCondition_name[_GroundCondition_index[idx]:_GroundCondition_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated by "stringer -type InitialLaneType -trimprefix InitialLane"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[InitialLaneExtraSpaceAfter9-1]
|
||||
_ = x[InitialLaneEquidistant-2]
|
||||
_ = x[InitialLaneExtraSpaceAfter14-3]
|
||||
_ = x[InitialLaneExtraSpaceAfter8-4]
|
||||
_ = x[initialLaneMax-5]
|
||||
}
|
||||
|
||||
const _InitialLaneType_name = "ExtraSpaceAfter9EquidistantExtraSpaceAfter14ExtraSpaceAfter8initialLaneMax"
|
||||
|
||||
var _InitialLaneType_index = [...]uint8{0, 16, 27, 44, 60, 74}
|
||||
|
||||
func (i InitialLaneType) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_InitialLaneType_index)-1 {
|
||||
return "InitialLaneType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _InitialLaneType_name[_InitialLaneType_index[idx]:_InitialLaneType_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Code generated by "stringer -type MainStoryRaceGimmickType -linecomment"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[GimmickNone-0]
|
||||
_ = x[GimmickSpecial00-1]
|
||||
_ = x[gimmickMax-2]
|
||||
}
|
||||
|
||||
const _MainStoryRaceGimmickType_name = "NONESpecial_00gimmickMax"
|
||||
|
||||
var _MainStoryRaceGimmickType_index = [...]uint8{0, 4, 14, 24}
|
||||
|
||||
func (i MainStoryRaceGimmickType) String() string {
|
||||
idx := int(i) - 0
|
||||
if i < 0 || idx >= len(_MainStoryRaceGimmickType_index)-1 {
|
||||
return "MainStoryRaceGimmickType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _MainStoryRaceGimmickType_name[_MainStoryRaceGimmickType_index[idx]:_MainStoryRaceGimmickType_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Code generated by "stringer -type RaceDifficulty -trimprefix Difficulty"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[DifficultyEasy-1]
|
||||
_ = x[DifficultyNormal-2]
|
||||
_ = x[DifficultyHard-3]
|
||||
_ = x[DifficultyVeryHard-4]
|
||||
_ = x[DifficultyExtreme-5]
|
||||
_ = x[difficultyMax-6]
|
||||
}
|
||||
|
||||
const _RaceDifficulty_name = "EasyNormalHardVeryHardExtremedifficultyMax"
|
||||
|
||||
var _RaceDifficulty_index = [...]uint8{0, 4, 10, 14, 22, 29, 42}
|
||||
|
||||
func (i RaceDifficulty) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_RaceDifficulty_index)-1 {
|
||||
return "RaceDifficulty(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RaceDifficulty_name[_RaceDifficulty_index[idx]:_RaceDifficulty_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Code generated by "stringer -type RaceTime -trimprefix Time"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[TimeMin-0]
|
||||
_ = x[TimeMorning-1]
|
||||
_ = x[TimeDaytime-2]
|
||||
_ = x[TimeEvening-3]
|
||||
_ = x[TimeNight-4]
|
||||
_ = x[TimeMax-5]
|
||||
}
|
||||
|
||||
const _RaceTime_name = "MinMorningDaytimeEveningNightMax"
|
||||
|
||||
var _RaceTime_index = [...]uint8{0, 3, 10, 17, 24, 29, 32}
|
||||
|
||||
func (i RaceTime) String() string {
|
||||
idx := int(i) - 0
|
||||
if i < 0 || idx >= len(_RaceTime_index)-1 {
|
||||
return "RaceTime(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RaceTime_name[_RaceTime_index[idx]:_RaceTime_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Code generated by "stringer -type RaceType -linecomment -trimprefix RaceType"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[RaceTypeNone-0]
|
||||
_ = x[RaceTypePvP-1]
|
||||
_ = x[RaceTypeTutorial-2]
|
||||
_ = x[RaceTypeStory-3]
|
||||
_ = x[RaceTypeStoryCondition-4]
|
||||
_ = x[RaceTypeChampions-5]
|
||||
_ = x[RaceTypeSingle-6]
|
||||
_ = x[RaceTypeSingleModeScenarioTeamRace-7]
|
||||
_ = x[RaceTypeRoomMatch-8]
|
||||
_ = x[RaceTypePractice-9]
|
||||
_ = x[RaceTypeDaily-10]
|
||||
_ = x[RaceTypeTeamBuilding-11]
|
||||
_ = x[RaceTypeLegend-12]
|
||||
_ = x[RaceTypeChallengeMatch-13]
|
||||
_ = x[RaceTypeTeamStadium-14]
|
||||
_ = x[RaceTypeHeroes-16]
|
||||
_ = x[raceTypeMaxInclusive-16]
|
||||
}
|
||||
|
||||
const (
|
||||
_RaceType_name_0 = "NONEPvPTutorialStoryStoryConditionChampionsSingleSingleModeScenarioTeamRaceRoomMatchPracticeDailyTeamBuildingLegendChallengeMatchTeamStadium"
|
||||
_RaceType_name_1 = "Heroes"
|
||||
)
|
||||
|
||||
var (
|
||||
_RaceType_index_0 = [...]uint8{0, 4, 7, 15, 20, 34, 43, 49, 75, 84, 92, 97, 109, 115, 129, 140}
|
||||
)
|
||||
|
||||
func (i RaceType) String() string {
|
||||
switch {
|
||||
case 0 <= i && i <= 14:
|
||||
return _RaceType_name_0[_RaceType_index_0[i]:_RaceType_index_0[i+1]]
|
||||
case i == 16:
|
||||
return _RaceType_name_1
|
||||
default:
|
||||
return "RaceType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Code generated by "stringer -type RaceWeather -trimprefix Weather"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[WeatherMin-0]
|
||||
_ = x[WeatherSunny-1]
|
||||
_ = x[WeatherCloudy-2]
|
||||
_ = x[WeatherRainy-3]
|
||||
_ = x[WeatherSnow-4]
|
||||
_ = x[WeatherMax-5]
|
||||
}
|
||||
|
||||
const _RaceWeather_name = "MinSunnyCloudyRainySnowMax"
|
||||
|
||||
var _RaceWeather_index = [...]uint8{0, 3, 8, 14, 19, 23, 26}
|
||||
|
||||
func (i RaceWeather) String() string {
|
||||
idx := int(i) - 0
|
||||
if i < 0 || idx >= len(_RaceWeather_index)-1 {
|
||||
return "RaceWeather(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _RaceWeather_name[_RaceWeather_index[idx]:_RaceWeather_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,920 @@
|
||||
package replay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"git.sunturtle.xyz/zephyr/horse"
|
||||
)
|
||||
|
||||
type Race struct {
|
||||
RaceType RaceType `json:"raceType"`
|
||||
IsExistPlayerRace bool `json:"isExistPlayerRace"`
|
||||
IsExistGhostRace bool `json:"isExistGhostRace"`
|
||||
IsExistFollowRace bool `json:"isExistFollowRace"`
|
||||
IsMultiplePlayerRace bool `json:"isMultiplePlayerRace"`
|
||||
RandomSeed int32 `json:"randomSeed"`
|
||||
SingleRaceProgramID int32 `json:"singleRaceProgramId"`
|
||||
OpponentEvaluate int32 `json:"opponentEvaluate"`
|
||||
SelfEvaluate int32 `json:"selfEvaluate"`
|
||||
SupportCardScoreBonus int32 `json:"supportCardScoreBonus"`
|
||||
ScoreCalcTeamID int32 `json:"scoreCalcTeamId"`
|
||||
RaceNo int32 `json:"raceNo"`
|
||||
RaceCourseSet RaceCourseSet `json:"raceCourseSet"`
|
||||
FenceSet struct{} `json:"fenceSet"`
|
||||
RaceTrack struct{} `json:"raceTrack"`
|
||||
GoalGate int32 `json:"goalGate"`
|
||||
GoalGateFlower int32 `json:"goalGateFlower"`
|
||||
InitialLaneType InitialLaneType `json:"initialLaneType"`
|
||||
RotationCategory Rotation `json:"rotationCategory"`
|
||||
ResultBoardConditionType ResultBoardConditionType `json:"resultBoardConditionType"`
|
||||
CourseSectionDistance float32 `json:"courseSectionDistance"`
|
||||
CourseDistanceType CourseDistanceType `json:"courseDistanceType"`
|
||||
CourseFurlongNum int32 `json:"courseFurlongNum"`
|
||||
IsHalfGate bool `json:"isHalfGate"`
|
||||
IsHorseNumVariationGate bool `json:"isHorseNumVariationGate"`
|
||||
TurfVisionType TurfVisionType `json:"turfVisionType"`
|
||||
GroundCondition GroundCondition `json:"groundCondition"`
|
||||
Weather RaceWeather `json:"weather"`
|
||||
Season Season `json:"season"`
|
||||
Time RaceTime `json:"time"`
|
||||
BaseSpeed float32 `json:"baseSpeed"`
|
||||
BorderTimeScaled float32 `json:"borderTimeScaled"`
|
||||
ChallengeMatchDifficulty RaceDifficulty `json:"challengeMatchDifficulty"`
|
||||
NumRaceHorses int32 `json:"numRaceHorses"`
|
||||
PostNumberMax int32 `json:"postNumberMax"`
|
||||
PlayerHorseIndex int32 `json:"playerHorseIndex"`
|
||||
OverridePlayerHorseIndex int32 `json:"overridePlayerHorseIndex"`
|
||||
PlayerTeamMemberArray []RaceHorse `json:"playerTeamMemberArray"`
|
||||
PlayerTeamTopFinishOrderHorse RaceHorse `json:"playerTeamTopFinishOrderHorse"`
|
||||
IsGateInPopularityInitialized bool `json:"isGateInPopularityInitialized"`
|
||||
RaceHorse []RaceHorse `json:"raceHorse"`
|
||||
RaceBibMaster struct{} `json:"raceBibMaster"`
|
||||
RaceMaster struct{} `json:"raceMaster"`
|
||||
RaceInstanceMaster struct{} `json:"raceInstanceMaster"`
|
||||
SimDataBase64 string `json:"simDataBase64"`
|
||||
SimData struct{} `json:"simData"`
|
||||
SimReader struct{} `json:"simReader"`
|
||||
EpisodeRaceReplayID int32 `json:"episodeRaceReplayId"`
|
||||
IsNotSimulateExport bool `json:"isNotSimulateExport"`
|
||||
LaneDistanceMax float32 `json:"laneDistanceMax"`
|
||||
ReplayCheckInfo struct{} `json:"replayCheckInfo"`
|
||||
ReplayCheckInfoDaily struct{} `json:"replayCheckInfoDaily"`
|
||||
ReplayCheckInfoLegend struct{} `json:"replayCheckInfoLegend"`
|
||||
IsDailyLegendRace bool `json:"isDailyLegendRace"`
|
||||
ReplayCheckInfoChallengeMatch struct{} `json:"replayCheckInfoChallengeMatch"`
|
||||
RaceRewardSingle RaceRewardSingle `json:"raceRewardSingle"`
|
||||
ResultHorseIndex int32 `json:"resultHorseIndex"`
|
||||
PrevGradeType CharaGradeType `json:"prevGradeType"`
|
||||
MainStoryRaceGimmickType MainStoryRaceGimmickType `json:"mainStoryRaceGimmickType"`
|
||||
IsMainStoryRaceMatchGimmick bool `json:"isMainStoryRaceMatchGimmick"`
|
||||
UnlockFlags uint32 `json:"unlockFlags"`
|
||||
PhaseCalculator struct{} `json:"phaseCalculator"`
|
||||
HorseIndexByFinishOrder []int32 `json:"horseIndexByFinishOrder"`
|
||||
HorseIndexByPopularity []int32 `json:"horseIndexByPopularity"`
|
||||
}
|
||||
|
||||
type RaceType int32
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type RaceType -linecomment -trimprefix RaceType
|
||||
const (
|
||||
RaceTypeNone RaceType = iota // NONE
|
||||
RaceTypePvP
|
||||
RaceTypeTutorial
|
||||
RaceTypeStory
|
||||
RaceTypeStoryCondition
|
||||
RaceTypeChampions
|
||||
RaceTypeSingle
|
||||
RaceTypeSingleModeScenarioTeamRace
|
||||
RaceTypeRoomMatch
|
||||
RaceTypePractice
|
||||
RaceTypeDaily
|
||||
RaceTypeTeamBuilding
|
||||
RaceTypeLegend
|
||||
RaceTypeChallengeMatch
|
||||
RaceTypeTeamStadium
|
||||
// no value 15
|
||||
RaceTypeHeroes RaceType = 16
|
||||
|
||||
raceTypeMaxInclusive
|
||||
)
|
||||
|
||||
func (r RaceType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r RaceType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var raceTypeNames = sync.OnceValue(func() map[string]RaceType {
|
||||
m := make(map[string]RaceType, raceTypeMaxInclusive)
|
||||
for r := RaceTypeNone; r <= raceTypeMaxInclusive; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "RaceType(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *RaceType) UnmarshalText(b []byte) error {
|
||||
n, ok := raceTypeNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown race type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RaceCourseSet struct {
|
||||
ID horse.RacecourseID `json:"id"`
|
||||
RaceTrackID horse.RaceTrackID `json:"raceTrackId"`
|
||||
Distance int32 `json:"distance"`
|
||||
Ground int `json:"ground"`
|
||||
Inout int `json:"inout"`
|
||||
Turn int `json:"turn"`
|
||||
FenceSet int `json:"fenceSet"`
|
||||
FloatLaneMax int `json:"floatLaneMax"`
|
||||
CourseSetStatusID int `json:"courseSetStatusId"`
|
||||
FinishTimeMin int `json:"finishTimeMin"`
|
||||
FinishTimeMinRandomRange int `json:"finishTimeMinRandomRange"`
|
||||
FinishTimeMax int `json:"finishTimeMax"`
|
||||
FinishTimeMaxRandomRange int `json:"finishTimeMaxRandomRange"`
|
||||
}
|
||||
|
||||
type InitialLaneType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type InitialLaneType -trimprefix InitialLane
|
||||
const (
|
||||
InitialLaneExtraSpaceAfter9 InitialLaneType = iota + 1
|
||||
InitialLaneEquidistant
|
||||
InitialLaneExtraSpaceAfter14
|
||||
InitialLaneExtraSpaceAfter8
|
||||
|
||||
initialLaneMax
|
||||
)
|
||||
|
||||
func (r InitialLaneType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r InitialLaneType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var initialLaneNames = sync.OnceValue(func() map[string]InitialLaneType {
|
||||
m := make(map[string]InitialLaneType, initialLaneMax)
|
||||
for r := InitialLaneExtraSpaceAfter9; r < initialLaneMax; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "InitialLaneType(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *InitialLaneType) UnmarshalText(b []byte) error {
|
||||
n, ok := initialLaneNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown initial lane type type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Rotation int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type Rotation -trimprefix Rotation
|
||||
const (
|
||||
RotationRight Rotation = iota + 1
|
||||
RotationLeft
|
||||
RotationStraightRight
|
||||
RotationStraightLeft
|
||||
)
|
||||
|
||||
func (r Rotation) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r Rotation) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *Rotation) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Right":
|
||||
*r = RotationRight
|
||||
case "Left":
|
||||
*r = RotationLeft
|
||||
case "StraightRight":
|
||||
*r = RotationStraightRight
|
||||
case "StraightLeft":
|
||||
*r = RotationStraightLeft
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown rotation type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ResultBoardConditionType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type ResultBoardConditionType -linecomment
|
||||
const (
|
||||
ResultBoardTurfNone ResultBoardConditionType = iota + 1 // Turf_None
|
||||
ResultBoardTurfDirt // Turf_Dirt
|
||||
ResultBoardDirtNone // Dirt_None
|
||||
ResultBoardDirtTurf // Dirt_Turf
|
||||
)
|
||||
|
||||
func (r ResultBoardConditionType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r ResultBoardConditionType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *ResultBoardConditionType) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Turf_None":
|
||||
*r = ResultBoardTurfNone
|
||||
case "Turf_Dirt":
|
||||
*r = ResultBoardTurfDirt
|
||||
case "Dirt_None":
|
||||
*r = ResultBoardDirtNone
|
||||
case "Dirt_Turf":
|
||||
*r = ResultBoardDirtTurf
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown result board type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CourseDistanceType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type CourseDistanceType -linecomment -trimprefix Distance
|
||||
const (
|
||||
DistanceSprint CourseDistanceType = iota + 1 // Short
|
||||
DistanceMile
|
||||
DistanceMedium // Middle
|
||||
DistanceLong
|
||||
)
|
||||
|
||||
func (r CourseDistanceType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r CourseDistanceType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *CourseDistanceType) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Short":
|
||||
*r = DistanceSprint
|
||||
case "Mile":
|
||||
*r = DistanceMile
|
||||
case "Middle":
|
||||
*r = DistanceMedium
|
||||
case "Long":
|
||||
*r = DistanceLong
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown distance type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type TurfVisionType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type TurfVisionType -trimprefix TurfVision
|
||||
const (
|
||||
TurfVisionURA TurfVisionType = iota + 1
|
||||
TurfVisionNAU
|
||||
TurfVisionStand
|
||||
|
||||
turfVisionMax
|
||||
)
|
||||
|
||||
func (r TurfVisionType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r TurfVisionType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var turfVisionNames = sync.OnceValue(func() map[string]TurfVisionType {
|
||||
m := make(map[string]TurfVisionType, turfVisionMax)
|
||||
for r := TurfVisionURA; r < turfVisionMax; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "TurfVisionType(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *TurfVisionType) UnmarshalText(b []byte) error {
|
||||
n, ok := turfVisionNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown turf vision type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GroundCondition int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type GroundCondition -linecomment
|
||||
const (
|
||||
GroundFirm GroundCondition = iota + 1 // Good
|
||||
GroundGood // Soft
|
||||
GroundSoft // Hard
|
||||
GroundHeavy // Bad
|
||||
)
|
||||
|
||||
func (r GroundCondition) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r GroundCondition) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *GroundCondition) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Good":
|
||||
*r = GroundFirm
|
||||
case "Soft":
|
||||
*r = GroundGood
|
||||
case "Hard":
|
||||
*r = GroundSoft
|
||||
case "Bad":
|
||||
*r = GroundHeavy
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown ground condition type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RaceWeather int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type RaceWeather -trimprefix Weather
|
||||
const (
|
||||
WeatherMin RaceWeather = iota
|
||||
WeatherSunny
|
||||
WeatherCloudy
|
||||
WeatherRainy
|
||||
WeatherSnow
|
||||
WeatherMax
|
||||
)
|
||||
|
||||
func (r RaceWeather) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r RaceWeather) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *RaceWeather) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Min", "NONE":
|
||||
*r = WeatherMin
|
||||
case "Sunny":
|
||||
*r = WeatherSunny
|
||||
case "Cloudy":
|
||||
*r = WeatherCloudy
|
||||
case "Rainy":
|
||||
*r = WeatherRainy
|
||||
case "Snow":
|
||||
*r = WeatherSnow
|
||||
case "Max":
|
||||
*r = WeatherMax
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown race weather %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Season int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type Season -trimprefix Season
|
||||
const (
|
||||
SeasonMin Season = iota
|
||||
SeasonSpring
|
||||
SeasonSummer
|
||||
SeasonFall
|
||||
SeasonWinter
|
||||
SeasonCherryBlossom
|
||||
SeasonMax
|
||||
)
|
||||
|
||||
func (r Season) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r Season) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *Season) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Min", "NONE":
|
||||
*r = SeasonMin
|
||||
case "Spring":
|
||||
*r = SeasonSpring
|
||||
case "Summer":
|
||||
*r = SeasonSummer
|
||||
case "Fall":
|
||||
*r = SeasonFall
|
||||
case "Winter":
|
||||
*r = SeasonWinter
|
||||
case "CherryBlossom":
|
||||
*r = SeasonCherryBlossom
|
||||
case "Max":
|
||||
*r = SeasonMax
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown season %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RaceTime int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type RaceTime -trimprefix Time
|
||||
const (
|
||||
TimeMin RaceTime = iota
|
||||
TimeMorning
|
||||
TimeDaytime
|
||||
TimeEvening
|
||||
TimeNight
|
||||
TimeMax
|
||||
)
|
||||
|
||||
func (r RaceTime) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r RaceTime) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
func (r *RaceTime) UnmarshalText(b []byte) error {
|
||||
switch string(b) {
|
||||
case "Min":
|
||||
*r = TimeMin
|
||||
case "Morning":
|
||||
*r = TimeMorning
|
||||
case "Daytime":
|
||||
*r = TimeDaytime
|
||||
case "Evening":
|
||||
*r = TimeEvening
|
||||
case "Night":
|
||||
*r = TimeNight
|
||||
case "Max":
|
||||
*r = TimeMax
|
||||
default:
|
||||
*r = 0
|
||||
return fmt.Errorf("unknown race time %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RaceDifficulty int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type RaceDifficulty -trimprefix Difficulty
|
||||
const (
|
||||
DifficultyEasy RaceDifficulty = iota + 1
|
||||
DifficultyNormal
|
||||
DifficultyHard
|
||||
DifficultyVeryHard
|
||||
DifficultyExtreme
|
||||
|
||||
difficultyMax
|
||||
)
|
||||
|
||||
func (r RaceDifficulty) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r RaceDifficulty) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var difficultyNames = sync.OnceValue(func() map[string]RaceDifficulty {
|
||||
m := make(map[string]RaceDifficulty, difficultyMax)
|
||||
for r := DifficultyEasy; r < difficultyMax; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "RaceDifficulty(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
// extra one for pure pvp races
|
||||
m["UNKNOWN"] = 0
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *RaceDifficulty) UnmarshalText(b []byte) error {
|
||||
n, ok := difficultyNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown turf vision type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RaceParam struct {
|
||||
RawSpeed int `json:"rawSpeed"`
|
||||
RawStamina int `json:"rawStamina"`
|
||||
RawPow int `json:"rawPow"`
|
||||
RawGuts int `json:"rawGuts"`
|
||||
RawWiz int `json:"rawWiz"`
|
||||
BaseSpeed float32 `json:"baseSpeed"`
|
||||
BaseStamina float32 `json:"baseStamina"`
|
||||
BasePow float32 `json:"basePow"`
|
||||
BaseGuts float32 `json:"baseGuts"`
|
||||
BaseWiz float32 `json:"baseWiz"`
|
||||
Motivation string `json:"motivation"`
|
||||
MotivationCoef float32 `json:"motivationCoef"`
|
||||
}
|
||||
|
||||
type SkillArray struct {
|
||||
SkillID int `json:"skill_id"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
|
||||
type RaceResultArray struct {
|
||||
Turn int `json:"turn"`
|
||||
ProgramID int `json:"program_id"`
|
||||
Weather int `json:"weather"`
|
||||
GroundCondition int `json:"ground_condition"`
|
||||
RunningStyle int `json:"running_style"`
|
||||
Popularity int `json:"popularity"`
|
||||
ResultRank int `json:"result_rank"`
|
||||
ResultTime int `json:"result_time"`
|
||||
PrizeMoney int `json:"prize_money"`
|
||||
}
|
||||
type ResponseHorseData struct {
|
||||
FrameOrder int `json:"frame_order"`
|
||||
ViewerID int64 `json:"viewer_id"`
|
||||
TrainerName string `json:"trainer_name"`
|
||||
OwnerViewerID int `json:"owner_viewer_id"`
|
||||
OwnerTrainerName string `json:"owner_trainer_name"`
|
||||
SingleModeCharaID int `json:"single_mode_chara_id"`
|
||||
TrainedCharaID int `json:"trained_chara_id"`
|
||||
NicknameID int `json:"nickname_id"`
|
||||
CharaID int `json:"chara_id"`
|
||||
CardID int `json:"card_id"`
|
||||
MobID int `json:"mob_id"`
|
||||
Rarity int `json:"rarity"`
|
||||
TalentLevel int `json:"talent_level"`
|
||||
SkillArray []SkillArray `json:"skill_array"`
|
||||
Stamina int `json:"stamina"`
|
||||
Speed int `json:"speed"`
|
||||
Pow int `json:"pow"`
|
||||
Guts int `json:"guts"`
|
||||
Wiz int `json:"wiz"`
|
||||
RunningStyle int `json:"running_style"`
|
||||
RaceDressID int `json:"race_dress_id"`
|
||||
CharaColorType int `json:"chara_color_type"`
|
||||
NpcType int `json:"npc_type"`
|
||||
FinalGrade int `json:"final_grade"`
|
||||
Popularity int `json:"popularity"`
|
||||
PopularityMarkRankArray []int `json:"popularity_mark_rank_array"`
|
||||
ProperDistanceShort int `json:"proper_distance_short"`
|
||||
ProperDistanceMile int `json:"proper_distance_mile"`
|
||||
ProperDistanceMiddle int `json:"proper_distance_middle"`
|
||||
ProperDistanceLong int `json:"proper_distance_long"`
|
||||
ProperRunningStyleNige int `json:"proper_running_style_nige"`
|
||||
ProperRunningStyleSenko int `json:"proper_running_style_senko"`
|
||||
ProperRunningStyleSashi int `json:"proper_running_style_sashi"`
|
||||
ProperRunningStyleOikomi int `json:"proper_running_style_oikomi"`
|
||||
ProperGroundTurf int `json:"proper_ground_turf"`
|
||||
ProperGroundDirt int `json:"proper_ground_dirt"`
|
||||
Motivation int `json:"motivation"`
|
||||
WinSaddleIDArray []int `json:"win_saddle_id_array"`
|
||||
RaceResultArray []RaceResultArray `json:"race_result_array"`
|
||||
TeamID int `json:"team_id"`
|
||||
TeamMemberID int `json:"team_member_id"`
|
||||
TeamRank int `json:"team_rank"`
|
||||
SingleModeWinCount int `json:"single_mode_win_count"`
|
||||
ItemIDArray []any `json:"item_id_array"`
|
||||
MotivationChangeFlag int `json:"motivation_change_flag"`
|
||||
FrameOrderChangeFlag int `json:"frame_order_change_flag"`
|
||||
}
|
||||
type RaceRecord struct {
|
||||
}
|
||||
type FactorDataArray struct {
|
||||
FactorLv int `json:"factorLv"`
|
||||
FactorID int `json:"factorId"`
|
||||
BaseFactorID int `json:"baseFactorId"`
|
||||
UpgradeHistoryList []any `json:"upgradeHistoryList"`
|
||||
}
|
||||
type FavoriteData struct {
|
||||
}
|
||||
type SuccessionCharaList struct {
|
||||
PositionID int `json:"positionId"`
|
||||
CardID int `json:"cardId"`
|
||||
Rarity int `json:"rarity"`
|
||||
Level int `json:"level"`
|
||||
Rank int `json:"rank"`
|
||||
FactorDataArray []FactorDataArray `json:"factorDataArray"`
|
||||
SortedFactorList []any `json:"sortedFactorList"`
|
||||
SortedFactorListForProfileCard []any `json:"sortedFactorListForProfileCard"`
|
||||
OwnerViewerID int `json:"ownerViewerId"`
|
||||
IsPlayer bool `json:"isPlayer"`
|
||||
WinSaddleArray []any `json:"winSaddleArray"`
|
||||
WinSaddleIDArray []int `json:"winSaddleIdArray"`
|
||||
}
|
||||
type Master struct {
|
||||
}
|
||||
type AcquiredSkillArray struct {
|
||||
MasterID int `json:"masterId"`
|
||||
Level int `json:"level"`
|
||||
Master Master `json:"master"`
|
||||
}
|
||||
type SupportCardArray struct {
|
||||
Position int `json:"position"`
|
||||
SupportCardID int `json:"supportCardId"`
|
||||
LimitBreakCount int `json:"limitBreakCount"`
|
||||
Exp int `json:"exp"`
|
||||
}
|
||||
type SingleModeRaceResultArray struct {
|
||||
Turn int `json:"turn"`
|
||||
ProgramID int `json:"programId"`
|
||||
RaceInstanceID int `json:"raceInstanceId"`
|
||||
FrameOrder int `json:"frameOrder"`
|
||||
NpcCount int `json:"npcCount"`
|
||||
Weather int `json:"weather"`
|
||||
GroundCondition int `json:"groundCondition"`
|
||||
RunningStyle int `json:"runningStyle"`
|
||||
ResultRank int `json:"resultRank"`
|
||||
ScenarioID int `json:"scenarioId"`
|
||||
}
|
||||
type MasterCardData struct {
|
||||
}
|
||||
type MasterCharaData struct {
|
||||
}
|
||||
type MasterCardRarityData struct {
|
||||
}
|
||||
type TrainedCharaDataAccessor struct {
|
||||
}
|
||||
type TrainedCharaData struct {
|
||||
ID int `json:"id"`
|
||||
IsSaved bool `json:"isSaved"`
|
||||
ViewerID int64 `json:"viewerId"`
|
||||
OwnerViewerID int `json:"ownerViewerId"`
|
||||
OwnerTrainedCharaID int `json:"ownerTrainedCharaId"`
|
||||
UseType int `json:"useType"`
|
||||
CardID int `json:"cardId"`
|
||||
NickNameID int `json:"nickNameId"`
|
||||
NickNameIDArray []int `json:"nickNameIdArray"`
|
||||
Stamina int `json:"stamina"`
|
||||
Speed int `json:"speed"`
|
||||
Power int `json:"power"`
|
||||
Guts int `json:"guts"`
|
||||
Wiz int `json:"wiz"`
|
||||
Fans int `json:"fans"`
|
||||
Rank int `json:"rank"`
|
||||
RankScore int `json:"rankScore"`
|
||||
RunningStyle int `json:"runningStyle"`
|
||||
ProperGroundTurf int `json:"properGroundTurf"`
|
||||
ProperGroundDirt int `json:"properGroundDirt"`
|
||||
ProperDistanceShort int `json:"properDistanceShort"`
|
||||
ProperDistanceMile int `json:"properDistanceMile"`
|
||||
ProperDistanceMiddle int `json:"properDistanceMiddle"`
|
||||
ProperDistanceLong int `json:"properDistanceLong"`
|
||||
ProperRunningStyleNige int `json:"properRunningStyleNige"`
|
||||
ProperRunningStyleSenko int `json:"properRunningStyleSenko"`
|
||||
ProperRunningStyleSashi int `json:"properRunningStyleSashi"`
|
||||
ProperRunningStyleOikomi int `json:"properRunningStyleOikomi"`
|
||||
SuccessionCount int `json:"successionCount"`
|
||||
FactorDataArray []FactorDataArray `json:"factorDataArray"`
|
||||
CreateTime string `json:"createTime"`
|
||||
ScenarioID int `json:"scenarioId"`
|
||||
TalentLevel int `json:"talentLevel"`
|
||||
CharaGrade int `json:"charaGrade"`
|
||||
Rarity int `json:"rarity"`
|
||||
IsLock bool `json:"isLock"`
|
||||
FavoriteData FavoriteData `json:"favoriteData"`
|
||||
CachedCreateTimeTimeStamp int `json:"cachedCreateTimeTimeStamp"`
|
||||
SortedFactorList []any `json:"sortedFactorList"`
|
||||
SortedFactorProfileCardList []any `json:"sortedFactorProfileCardList"`
|
||||
FactorListIncludingSuccession []any `json:"factorListIncludingSuccession"`
|
||||
SuccessionCharaList []SuccessionCharaList `json:"successionCharaList"`
|
||||
IsSuccessionHistoryInitialized bool `json:"isSuccessionHistoryInitialized"`
|
||||
SuccessionHistoryList []any `json:"successionHistoryList"`
|
||||
AcquiredSkillArray []AcquiredSkillArray `json:"acquiredSkillArray"`
|
||||
SupportCardArray []SupportCardArray `json:"supportCardArray"`
|
||||
SingleModeRaceResultArray []SingleModeRaceResultArray `json:"singleModeRaceResultArray"`
|
||||
WinSaddleArray []any `json:"winSaddleArray"`
|
||||
WinSaddleIDArray []int `json:"winSaddleIdArray"`
|
||||
CacheCharaID int `json:"cacheCharaId"`
|
||||
MasterCardData MasterCardData `json:"masterCardData"`
|
||||
MasterCharaData MasterCharaData `json:"masterCharaData"`
|
||||
MasterCardRarityData MasterCardRarityData `json:"masterCardRarityData"`
|
||||
SingleTotalRaceNum int `json:"singleTotalRaceNum"`
|
||||
SingleWinNum int `json:"singleWinNum"`
|
||||
TrainedCharaDataAccessor TrainedCharaDataAccessor `json:"trainedCharaDataAccessor"`
|
||||
}
|
||||
type PlayerTeamMember struct {
|
||||
HorseIndex int `json:"horseIndex"`
|
||||
PostNumber int `json:"postNumber"`
|
||||
CharaID int `json:"charaId"`
|
||||
CharaName string `json:"charaName"`
|
||||
FinishOrder int `json:"finishOrder"`
|
||||
FinishTimeRaw float32 `json:"finishTimeRaw"`
|
||||
FinishTimeScaled float32 `json:"finishTimeScaled"`
|
||||
FinishDiffTimeFromPrev float32 `json:"finishDiffTimeFromPrev"`
|
||||
RaceParam RaceParam `json:"raceParam"`
|
||||
ResponseHorseData ResponseHorseData `json:"responseHorseData"`
|
||||
Popularity int `json:"popularity"`
|
||||
PopularityRankLeft int `json:"popularityRankLeft"`
|
||||
PopularityRankCenter int `json:"popularityRankCenter"`
|
||||
PopularityRankRight int `json:"popularityRankRight"`
|
||||
GateInPopularity int `json:"gateInPopularity"`
|
||||
Rarity string `json:"rarity"`
|
||||
TrainerName string `json:"trainerName"`
|
||||
IsGhost bool `json:"isGhost"`
|
||||
IsRunningStyleExInitialized bool `json:"isRunningStyleExInitialized"`
|
||||
RunningStyleEx string `json:"runningStyleEx"`
|
||||
Defeat string `json:"defeat"`
|
||||
RaceDressID int `json:"raceDressId"`
|
||||
RaceDressIDWithOption int `json:"raceDressIdWithOption"`
|
||||
RunningType string `json:"runningType"`
|
||||
ActiveProperDistance string `json:"activeProperDistance"`
|
||||
ActiveProperGroundType string `json:"activeProperGroundType"`
|
||||
MobID int `json:"mobId"`
|
||||
RaceRecord RaceRecord `json:"raceRecord"`
|
||||
FinishOrderRawScore int `json:"finishOrderRawScore"`
|
||||
TrainedCharaData TrainedCharaData `json:"trainedCharaData"`
|
||||
}
|
||||
type PlayerTeamTopFinishOrderHorse struct {
|
||||
HorseIndex int `json:"horseIndex"`
|
||||
PostNumber int `json:"postNumber"`
|
||||
CharaID int `json:"charaId"`
|
||||
CharaName string `json:"charaName"`
|
||||
FinishOrder int `json:"finishOrder"`
|
||||
FinishTimeRaw float32 `json:"finishTimeRaw"`
|
||||
FinishTimeScaled float32 `json:"finishTimeScaled"`
|
||||
FinishDiffTimeFromPrev float32 `json:"finishDiffTimeFromPrev"`
|
||||
RaceParam RaceParam `json:"raceParam"`
|
||||
ResponseHorseData ResponseHorseData `json:"responseHorseData"`
|
||||
Popularity int `json:"popularity"`
|
||||
PopularityRankLeft int `json:"popularityRankLeft"`
|
||||
PopularityRankCenter int `json:"popularityRankCenter"`
|
||||
PopularityRankRight int `json:"popularityRankRight"`
|
||||
GateInPopularity int `json:"gateInPopularity"`
|
||||
Rarity string `json:"rarity"`
|
||||
TrainerName string `json:"trainerName"`
|
||||
IsGhost bool `json:"isGhost"`
|
||||
IsRunningStyleExInitialized bool `json:"isRunningStyleExInitialized"`
|
||||
RunningStyleEx string `json:"runningStyleEx"`
|
||||
Defeat string `json:"defeat"`
|
||||
RaceDressID int `json:"raceDressId"`
|
||||
RaceDressIDWithOption int `json:"raceDressIdWithOption"`
|
||||
RunningType string `json:"runningType"`
|
||||
ActiveProperDistance string `json:"activeProperDistance"`
|
||||
ActiveProperGroundType string `json:"activeProperGroundType"`
|
||||
MobID int `json:"mobId"`
|
||||
RaceRecord RaceRecord `json:"raceRecord"`
|
||||
FinishOrderRawScore int `json:"finishOrderRawScore"`
|
||||
TrainedCharaData TrainedCharaData `json:"trainedCharaData"`
|
||||
}
|
||||
|
||||
type RaceHorse struct {
|
||||
HorseIndex int `json:"horseIndex"`
|
||||
PostNumber int `json:"postNumber"`
|
||||
CharaID int `json:"charaId"`
|
||||
CharaName string `json:"charaName"`
|
||||
FinishOrder int `json:"finishOrder"`
|
||||
FinishTimeRaw float32 `json:"finishTimeRaw"`
|
||||
FinishTimeScaled float32 `json:"finishTimeScaled"`
|
||||
FinishDiffTimeFromPrev float32 `json:"finishDiffTimeFromPrev"`
|
||||
RaceParam RaceParam `json:"raceParam"`
|
||||
ResponseHorseData ResponseHorseData `json:"responseHorseData"`
|
||||
Popularity int `json:"popularity"`
|
||||
PopularityRankLeft int `json:"popularityRankLeft"`
|
||||
PopularityRankCenter int `json:"popularityRankCenter"`
|
||||
PopularityRankRight int `json:"popularityRankRight"`
|
||||
GateInPopularity int `json:"gateInPopularity"`
|
||||
Rarity string `json:"rarity"`
|
||||
TrainerName string `json:"trainerName"`
|
||||
IsGhost bool `json:"isGhost"`
|
||||
IsRunningStyleExInitialized bool `json:"isRunningStyleExInitialized"`
|
||||
RunningStyleEx string `json:"runningStyleEx"`
|
||||
Defeat string `json:"defeat"`
|
||||
RaceDressID int `json:"raceDressId"`
|
||||
RaceDressIDWithOption int `json:"raceDressIdWithOption"`
|
||||
RunningType string `json:"runningType"`
|
||||
ActiveProperDistance string `json:"activeProperDistance"`
|
||||
ActiveProperGroundType string `json:"activeProperGroundType"`
|
||||
MobID int `json:"mobId"`
|
||||
RaceRecord RaceRecord `json:"raceRecord"`
|
||||
FinishOrderRawScore int `json:"finishOrderRawScore"`
|
||||
TrainedCharaData TrainedCharaData `json:"trainedCharaData,omitempty"`
|
||||
}
|
||||
|
||||
type RaceRewardSingle struct {
|
||||
// TODO(zeph): this
|
||||
}
|
||||
|
||||
type CharaGradeType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type CharaGradeType -linecomment -trimprefix CharaGrade
|
||||
const (
|
||||
CharaGradeNone CharaGradeType = iota // NONE
|
||||
CharaGradeDebut
|
||||
CharaGradeNoWin
|
||||
CharaGradeOpen
|
||||
CharaGradeG3Silver
|
||||
CharaGradeG3Gold
|
||||
CharaGradeG2Silver
|
||||
CharaGradeG2Gold
|
||||
CharaGradeG1Bronze
|
||||
CharaGradeG1Silver
|
||||
CharaGradeG1Gold
|
||||
|
||||
charaGradeMax
|
||||
)
|
||||
|
||||
func (r CharaGradeType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r CharaGradeType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var charaGradeNames = sync.OnceValue(func() map[string]CharaGradeType {
|
||||
m := make(map[string]CharaGradeType, raceTypeMaxInclusive)
|
||||
for r := CharaGradeNone; r < charaGradeMax; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "CharaGradeType(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *CharaGradeType) UnmarshalText(b []byte) error {
|
||||
n, ok := charaGradeNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown chara grade type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MainStoryRaceGimmickType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type MainStoryRaceGimmickType -linecomment
|
||||
const (
|
||||
GimmickNone MainStoryRaceGimmickType = iota // NONE
|
||||
GimmickSpecial00 // Special_00
|
||||
|
||||
gimmickMax
|
||||
)
|
||||
|
||||
func (r MainStoryRaceGimmickType) AppendText(b []byte) ([]byte, error) {
|
||||
return append(b, r.String()...), nil
|
||||
}
|
||||
|
||||
func (r MainStoryRaceGimmickType) MarshalText() ([]byte, error) {
|
||||
return r.AppendText(nil)
|
||||
}
|
||||
|
||||
var mainStoryGimmickNames = sync.OnceValue(func() map[string]MainStoryRaceGimmickType {
|
||||
m := make(map[string]MainStoryRaceGimmickType, raceTypeMaxInclusive)
|
||||
for r := GimmickNone; r < gimmickMax; r++ {
|
||||
s := r.String()
|
||||
if strings.HasPrefix(s, "MainStoryRaceGimmickType(") {
|
||||
continue
|
||||
}
|
||||
m[r.String()] = r
|
||||
}
|
||||
return m
|
||||
})
|
||||
|
||||
func (r *MainStoryRaceGimmickType) UnmarshalText(b []byte) error {
|
||||
n, ok := mainStoryGimmickNames()[string(b)]
|
||||
*r = n
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown main story race gimmick type %q", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type ResultBoardConditionType -linecomment"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[ResultBoardTurfNone-1]
|
||||
_ = x[ResultBoardTurfDirt-2]
|
||||
_ = x[ResultBoardDirtNone-3]
|
||||
_ = x[ResultBoardDirtTurf-4]
|
||||
}
|
||||
|
||||
const _ResultBoardConditionType_name = "Turf_NoneTurf_DirtDirt_NoneDirt_Turf"
|
||||
|
||||
var _ResultBoardConditionType_index = [...]uint8{0, 9, 18, 27, 36}
|
||||
|
||||
func (i ResultBoardConditionType) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_ResultBoardConditionType_index)-1 {
|
||||
return "ResultBoardConditionType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _ResultBoardConditionType_name[_ResultBoardConditionType_index[idx]:_ResultBoardConditionType_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type Rotation -trimprefix Rotation"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[RotationRight-1]
|
||||
_ = x[RotationLeft-2]
|
||||
_ = x[RotationStraightRight-3]
|
||||
_ = x[RotationStraightLeft-4]
|
||||
}
|
||||
|
||||
const _Rotation_name = "RightLeftStraightRightStraightLeft"
|
||||
|
||||
var _Rotation_index = [...]uint8{0, 5, 9, 22, 34}
|
||||
|
||||
func (i Rotation) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_Rotation_index)-1 {
|
||||
return "Rotation(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Rotation_name[_Rotation_index[idx]:_Rotation_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated by "stringer -type Season -trimprefix Season"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[SeasonMin-0]
|
||||
_ = x[SeasonSpring-1]
|
||||
_ = x[SeasonSummer-2]
|
||||
_ = x[SeasonFall-3]
|
||||
_ = x[SeasonWinter-4]
|
||||
_ = x[SeasonCherryBlossom-5]
|
||||
_ = x[SeasonMax-6]
|
||||
}
|
||||
|
||||
const _Season_name = "MinSpringSummerFallWinterCherryBlossomMax"
|
||||
|
||||
var _Season_index = [...]uint8{0, 3, 9, 15, 19, 25, 38, 41}
|
||||
|
||||
func (i Season) String() string {
|
||||
idx := int(i) - 0
|
||||
if i < 0 || idx >= len(_Season_index)-1 {
|
||||
return "Season(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Season_name[_Season_index[idx]:_Season_index[idx+1]]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type TurfVisionType -trimprefix TurfVision"; DO NOT EDIT.
|
||||
|
||||
package replay
|
||||
|
||||
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[TurfVisionURA-1]
|
||||
_ = x[TurfVisionNAU-2]
|
||||
_ = x[TurfVisionStand-3]
|
||||
_ = x[turfVisionMax-4]
|
||||
}
|
||||
|
||||
const _TurfVisionType_name = "URANAUStandturfVisionMax"
|
||||
|
||||
var _TurfVisionType_index = [...]uint8{0, 3, 6, 11, 24}
|
||||
|
||||
func (i TurfVisionType) String() string {
|
||||
idx := int(i) - 1
|
||||
if i < 1 || idx >= len(_TurfVisionType_index)-1 {
|
||||
return "TurfVisionType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _TurfVisionType_name[_TurfVisionType_index[idx]:_TurfVisionType_index[idx+1]]
|
||||
}
|
||||
@@ -49,11 +49,16 @@ export function convoCharas(c: Conversation): number[] {
|
||||
|
||||
export function requiredCharas(c: Conversation): number[] {
|
||||
switch (c.condition_type) {
|
||||
case Required.None: return []
|
||||
case Required.All: return convoCharas(c);
|
||||
case Required.Chara1: return [c.chara_1];
|
||||
case Required.Chara2: return [c.chara_2!];
|
||||
case Required.Chara3: return [c.chara_3!];
|
||||
case Required.None:
|
||||
return [];
|
||||
case Required.All:
|
||||
return convoCharas(c);
|
||||
case Required.Chara1:
|
||||
return [c.chara_1];
|
||||
case Required.Chara2:
|
||||
return [c.chara_2!];
|
||||
case Required.Chara3:
|
||||
return [c.chara_3!];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1143,22 +1143,14 @@
|
||||
>. (This race is why I made it.)
|
||||
</p>
|
||||
|
||||
<Sec h={3} id="jbc-sprint">JBC Sprint (Ooi ver.)</Sec>
|
||||
<p>
|
||||
An even more anti-front track is Ooi 1200 Dirt. This one is actively malicious. Visually, it looks like late race starts on a
|
||||
corner, but the portion before the stretch is a special <i>neither corner nor straight</i> property. That means Angling won't activate,
|
||||
and VPP is delayed (though still within the accel period).
|
||||
</p>
|
||||
<p>
|
||||
Fortunately, JBC Sprint is after summer, which means you should be able to stat diff your opponents. If you are planning to
|
||||
win this race, you may want to prioritize a bit of extra speed training, or take Front Straights/Corners. If MANT, don't be
|
||||
too surprised if you lose a clock or five to a Taiki Shuttle rival.
|
||||
</p>
|
||||
<p>
|
||||
Since the 1 Jul update, the JBC races take place at a randomly selected one of the NAR courses (Ooi, Kawasaki, Funabashi,
|
||||
Morioka) each year. If you're hunting for a completionist title on a front runner, you have the option of just not picking an
|
||||
Ooi JBC Sprint; the others are all Angling tracks.
|
||||
</p>
|
||||
<div id="jbc-sprint" class="hidden target:block">
|
||||
<h3>JBC Sprint</h3>
|
||||
<p>
|
||||
It used to be the case that Oi 1200 Dirt had a strange neither-straight-nor-corner segment at the start of late race so that
|
||||
Angling wouldn't activate. As of the 1 Jul update, the corner is now connected to the final straight, so there is no longer
|
||||
anything remarkable about this track.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Sec h={3} id="3k">Kikuka Sho & Tenno Sho (Spring)</Sec>
|
||||
<p>
|
||||
|
||||
@@ -17,8 +17,107 @@
|
||||
}
|
||||
});
|
||||
|
||||
const raceGroups = [
|
||||
[1, 'Common'],
|
||||
[2, 'Daily Race'],
|
||||
[3, '"Training Practice"'],
|
||||
[4, '"Story Condition"'],
|
||||
[5, '"Team Building"'],
|
||||
[6, 'Practice'],
|
||||
[7, 'Career-Exclusive'],
|
||||
[8, 'Legend Race'],
|
||||
[9, 'Team Trials'],
|
||||
[10, 'Unity Cup Team Race'],
|
||||
[11, "Champions' Meet"],
|
||||
[12, 'Room Match'],
|
||||
[13, '"Challenge Match"'],
|
||||
[14, 'League of Heroes Race'],
|
||||
[61, 'Custom G1'],
|
||||
] as const;
|
||||
|
||||
const raceGrades = [
|
||||
[100, 'G1'],
|
||||
[200, 'G2'],
|
||||
[300, 'G3'],
|
||||
[400, 'OP'],
|
||||
[700, 'Pre-OP'],
|
||||
[800, 'Maiden'],
|
||||
[900, 'Debut'],
|
||||
[999, 'Daily Race or Room Match (?)'],
|
||||
[1000, 'Unity Cup Team Race (?)'],
|
||||
] as const;
|
||||
|
||||
const raceTimes = [
|
||||
[1, 'Morning (unused)'],
|
||||
[2, 'Daytime'],
|
||||
[3, 'Evening'],
|
||||
[4, 'Night'],
|
||||
] as const;
|
||||
|
||||
const raceInitialLanes = [
|
||||
[1, 9, 0.03333333],
|
||||
[2, 0, 0],
|
||||
[3, 14, 0.10333333],
|
||||
[4, 8, 0.03333333],
|
||||
] as const;
|
||||
|
||||
const raceAreas = [
|
||||
[0, 'Hokkaido'],
|
||||
[1, 'Tohoku'],
|
||||
[2, 'Kanto'],
|
||||
[3, 'Western Japan'],
|
||||
[4, 'Kokura'],
|
||||
[5, 'France'],
|
||||
[6, 'America'],
|
||||
] as const;
|
||||
|
||||
const raceLoops = [
|
||||
[1, 'None'],
|
||||
[2, 'Inner'],
|
||||
[3, 'Outer'],
|
||||
[4, 'Outer→Inner'],
|
||||
] as const;
|
||||
|
||||
const raceRotations = [
|
||||
[1, 'Right'],
|
||||
[2, 'Left'],
|
||||
[3, 'Rightward Stretch (unused)'],
|
||||
[4, 'Leftward Stretch'],
|
||||
] as const;
|
||||
|
||||
const raceCourseThresholds = [
|
||||
[1, 1, 0],
|
||||
[2, 2, 0],
|
||||
[3, 3, 0],
|
||||
[4, 4, 0],
|
||||
[5, 5, 0],
|
||||
[6, 1, 2],
|
||||
[7, 2, 3],
|
||||
[8, 2, 4],
|
||||
[9, 3, 5],
|
||||
[10, 2, 5],
|
||||
[11, 4, 5],
|
||||
] as const;
|
||||
|
||||
const raceSaddleTypes = [
|
||||
[0, 'Special'],
|
||||
[1, 'G3'],
|
||||
[2, 'G2'],
|
||||
[3, 'G1'],
|
||||
] as const;
|
||||
|
||||
const racePermissions = [
|
||||
[1, 'Junior'],
|
||||
[2, 'Classic'],
|
||||
[3, 'Classic and Senior'],
|
||||
[4, 'Senior'],
|
||||
[5, 'Finale'],
|
||||
] as const;
|
||||
|
||||
const skills = $derived({
|
||||
rickey: skillMap.get(100981),
|
||||
right1: skillMap.get(200012),
|
||||
left1: skillMap.get(200022),
|
||||
fall2: skillMap.get(200191),
|
||||
fall1: skillMap.get(200192),
|
||||
fallX: skillMap.get(200193),
|
||||
@@ -299,6 +398,10 @@
|
||||
in-game shows a "Connecting..." indicator while it loads, it probably isn't in the mdb. Notably, this includes everything
|
||||
related to career event outcomes. (Event information on sites like GameTora and GameWith are massive crowd-sourced efforts.)
|
||||
</p>
|
||||
<p>Since I see this question about weekly, allow me to reiterate.</p>
|
||||
<p class="text-4xl font-bold">
|
||||
Support card event outcomes are not in master.mdb or any other locally stored file. Not even the list of possible skills.
|
||||
</p>
|
||||
<p>
|
||||
This document is oriented toward programmers with understanding of SQL databases. Mentions of <Mono>Gallop::</Mono> are references
|
||||
to types visible in decompilations of the game, but no C# knowledge is needed.
|
||||
@@ -330,6 +433,363 @@
|
||||
>, but a few categories that have useful strings are missing from there.
|
||||
</p>
|
||||
|
||||
<Sec h={2} id="race">Races</Sec>
|
||||
<p>First, some terminology, as the game uses it internally. (Some UI phrasing disagrees.)</p>
|
||||
<p>
|
||||
A <i>race</i> is an organized running competition, typically held annually. A <i>race instance</i> is a single holding of a
|
||||
race at a specific date and time; this includes special race instances like Team Trials races, Aim for the Stars races,
|
||||
&c. Race instances are held on a given <i>race course</i>, which is a fixed-length segment of a physical location called a
|
||||
<i>race track</i>. A <i>win saddle</i> is a given horse's victory of a race or a specific group of races, e.g. Classic Triple Crown
|
||||
or Dual Grand Prix. This section will cover races, race instances, race tracks, race courses, and win saddles.
|
||||
</p>
|
||||
<p>
|
||||
<Mono>text_data</Mono> categories relevant to races include:
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li>32 and 33 are both race names, the latter for jikkyo (the announcer's lines).</li>
|
||||
<li>
|
||||
28 is race instance names. 29 is abbreviated race instance names, e.g. <Mono>Mile Ch.</Mono> instead of <Mono
|
||||
>Mile Championship</Mono
|
||||
>.
|
||||
</li>
|
||||
<li>
|
||||
31 and 34 are race track full names, the former for jikkyo, e.g. <Mono>Kyoto Racecourse</Mono>. 35 is race track names
|
||||
without "Racecourse".
|
||||
</li>
|
||||
<li>111 is win saddle names.</li>
|
||||
</ul>
|
||||
|
||||
<Sec h={3} id="race-race">Race Info</Sec>
|
||||
<p>
|
||||
Races are defined in <Mono>race</Mono>, which is quite a direct name innit.
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li>
|
||||
Race ID is just <Mono>id</Mono>.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>group</Mono> is the game situation where the race occurs.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">Group</th>
|
||||
<th scope="col" class="px-2">Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceGroups as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
<li>
|
||||
<Mono>grade</Mono> defines the race grade.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">Grade ID</th>
|
||||
<th scope="col" class="px-2">Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceGrades as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
<li><Mono>course_set</Mono> gives the <a href="#race-course">race course</a> where the race occurs.</li>
|
||||
<li><Mono>thumbnail_id</Mono> is the resource ID of the race's thumbnail image.</li>
|
||||
<li><Mono>entry_num</Mono> is the maximum number of horses that can run the race.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Some races are ostensibly defined twice to account for variant races run during some characters' careers, e.g. Maruzensky's
|
||||
five opponent Spring Stakes, McQueen/Ryan/Rice's Kyoto Takarazuka Kinen, &c.
|
||||
</p>
|
||||
|
||||
<Sec h={3} id="race-instances">Race Instances</Sec>
|
||||
<p>
|
||||
The table is <Mono>race_instance</Mono>.
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li><Mono>id</Mono> is the race instance ID.</li>
|
||||
<li><Mono>race_id</Mono> joins with <Mono>race.id</Mono>.</li>
|
||||
<li>
|
||||
<Mono>npc_group_id</Mono> should define the NPC racers allowed to appear in the race instance, although I haven't looked into
|
||||
it.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>date</Mono> gives the month and day-of-month when the race instance occurs, expressed as M×100+d – 1 Jan is
|
||||
101 and 31 Dec is 1231. This appears to decide the season that the race instance occurs in and thus the applicable green skill.
|
||||
E.g., we can see in career that Challenge Cup is offered on the Early December turn, but its race instance has a <Mono
|
||||
>date</Mono
|
||||
> of 1130 (i.e. 30 Nov), so it is a fall rather than winter race. All races occur in 2019.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>time</Mono> is the time of day that the race instance is held.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">Time</th>
|
||||
<th scope="col" class="px-2">Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceTimes as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
<li>
|
||||
<Mono>clock_time</Mono> has a value of 1605 for one race and is otherwise always 0. It might be a specific hour and minute that
|
||||
a race instance occurs, but I'm not sure why that would ever matter.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>race_number</Mono> takes every value between -1 and 12, but I couldn't find any explanation for it.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Similarly to races, some race instances are ostensibly defined twice to account for variant races run during some characters'
|
||||
careers.
|
||||
</p>
|
||||
|
||||
<Sec h={3} id="race-track">Race Tracks</Sec>
|
||||
<p>
|
||||
Since race tracks are the physical locations where races are held, there are not many rows in <Mono>race_track</Mono>. Most of
|
||||
its purpose is to define appearance characteristics, but some fields are mechanically relevant.
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li><Mono>id</Mono> is the race track ID.</li>
|
||||
<li>
|
||||
<Mono>initial_lane_type</Mono> describes the starting lane positions of each horse by determining the location and width of the
|
||||
gap between posts.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Gap After Gate</th>
|
||||
<th scope="col" class="px-2">Gap Width (CW)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceInitialLanes as [id, gate, w] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td>{id}</td>
|
||||
<td>{gate}</td>
|
||||
<td>{w}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
Horses in gates
|
||||
<i>after</i> the Gap After Gate listed in this table have the gap width added to their starting lane.
|
||||
<Mono>initial_lane_type</Mono> is 2 on Oi, Kawasaki, and Funabashi; 3 on Longchamp; 4 on Morioka; and 1 elsewhere. (The race mechanics
|
||||
doc's
|
||||
<a
|
||||
href="https://docs.google.com/document/d/15VzW9W2tXBBTibBRbZ8IVpW6HaMX8H0RP03kq6Az7Xg/edit?tab=t.0#heading=h.ohdxzwro17n5"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">description of initial lane</a
|
||||
>
|
||||
uses horse index rather than gate number and describes lanes in units of horse lanes rather than course widths.)
|
||||
</li>
|
||||
<li>
|
||||
<Mono>area</Mono> defines the geographic region where the race track exists.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Region</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceAreas as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Sec h={3} id="race-course">Race Courses</Sec>
|
||||
<p>
|
||||
Race courses are physical segments of race tracks. They are defined in <Mono>race_course_set</Mono>.
|
||||
</p>
|
||||
<p>
|
||||
Most tracks have one or two turf loops (the "(Inner)" and "(Outer)" or sometimes "(Outer→Inner)") and one dirt loop. The
|
||||
length of a race course is determined solely by the position of the gates: since the race course is a physical structure with
|
||||
the audience stands in a specific location, and since said audience wants to see the race finish clearly, courses of all
|
||||
lengths end at the same place on the front stretch. The straight opposite the front stretch is called the backstretch. Corners
|
||||
are counted backward from the front stretch in the order 4, 3, 2, 1; all races except Ibis Summer Dash include corners 3 and
|
||||
4, while long and sometimes medium races run corners multiple times. Some courses start on an extra segment of the track which
|
||||
is <i>neither straight nor corner</i> (which means <Mono>straight_random==1</Mono> skills won't fire there).
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li><Mono>id</Mono> gives the race course ID.</li>
|
||||
<li><Mono>race_track_id</Mono> joins with <Mono>race_track.id</Mono>.</li>
|
||||
<li><Mono>distance</Mono> is the race course length in meters.</li>
|
||||
<li><Mono>ground</Mono> is 1 for turf and 2 for dirt.</li>
|
||||
<li>
|
||||
<Mono>inout</Mono> gives the loop for the surface type where the race occurs.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Loop</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceLoops as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
<li>
|
||||
<Mono>turn</Mono> gives the handedness of the track, i.e. the direction from horses to the rail as they round the track's corners.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Handedness</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceRotations as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
Stretch types have no corners and do not activate <Skill skill={skills.right1} /> or <Skill skill={skills.left1} /> or their variants.
|
||||
Niigata 1000 is the only such race course in the game.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>float_lane_max</Mono> gives the <i>initial</i> race course width in units of ten thousandths of course widths. (Confusingly,
|
||||
no race course has a width of 1 course width.) Some race courses have locations where the lane max changes, but these are defined
|
||||
as events and are not in the mdb.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>course_set_status_id</Mono> joins with <Mono>race_course_set_status.course_set_status_id</Mono> to define the stat thresholds.
|
||||
A value of 0 means no thresholds.
|
||||
<table class="table-fixed border text-center">
|
||||
<caption><Mono>race_course_set_status</Mono></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2"><Mono>course_set_status_id</Mono></th>
|
||||
<th scope="col" class="px-2"><Mono>target_status_1</Mono></th>
|
||||
<th scope="col" class="px-2"><Mono>target_status_2</Mono></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceCourseThresholds as [id, stat1, stat2] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{stat1}</td>
|
||||
<td class="px-2">{stat2}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
Status of 1 is Speed, 2 is Power, and so on up to 5 for Wit. 0 means no (second) threshold.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Characteristics like straight and corner locations, slopes, lane max changes, &c. are <i>not</i> in the mdb. They are defined
|
||||
as assets instead and must be extracted using special tools.
|
||||
</p>
|
||||
|
||||
<Sec h={3} id="race-saddle">Win Saddles</Sec>
|
||||
<p>
|
||||
<Mono>single_mode_wins_saddle</Mono> defines the awards given to the horse (not the player) for winning a race or specific group
|
||||
of races. These are the medals displayed as important wins for a horse at the end of a career. They are now purely aesthetic, but
|
||||
I am documenting them anyway because I have the notes already since they used to determine affinity.
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li><Mono>id</Mono> is the win saddle ID.</li>
|
||||
<li><Mono>priority</Mono> is the sort order for win saddles.</li>
|
||||
<li>
|
||||
<Mono>group_id</Mono> associates multiple win saddles for the same race, for horses whose careers have special versions of some
|
||||
races.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>win_saddle_type</Mono> is the type of the win saddle, used to determine the color of the medal displayed.
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each raceSaddleTypes as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
Special win saddles are for win saddles requiring multiple wins, e.g. Classic Triple Crown.
|
||||
</li>
|
||||
<li>
|
||||
<Mono>race_instance_id_1</Mono> through <Mono>race_instance_id_8</Mono> define the race instance IDs that must be won to be awarded
|
||||
the win saddle. Columns beyond <Mono>race_instance_id_3</Mono> are unused.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Sec h={3} id="race-program">Single Mode Program</Sec>
|
||||
<p>
|
||||
The table <Mono>single_mode_program</Mono> defines the race instances offered each turn in a career. Confusingly, races that permit
|
||||
both classic and senior year horses are only defined here once.
|
||||
</p>
|
||||
<ul class="ml-4 list-disc pb-4">
|
||||
<li><Mono>race_instance_id</Mono> joins with <Mono>race_instance.id</Mono>.</li>
|
||||
<li>
|
||||
<Mono>race_permission</Mono> gives the career years that offer the race. (More precisely, it gives the age ranges of horses that
|
||||
are permitted to enter.)
|
||||
<table class="table-fixed border text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="px-2">ID</th>
|
||||
<th scope="col" class="px-2">Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each racePermissions as [id, name] (id)}
|
||||
<tr class="even:bg-mist-300 dark:even:bg-mist-900">
|
||||
<td class="px-2">{id}</td>
|
||||
<td class="px-2">{name}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
<li><Mono>month</Mono> and <Mono>half</Mono> give the turn that the race is held.</li>
|
||||
</ul>
|
||||
<p>
|
||||
I was unable to identify whether any of the columns indicate maiden races, despite the UI restrictions on when they can
|
||||
appear.
|
||||
</p>
|
||||
|
||||
<Sec h={2} id="skills">Skills</Sec>
|
||||
<p>
|
||||
Relevant <Mono>text_data</Mono> categories include 47 for skill names and 48 for skill descriptions. Otherwise, info for skills
|
||||
@@ -816,6 +1276,9 @@
|
||||
Relevant <Mono>text_data</Mono> categories include 75 for name including variant, 76 for variant alone, 77 for character name. Category
|
||||
151 gives support card effect names, 154 gives effect descriptions, 150 gives unique effect names, and 155 gives unique effect descriptions.
|
||||
</p>
|
||||
<p class="text-4xl font-bold">
|
||||
Support card event outcomes are not in master.mdb or any other locally stored file. Not even the list of possible skills.
|
||||
</p>
|
||||
|
||||
<Sec h={3} id="support_card_data">Support Card Data</Sec>
|
||||
<p>
|
||||
|
||||
Reference in New Issue
Block a user