~moody/pse

pse/trainer.go -rw-r--r-- 2.9 KiB
e4de17d5 — Jacob Moody Introduce pse(1) 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package pse

import (
	"fmt"
	"strings"
)

type TrainerInfo struct {
	Name         *PkString
	Gender       byte
	ID           uint16
	SecretID     uint16
	HoursPlayed  uint16
	MinPlayed    byte
	SecPlayed    byte
	FramePlayed  byte
	ButtonOption byte
	TextOption   byte
	MiscOption   byte
	//For emerald the gamecode section is the SecurityKey
	GameCode    uint32
	SecurityKey uint32

	//Underlying section
	data *Section
}

func NewTrainerInfo(s *Section) (*TrainerInfo, error) {
	var err error
	ti := &TrainerInfo{}
	ti.Name, err = NewPkString(s.data[:7], LangEN)
	if err != nil {
		return nil, err
	}
	ti.Gender = s.data[8]
	ti.ID = get2(s.data[0xA:0xC])
	ti.SecretID = get2(s.data[0xC:0xE])
	ti.HoursPlayed = get2(s.data[0xE:0x10])
	ti.MinPlayed = s.data[0x10]
	ti.SecPlayed = s.data[0x11]
	ti.FramePlayed = s.data[0x12]
	ti.ButtonOption = s.data[0x13]
	ti.TextOption = s.data[0x14]
	ti.MiscOption = s.data[0x15]
	ti.GameCode = get4(s.data[0xAC:0xB0])
	if ti.GameCode == 1 {
		ti.SecurityKey = get4(s.data[0xF20:])
	}
	ti.data = s
	return ti, nil
}

func (ti *TrainerInfo) Commit() error {
	s := ti.data
	err := ti.Name.Commit(LangEN)
	if err != nil {
		return err
	}
	s.data[8] = ti.Gender
	put2(ti.ID, s.data[0xA:0xC])
	put2(ti.SecretID, s.data[0xC:0xE])
	put2(ti.HoursPlayed, s.data[0xE:0x10])
	s.data[0x10] = ti.MinPlayed
	s.data[0x11] = ti.SecPlayed
	s.data[0x12] = ti.FramePlayed
	s.data[0x13] = ti.ButtonOption
	s.data[0x14] = ti.TextOption
	s.data[0x15] = ti.MiscOption
	put4(ti.GameCode, s.data[0xAC:0xB0])
	if ti.GameCode == 1 {
		put4(ti.SecurityKey, s.data[0xF20:])
	}
	ti.data.Commit()
	return nil
}

func (ti *TrainerInfo) GenderString() string {
	if ti.Gender == 0 {
		return "male"
	} else {
		return "female"
	}
}

func (ti *TrainerInfo) String() string {
	var b strings.Builder
	fmt.Fprintf(&b, "Name: %s\n", ti.Name.string)
	fmt.Fprintf(&b, "Gender: %s\n", ti.GenderString())
	fmt.Fprintf(&b, "Time Played: %v-%v-%v-%v\n", ti.HoursPlayed, ti.MinPlayed, ti.SecPlayed, ti.FramePlayed)
	fmt.Fprintf(&b, "Trainer ID: %v\n", ti.ID)
	fmt.Fprintf(&b, "Secret ID: %v\n", ti.SecretID)
	switch ti.GameCode {
	case 0:
		fmt.Fprint(&b, "Game: Ruby/Sapphire")
	case 1:
		fmt.Fprintf(&b, "Game: FireRed/LeafGreen\nSecurity Key: %v", ti.SecurityKey)
	default:
		fmt.Fprintf(&b, "Game: Emerald\nSecurity Key: %v", ti.GameCode)
	}
	return b.String()
}

func (ti *TrainerInfo) Format(f fmt.State, verb rune) {
	switch verb {
	case 'v':
		fmt.Fprint(f, ti.String())
	case 'a':
		fmt.Fprintf(f, "%s\t%s\t%v\t%v\t%v\t%v\t%v\t%v", ti.Name.string, ti.GenderString(),
			ti.HoursPlayed, ti.MinPlayed, ti.SecPlayed, ti.FramePlayed,
			ti.ID, ti.SecretID)
	}
}

func (ti *TrainerInfo) Scan(state fmt.ScanState, verb rune) error {
	var gender string
	_, err := fmt.Fscanln(state, &ti.Name.string, &gender,
		&ti.HoursPlayed, &ti.MinPlayed, &ti.SecPlayed, &ti.FramePlayed,
		&ti.ID, &ti.SecretID)
	switch gender {
	case "male":
		ti.Gender = 0
	case "female":
		ti.Gender = 1
	}
	return err
}