-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathget_player_data.py
145 lines (118 loc) · 3.45 KB
/
get_player_data.py
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from collections import Counter
import dataclass
class BoxCard(dataclass.DataClass):
"A card in a player's box."
fields = [
'chr', #0. Internal (chronological) ID.
# Change to id? We do need lookup by ID.
'xp',
'lv',
'slv',
'fuses', #4. Useless.
'cid', #5. Monster ID. (Can I change this to id?)
'plus_hp',
'plus_atk',
'plus_rcv',
'tamas', #9. Number of tamas (up to 10)
# Newer:
'latbits', #10. Packed bits representing latents.
'inherit', #11. Inherit's CHR
'saplus', #12. Super Awakening plus progress.
'sawkn', #13. Super Awakening.
'_unk14',
]
__slots__ = fields #Should I slots here?
defaults = [0]*len(fields) #for now.
properties = {
'plusses': lambda m: m.plus_hp + m.plus_atk + m.plus_rcv,
'latents': lambda m: unpack_latents(m.latbits),
}
def __init__(self, raw):
# for name, value in zip(self.fields, raw):
# setattr(self, name, value)
# Pad with 0s.
#? Maybe handle defaults in DataClass
raw.extend(self.defaults[len(raw):])
super().__init__(raw)
# Need to override DataClass's repr.
def __repr__(self):
return '%s<%r, %r>' % (type(self).__name__, self.chr, self.cid)
# def unpack_latent(latent):
# bits = bin(latent)[2:]
# parts = []
# for i in range(0, -25, -5):
# parts.append(int(bits[-9+i:-4+i] or '0', 2))
# #print parts
# return parts
# def unpack_latents(latents):
# if not latents:
# return (0,0,0,0,0)
# bits = bin(latents)[2:-4].zfill(25)
# parts = []
# for i in range(0, -25, -5):
# parts.append(int(bits[-9+i:-4+i] or '0', 2))
# #print parts
# return parts
# def unpack_latents(raw):
# if not raw:
# return (0,0,0,0,0)
# raw //= 0x10
# latents = []
# for _ in range(5):
# raw, lat = divmod(raw, 0x20)
# latents.append(lat)
# return latents
# def repack_latents(latents):
# # Test for order:
# # repack_latents([5, 5, 3, 2, 1])
# # => 17877589
# if not any(latents):
# return 0
# raw = 0
# for latent in reversed(latents):
# raw = raw * 0x20 + latent
# raw = raw * 0x10 + 5
# return raw
# def repack_latents(latents):
# if not any(latents):
# return 0
# raw = 5
# m = 0x10
# for latent in latents:
# raw += m * latent
# m *= 0x20
# return raw
def unpack_latents(raw):
"""Unpack latents.
Returns a tuple of size 0, 5, or 6.
"""
#! The latents come out backwards.
# if raw == 0:
# return (0,0,0,0,0)
ct = raw & 0xF #number of latent slots
raw >>= 4
if ct == 0xF:
# New version with more slots and bigger values.
ct = raw & 0xF
raw >>= 4
bpl = 7 #bits per latent
else:
bpl = 5
mask = (1<<bpl) - 1
latents = []
for _ in range(ct):
latents.append(raw & mask)
raw >>= bpl
assert raw == 0
return tuple(latents)
def repack_latents(latents):
#! Doesn't handle new version.
# It's fine to always use new version now, even if it doesn't use new features.
if not any(latents):
return 0
raw = 5
shift = 4
for latent in latents:
raw |= latent << shift
shift += 5
return raw