store: categorías en inglés (términos oficiales sacados de los DB2)
Cierra el idioma de /en/store: los nombres de ítem ya salían en inglés
(2daf920), pero el árbol de categorías seguía en español y la tienda se veía a
medias.
Los términos DEL JUEGO no se traducen a mano, se sacan del cliente, para que
casen con lo que ve un jugador en inglés:
- ChrClasses -> clases (Brujo = Warlock, Pícaro = Rogue...)
- ItemSet -> sets (Vestiduras de la Némesis = Nemesis Raiment, Las diez
tormentas = The Ten Storms, Atavío viento abisal = Netherwind
Regalia). Casando sin distinguir mayúsculas: las categorías
capitalizan distinto que los ItemSet.
- ItemSubClass-> tipos de arma (Armas de asta = Polearms, Varitas = Wands)
- home_item_data -> lo que no es ItemSet. Los sets de PvP de WotLK no son
ItemSets reales, así que "Gladiador furioso" = "Furious
Gladiator" sale de los nombres bilingües de sus propios ítems.
Solo se traduce a mano lo que la tienda se inventó y no existe en el juego
(Items de leveo = Leveling Items, Moneda de transfiguración = Transmog
Currency), más las fórmulas (Nivel de objeto N = Item Level N, Set de banda
tier N = Tier N Raid Set). Los ~45 nombres que son solo un código ("11-1") y
los que ya estaban en inglés ("Tier 7.1 (PvE)") se dejan igual.
wdc_db2.py aprende a leer strings de tablas no sparse: el valor guardado no es
un índice a la string table sino un offset relativo a la posición del propio
campo. Verificado con ChrClasses (las 10 clases en ambos idiomas).
Revisadas las 218 a mano. Corregida una que me había inventado: "Equipo de
Batalla del Iluminado de la Fuente del Sol" no es "Sunwell Radiance"
(eso es un buff): "Iluminado" es Lightbringer en el ItemSet y "Fuente del Sol"
es Sunwell según sus ítems -> "Sunwell Lightbringer Battlegear".
OJO, bug de datos preexistente: "Sacedorte" (errata de "Sacerdote") en las
categorías 3-10, 4-10 y 19-9; el 20-9 sí está bien. Se ve así en español. El
name_en va a "Priest"; la errata en español NO se toca.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,7 @@ class DB2:
|
||||
self.common[fi] = m
|
||||
|
||||
self.rows = []
|
||||
self.row_pos = [] # posición en fichero de cada fila (para string_at)
|
||||
for s in self.sections:
|
||||
self._read_section(s)
|
||||
|
||||
@@ -99,6 +100,7 @@ class DB2:
|
||||
o = s['file_offset']
|
||||
if self.flags & 0x1: # sparse: offset map en vez de registros fijos
|
||||
raise NotImplementedError('tabla sparse (offset map) no soportada')
|
||||
rec_start = o
|
||||
rec_data = d[o:o + s['record_count'] * self.record_size]
|
||||
o += s['record_count'] * self.record_size
|
||||
o += s['string_table_size']
|
||||
@@ -110,6 +112,9 @@ class DB2:
|
||||
|
||||
for i in range(s['record_count']):
|
||||
rec = rec_data[i * self.record_size:(i + 1) * self.record_size]
|
||||
# Posición del registro en el fichero: la necesita string_at, porque
|
||||
# los offsets de los strings son relativos al propio campo.
|
||||
self.row_pos.append(rec_start + i * self.record_size)
|
||||
row = [self._field(rec, fi, i) for fi in range(self.field_count)]
|
||||
rid = ids[i] if ids is not None else row[self.id_index]
|
||||
# common data: valor por id, o el default (c1) si no está listado
|
||||
@@ -141,3 +146,16 @@ class DB2:
|
||||
return struct.unpack_from('<I', self.pallet, off)[0]
|
||||
return 0
|
||||
raise NotImplementedError(f'storage type {t}')
|
||||
|
||||
def string_at(self, row_index, fi, value):
|
||||
"""Resuelve un campo string de una tabla NO sparse.
|
||||
|
||||
El valor guardado no es un offset absoluto ni un índice a la string
|
||||
table: es un offset RELATIVO a la posición del propio campo dentro del
|
||||
fichero. 0 = cadena vacía.
|
||||
"""
|
||||
if not value:
|
||||
return ''
|
||||
pos = self.row_pos[row_index] + self.storage[fi]['offset_bits'] // 8 + value
|
||||
end = self.d.find(b'\x00', pos)
|
||||
return self.d[pos:end].decode('utf-8', 'replace')
|
||||
|
||||
Reference in New Issue
Block a user