Rivage brise : placements des cartes 1460 et 1666, generateur unifie
NON APPLIQUES au serveur. Verses pour relecture.
DECOUVERTE QUI RECADRE LE CHANTIER
Il y a DEUX Rivages brises, et je preparais le second en premier :
carte 1460 -- le lancement de Legion (Voljin, Varian, la defaite),
c est le contenu de la video fournie ;
carte 1666 -- l assaut de la 7.2 (Kalgorath, Arganoth, Mephistroth).
Pour la 1460, NOTRE SCRIPT EXISTE DEJA : scenario_broken_shore_intro.cpp,
464 lignes, correctement rattache -- instance_template reclame
scenario_broken_shore_intro et c est exactement le nom sous lequel il
s enregistre (RegisterInstanceScript, map 1460). Son scenario est aussi
deja declare (786). Il ne lui manquait QUE les placements. Aucun portage
C++ n est necessaire pour cette carte.
VERIFICATION CROISEE faite avant de generer : sur les 17 entrees que le
script attend, 10 sont placees dans la reference (Voljin, Sylvanas,
Baine, Thrall, Varian, Jaina, Mekkatorque, Genn, Krosus, Arganoth) et
les 7 autres sont INVOQUEES par le script lui-meme (Khadgar l.335,
ancres l.370-371, Tirion l.380, Guldan l.398, troupes via TroopEntry,
credit de fin l.431). La repartition est donc coherente.
CONTENU
carte 1460 : 757 creatures, 101 objets, 84 chemins (526 points)
carte 1666 : 593 creatures, 59 objets, 180 chemins (1495 points)
Toutes les creatures mobiles ont leur chemin, aucune orpheline.
BUG RATTRAPE A LA VALIDATION
Une premiere version de l outil, obtenue en substituant mecaniquement le
numero de carte, produisait pour la 1460 un fichier dont les DELETE
visaient encore la 1666 : il aurait vide la mauvaise carte et laisse
l autre intacte. Le generateur est reecrit, le numero de carte ne vit
plus qu a un seul endroit, et la difficulte est desormais DEDUITE du
spawnMask (verifiee puissance de 2, uniforme) au lieu d etre codee.
VALIDATION en base jetable pour les deux fichiers : import reussi,
comptages exacts, zero creature hors carte, zero mauvaise difficulte,
zero mobile sans chemin, zero collision de GUID avec la base reelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,215 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""Genere le SQL de placement de la carte 1666 dans NOTRE schema.
|
|
||||||
N'applique rien : ecrit un fichier.
|
|
||||||
|
|
||||||
La correspondance est pilotee par les NOMS de colonnes, pas par leur
|
|
||||||
position : si les schemas bougent, le generateur ne produira pas de
|
|
||||||
decalage silencieux -- il s'arretera.
|
|
||||||
"""
|
|
||||||
import io, re, sys
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
DUMP = '/home/ubuntu/tmp/abs/LegionCore_world_2020_04_25.sql'
|
|
||||||
SORTIE = '/home/ubuntu/DestinyCore/sql/sylvania/rivage_brise_placements.sql'
|
|
||||||
|
|
||||||
GUID_CREA = 290100000
|
|
||||||
GUID_GO = 210200000
|
|
||||||
|
|
||||||
NOS_CREA = ['guid','id','map','zoneId','areaId','spawnDifficulties','phaseUseFlags','PhaseId',
|
|
||||||
'PhaseGroup','terrainSwapMap','modelid','equipment_id','position_x','position_y',
|
|
||||||
'position_z','orientation','spawntimesecs','spawndist','currentwaypoint','curhealth',
|
|
||||||
'curmana','MovementType','npcflag','unit_flags','unit_flags2','unit_flags3',
|
|
||||||
'dynamicflags','ScriptName','movementmode','VerifiedBuild']
|
|
||||||
|
|
||||||
NOS_GO = ['guid','id','map','zoneId','areaId','spawnDifficulties','phaseUseFlags','PhaseId',
|
|
||||||
'PhaseGroup','terrainSwapMap','position_x','position_y','position_z','orientation',
|
|
||||||
'rotation0','rotation1','rotation2','rotation3','spawntimesecs','animprogress','state',
|
|
||||||
'isActive','ScriptName','VerifiedBuild']
|
|
||||||
|
|
||||||
NOS_WP = ['id','point','position_x','position_y','position_z','orientation','delay',
|
|
||||||
'move_type','action','action_chance','wpguid']
|
|
||||||
|
|
||||||
# valeurs imposees, quelle que soit la reference
|
|
||||||
FIXES = {
|
|
||||||
'spawnDifficulties': "'12'", # 4096 = 2^12, difficulte « Normal Scenario »
|
|
||||||
'phaseUseFlags': '0',
|
|
||||||
'PhaseGroup': '0',
|
|
||||||
'terrainSwapMap': '-1',
|
|
||||||
'unit_flags2': '0',
|
|
||||||
'ScriptName': "''",
|
|
||||||
'movementmode': '0',
|
|
||||||
'VerifiedBuild': '0',
|
|
||||||
'wpguid': '0',
|
|
||||||
}
|
|
||||||
|
|
||||||
# nos colonnes qui portent un autre nom dans la reference
|
|
||||||
ALIAS = {'move_type': 'move_flag'}
|
|
||||||
|
|
||||||
|
|
||||||
def decoupe_tuples(bloc):
|
|
||||||
res, cur, prof, chaine, echap = [], [], 0, False, False
|
|
||||||
for c in bloc:
|
|
||||||
if chaine:
|
|
||||||
cur.append(c)
|
|
||||||
if echap: echap = False
|
|
||||||
elif c == '\\': echap = True
|
|
||||||
elif c == "'": chaine = False
|
|
||||||
continue
|
|
||||||
if c == "'":
|
|
||||||
chaine = True; cur.append(c)
|
|
||||||
elif c == '(':
|
|
||||||
prof += 1
|
|
||||||
cur = [] if prof == 1 else cur + [c]
|
|
||||||
elif c == ')':
|
|
||||||
prof -= 1
|
|
||||||
if prof == 0: res.append(''.join(cur))
|
|
||||||
else: cur.append(c)
|
|
||||||
elif prof > 0:
|
|
||||||
cur.append(c)
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def champs(t):
|
|
||||||
vals, cur, chaine, echap = [], [], False, False
|
|
||||||
for c in t:
|
|
||||||
if chaine:
|
|
||||||
cur.append(c)
|
|
||||||
if echap: echap = False
|
|
||||||
elif c == '\\': echap = True
|
|
||||||
elif c == "'": chaine = False
|
|
||||||
continue
|
|
||||||
if c == "'":
|
|
||||||
chaine = True; cur.append(c)
|
|
||||||
elif c == ',':
|
|
||||||
vals.append(''.join(cur).strip()); cur = []
|
|
||||||
else:
|
|
||||||
cur.append(c)
|
|
||||||
vals.append(''.join(cur).strip())
|
|
||||||
return vals
|
|
||||||
|
|
||||||
|
|
||||||
def lire(tables):
|
|
||||||
"""Renvoie {table: (colonnes, [tuples decoupes])} pour tout le dump."""
|
|
||||||
motif = re.compile(r"insert\s+into\s+`(%s)`\(([^)]*)\)\s+values\s*" % '|'.join(tables), re.I)
|
|
||||||
out = {t: {'cols': None, 'rows': []} for t in tables}
|
|
||||||
with io.open(DUMP, encoding='utf-8', errors='replace') as f:
|
|
||||||
ligne = f.readline()
|
|
||||||
while ligne:
|
|
||||||
m = motif.match(ligne.lstrip())
|
|
||||||
if not m:
|
|
||||||
ligne = f.readline(); continue
|
|
||||||
table = m.group(1).lower()
|
|
||||||
cols = [c.strip().strip('`') for c in m.group(2).split(',')]
|
|
||||||
morceaux = [ligne[ligne.lower().find('values') + 6:]]
|
|
||||||
while not morceaux[-1].rstrip().endswith(';'):
|
|
||||||
s = f.readline()
|
|
||||||
if not s: break
|
|
||||||
morceaux.append(s)
|
|
||||||
out[table]['cols'] = cols
|
|
||||||
for t in decoupe_tuples(''.join(morceaux)):
|
|
||||||
v = champs(t)
|
|
||||||
if len(v) == len(cols):
|
|
||||||
out[table]['rows'].append(v)
|
|
||||||
ligne = f.readline()
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
def valeur(nom, cols, v, guid_neuf):
|
|
||||||
if nom == 'guid':
|
|
||||||
return str(guid_neuf)
|
|
||||||
if nom in FIXES:
|
|
||||||
return FIXES[nom]
|
|
||||||
src = ALIAS.get(nom, nom)
|
|
||||||
if src not in cols:
|
|
||||||
raise KeyError("colonne '%s' absente de la reference" % src)
|
|
||||||
brut = v[cols.index(src)]
|
|
||||||
if nom in ('PhaseId', 'PhaseGroup'): # chaine cote reference, entier chez nous
|
|
||||||
b = brut.strip().strip("'")
|
|
||||||
return b if b else '0'
|
|
||||||
return brut
|
|
||||||
|
|
||||||
|
|
||||||
print('lecture du dump...')
|
|
||||||
d = lire(['creature', 'gameobject', 'waypoint_data'])
|
|
||||||
|
|
||||||
crea = [v for v in d['creature']['rows'] if v[d['creature']['cols'].index('map')] == '1666']
|
|
||||||
go = [v for v in d['gameobject']['rows'] if v[d['gameobject']['cols'].index('map')] == '1666']
|
|
||||||
print('creatures 1666 : %d | objets 1666 : %d' % (len(crea), len(go)))
|
|
||||||
assert crea and go, 'extraction vide -- refuser de generer'
|
|
||||||
|
|
||||||
# renumerotation, en gardant la trace ancien -> nouveau
|
|
||||||
i_guid_c = d['creature']['cols'].index('guid')
|
|
||||||
map_guid = {}
|
|
||||||
for n, v in enumerate(crea):
|
|
||||||
map_guid[v[i_guid_c]] = GUID_CREA + n
|
|
||||||
|
|
||||||
# chemins des creatures mobiles
|
|
||||||
i_mt = d['creature']['cols'].index('MovementType')
|
|
||||||
mobiles = {v[i_guid_c] for v in crea if v[i_mt] == '2'}
|
|
||||||
wp_cols = d['waypoint_data']['cols']
|
|
||||||
i_wid = wp_cols.index('id')
|
|
||||||
wp = [v for v in d['waypoint_data']['rows'] if v[i_wid] in mobiles]
|
|
||||||
chemins = len({v[i_wid] for v in wp})
|
|
||||||
print('creatures mobiles : %d | chemins trouves : %d | points : %d' % (len(mobiles), chemins, len(wp)))
|
|
||||||
|
|
||||||
lignes = []
|
|
||||||
A = lignes.append
|
|
||||||
A("-- =====================================================================")
|
|
||||||
A("-- Assaut du Rivage brise (carte 1666) -- PLACEMENTS")
|
|
||||||
A("--")
|
|
||||||
A("-- Transpose depuis le dump world de dufernst/LegionCore-7.3.5, meme")
|
|
||||||
A("-- lignee uwow que notre fork. Les deux schemas divergent : la")
|
|
||||||
A("-- correspondance ci-dessous est pilotee par les NOMS de colonnes, et le")
|
|
||||||
A("-- generateur s'arrete plutot que de produire un decalage silencieux.")
|
|
||||||
A("--")
|
|
||||||
A("-- DECISIONS, etablies sur donnees et non supposees :")
|
|
||||||
A("-- spawnMask 4096 = 2^12 -> spawnDifficulties '12', la difficulte 12")
|
|
||||||
A("-- etant « Normal Scenario » d'apres Difficulty.db2 du build")
|
|
||||||
A("-- 7.3.5.26972 (type instance 5, 5 joueurs).")
|
|
||||||
A("-- GUID renumerotes a partir de %d (creatures) et %d (objets)," % (GUID_CREA, GUID_GO))
|
|
||||||
A("-- au-dessus de nos maxima 290000114 et 210120986.")
|
|
||||||
A("-- PhaseId : chaine vide cote reference -> 0 chez nous (entier).")
|
|
||||||
A("--")
|
|
||||||
A("-- ABANDONNE faute d'equivalent : npcflag2, AiID, MovementID, MeleeID,")
|
|
||||||
A("-- isActive (creature), skipClone, personal_size, isTeemingSpawn.")
|
|
||||||
A("-- 12 creatures portaient AiID=7424, une table d'IA propre au coeur de")
|
|
||||||
A("-- reference : leur comportement est PERDU et reste a refaire.")
|
|
||||||
A("--")
|
|
||||||
A("-- Contenu : %d creatures, %d objets, %d chemins (%d points)." % (len(crea), len(go), chemins, len(wp)))
|
|
||||||
A("-- =====================================================================")
|
|
||||||
A("")
|
|
||||||
A("DELETE FROM `creature` WHERE `map`=1666;")
|
|
||||||
A("DELETE FROM `gameobject` WHERE `map`=1666;")
|
|
||||||
A("DELETE FROM `waypoint_data` WHERE `id` BETWEEN %d AND %d;" % (GUID_CREA, GUID_CREA + len(crea)))
|
|
||||||
A("")
|
|
||||||
|
|
||||||
A("INSERT INTO `creature` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_CREA))
|
|
||||||
bouts = []
|
|
||||||
for n, v in enumerate(crea):
|
|
||||||
bouts.append('(' + ','.join(valeur(c, d['creature']['cols'], v, GUID_CREA + n) for c in NOS_CREA) + ')')
|
|
||||||
A(',\n'.join(bouts) + ';')
|
|
||||||
A("")
|
|
||||||
|
|
||||||
A("INSERT INTO `gameobject` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_GO))
|
|
||||||
bouts = []
|
|
||||||
for n, v in enumerate(go):
|
|
||||||
bouts.append('(' + ','.join(valeur(c, d['gameobject']['cols'], v, GUID_GO + n) for c in NOS_GO) + ')')
|
|
||||||
A(',\n'.join(bouts) + ';')
|
|
||||||
A("")
|
|
||||||
|
|
||||||
if wp:
|
|
||||||
A("INSERT INTO `waypoint_data` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_WP))
|
|
||||||
bouts = []
|
|
||||||
for v in wp:
|
|
||||||
anc = v[i_wid]
|
|
||||||
ligne_vals = []
|
|
||||||
for c in NOS_WP:
|
|
||||||
if c == 'id':
|
|
||||||
ligne_vals.append(str(map_guid[anc]))
|
|
||||||
else:
|
|
||||||
ligne_vals.append(valeur(c, wp_cols, v, 0))
|
|
||||||
bouts.append('(' + ','.join(ligne_vals) + ')')
|
|
||||||
A(',\n'.join(bouts) + ';')
|
|
||||||
|
|
||||||
io.open(SORTIE, 'w', encoding='utf-8').write('\n'.join(lignes) + '\n')
|
|
||||||
print('ecrit : %s' % SORTIE)
|
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Genere le SQL de placement d'une carte depuis le dump de reference,
|
||||||
|
transpose dans NOTRE schema.
|
||||||
|
|
||||||
|
python3 generer_placements.py <carte> <guid_creature> <guid_objet>
|
||||||
|
|
||||||
|
La correspondance est pilotee par les NOMS de colonnes : si un schema
|
||||||
|
bouge, le generateur s'arrete au lieu de produire un decalage silencieux.
|
||||||
|
|
||||||
|
ATTENTION -- une version precedente de cet outil, obtenue en substituant
|
||||||
|
mecaniquement le numero de carte, produisait un fichier dont les DELETE
|
||||||
|
visaient encore l'ancienne carte. Le fichier aurait vide la mauvaise et
|
||||||
|
laisse l'autre intacte. Ici le numero de carte ne vit qu'a UN endroit,
|
||||||
|
la variable CARTE, et sert partout.
|
||||||
|
"""
|
||||||
|
import io, re, sys
|
||||||
|
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
sys.exit(__doc__)
|
||||||
|
|
||||||
|
CARTE = sys.argv[1]
|
||||||
|
GUID_CREA = int(sys.argv[2])
|
||||||
|
GUID_GO = int(sys.argv[3])
|
||||||
|
|
||||||
|
DUMP = '/home/ubuntu/tmp/abs/LegionCore_world_2020_04_25.sql'
|
||||||
|
SORTIE = '/home/ubuntu/DestinyCore/sql/sylvania/rivage_brise_placements_%s.sql' % CARTE
|
||||||
|
|
||||||
|
NOS_CREA = ['guid','id','map','zoneId','areaId','spawnDifficulties','phaseUseFlags','PhaseId',
|
||||||
|
'PhaseGroup','terrainSwapMap','modelid','equipment_id','position_x','position_y',
|
||||||
|
'position_z','orientation','spawntimesecs','spawndist','currentwaypoint','curhealth',
|
||||||
|
'curmana','MovementType','npcflag','unit_flags','unit_flags2','unit_flags3',
|
||||||
|
'dynamicflags','ScriptName','movementmode','VerifiedBuild']
|
||||||
|
|
||||||
|
NOS_GO = ['guid','id','map','zoneId','areaId','spawnDifficulties','phaseUseFlags','PhaseId',
|
||||||
|
'PhaseGroup','terrainSwapMap','position_x','position_y','position_z','orientation',
|
||||||
|
'rotation0','rotation1','rotation2','rotation3','spawntimesecs','animprogress','state',
|
||||||
|
'isActive','ScriptName','VerifiedBuild']
|
||||||
|
|
||||||
|
NOS_WP = ['id','point','position_x','position_y','position_z','orientation','delay',
|
||||||
|
'move_type','action','action_chance','wpguid']
|
||||||
|
|
||||||
|
FIXES = {'phaseUseFlags':'0', 'PhaseGroup':'0', 'terrainSwapMap':'-1', 'unit_flags2':'0',
|
||||||
|
'ScriptName':"''", 'movementmode':'0', 'VerifiedBuild':'0', 'wpguid':'0'}
|
||||||
|
ALIAS = {'move_type': 'move_flag'}
|
||||||
|
|
||||||
|
|
||||||
|
def decoupe_tuples(bloc):
|
||||||
|
res, cur, prof, chaine, echap = [], [], 0, False, False
|
||||||
|
for c in bloc:
|
||||||
|
if chaine:
|
||||||
|
cur.append(c)
|
||||||
|
if echap: echap = False
|
||||||
|
elif c == '\\': echap = True
|
||||||
|
elif c == "'": chaine = False
|
||||||
|
continue
|
||||||
|
if c == "'":
|
||||||
|
chaine = True; cur.append(c)
|
||||||
|
elif c == '(':
|
||||||
|
prof += 1
|
||||||
|
cur = [] if prof == 1 else cur + [c]
|
||||||
|
elif c == ')':
|
||||||
|
prof -= 1
|
||||||
|
if prof == 0: res.append(''.join(cur))
|
||||||
|
else: cur.append(c)
|
||||||
|
elif prof > 0:
|
||||||
|
cur.append(c)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def champs(t):
|
||||||
|
vals, cur, chaine, echap = [], [], False, False
|
||||||
|
for c in t:
|
||||||
|
if chaine:
|
||||||
|
cur.append(c)
|
||||||
|
if echap: echap = False
|
||||||
|
elif c == '\\': echap = True
|
||||||
|
elif c == "'": chaine = False
|
||||||
|
continue
|
||||||
|
if c == "'":
|
||||||
|
chaine = True; cur.append(c)
|
||||||
|
elif c == ',':
|
||||||
|
vals.append(''.join(cur).strip()); cur = []
|
||||||
|
else:
|
||||||
|
cur.append(c)
|
||||||
|
vals.append(''.join(cur).strip())
|
||||||
|
return vals
|
||||||
|
|
||||||
|
|
||||||
|
def lire(tables):
|
||||||
|
motif = re.compile(r"insert\s+into\s+`(%s)`\(([^)]*)\)\s+values\s*" % '|'.join(tables), re.I)
|
||||||
|
out = {t: {'cols': None, 'rows': []} for t in tables}
|
||||||
|
with io.open(DUMP, encoding='utf-8', errors='replace') as f:
|
||||||
|
ligne = f.readline()
|
||||||
|
while ligne:
|
||||||
|
m = motif.match(ligne.lstrip())
|
||||||
|
if not m:
|
||||||
|
ligne = f.readline(); continue
|
||||||
|
table = m.group(1).lower()
|
||||||
|
cols = [c.strip().strip('`') for c in m.group(2).split(',')]
|
||||||
|
morceaux = [ligne[ligne.lower().find('values') + 6:]]
|
||||||
|
while not morceaux[-1].rstrip().endswith(';'):
|
||||||
|
s = f.readline()
|
||||||
|
if not s: break
|
||||||
|
morceaux.append(s)
|
||||||
|
out[table]['cols'] = cols
|
||||||
|
for t in decoupe_tuples(''.join(morceaux)):
|
||||||
|
v = champs(t)
|
||||||
|
if len(v) == len(cols):
|
||||||
|
out[table]['rows'].append(v)
|
||||||
|
ligne = f.readline()
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def valeur(nom, cols, v, guid_neuf, difficulte):
|
||||||
|
if nom == 'guid':
|
||||||
|
return str(guid_neuf)
|
||||||
|
if nom == 'spawnDifficulties':
|
||||||
|
return "'%s'" % difficulte
|
||||||
|
if nom in FIXES:
|
||||||
|
return FIXES[nom]
|
||||||
|
src = ALIAS.get(nom, nom)
|
||||||
|
if src not in cols:
|
||||||
|
raise KeyError("colonne '%s' absente de la reference" % src)
|
||||||
|
brut = v[cols.index(src)]
|
||||||
|
if nom in ('PhaseId', 'PhaseGroup'):
|
||||||
|
b = brut.strip().strip("'")
|
||||||
|
return b if b else '0'
|
||||||
|
return brut
|
||||||
|
|
||||||
|
|
||||||
|
print('lecture du dump (carte %s)...' % CARTE)
|
||||||
|
d = lire(['creature', 'gameobject', 'waypoint_data'])
|
||||||
|
|
||||||
|
cc, cg = d['creature']['cols'], d['gameobject']['cols']
|
||||||
|
crea = [v for v in d['creature']['rows'] if v[cc.index('map')] == CARTE]
|
||||||
|
go = [v for v in d['gameobject']['rows'] if v[cg.index('map')] == CARTE]
|
||||||
|
if not crea:
|
||||||
|
sys.exit('extraction vide pour la carte %s -- on ne genere rien' % CARTE)
|
||||||
|
|
||||||
|
# la difficulte se DEDUIT du spawnMask, elle n'est pas supposee
|
||||||
|
masques = {v[cc.index('spawnMask')] for v in crea}
|
||||||
|
if len(masques) != 1:
|
||||||
|
sys.exit('spawnMask non uniforme (%s) -- transposition a decider a la main' % masques)
|
||||||
|
masque = int(masques.pop())
|
||||||
|
if masque & (masque - 1):
|
||||||
|
sys.exit('spawnMask %d n est pas une puissance de 2 -- a decider a la main' % masque)
|
||||||
|
DIFFICULTE = masque.bit_length() - 1
|
||||||
|
print('spawnMask %d -> difficulte %d' % (masque, DIFFICULTE))
|
||||||
|
|
||||||
|
i_guid = cc.index('guid')
|
||||||
|
map_guid = {v[i_guid]: GUID_CREA + n for n, v in enumerate(crea)}
|
||||||
|
|
||||||
|
mobiles = {v[i_guid] for v in crea if v[cc.index('MovementType')] == '2'}
|
||||||
|
wpc = d['waypoint_data']['cols']
|
||||||
|
wp = [v for v in d['waypoint_data']['rows'] if v[wpc.index('id')] in mobiles]
|
||||||
|
chemins = len({v[wpc.index('id')] for v in wp})
|
||||||
|
print('creatures %d | objets %d | mobiles %d | chemins %d | points %d'
|
||||||
|
% (len(crea), len(go), len(mobiles), chemins, len(wp)))
|
||||||
|
if chemins != len(mobiles):
|
||||||
|
print(' ATTENTION : %d creatures mobiles sans chemin' % (len(mobiles) - chemins))
|
||||||
|
|
||||||
|
L = []
|
||||||
|
L.append("-- =====================================================================")
|
||||||
|
L.append("-- Rivage brise -- PLACEMENTS de la carte %s" % CARTE)
|
||||||
|
L.append("--")
|
||||||
|
L.append("-- Transpose depuis le dump world de dufernst/LegionCore-7.3.5, meme")
|
||||||
|
L.append("-- lignee uwow que notre fork. Les schemas divergent : la")
|
||||||
|
L.append("-- correspondance est pilotee par les NOMS de colonnes, et le")
|
||||||
|
L.append("-- generateur s'arrete plutot que de produire un decalage silencieux.")
|
||||||
|
L.append("--")
|
||||||
|
L.append("-- DIFFICULTE : deduite, pas supposee. Les %d placements portent tous" % len(crea))
|
||||||
|
L.append("-- spawnMask %d = 2^%d, d'ou spawnDifficulties '%d'." % (masque, DIFFICULTE, DIFFICULTE))
|
||||||
|
L.append("--")
|
||||||
|
L.append("-- GUID renumerotes a partir de %d (creatures) et %d (objets)," % (GUID_CREA, GUID_GO))
|
||||||
|
L.append("-- au-dessus de nos maxima connus 290000114 et 210120986.")
|
||||||
|
L.append("-- PhaseId : chaine vide cote reference -> 0 chez nous (colonne entiere).")
|
||||||
|
L.append("--")
|
||||||
|
L.append("-- ABANDONNE faute d'equivalent chez nous : npcflag2, AiID, MovementID,")
|
||||||
|
L.append("-- MeleeID, isActive (creature), skipClone, personal_size, isTeemingSpawn.")
|
||||||
|
L.append("--")
|
||||||
|
L.append("-- Contenu : %d creatures, %d objets, %d chemins (%d points)." % (len(crea), len(go), chemins, len(wp)))
|
||||||
|
L.append("-- =====================================================================")
|
||||||
|
L.append("")
|
||||||
|
L.append("DELETE FROM `creature` WHERE `map`=%s;" % CARTE)
|
||||||
|
L.append("DELETE FROM `gameobject` WHERE `map`=%s;" % CARTE)
|
||||||
|
L.append("DELETE FROM `waypoint_data` WHERE `id` BETWEEN %d AND %d;" % (GUID_CREA, GUID_CREA + len(crea)))
|
||||||
|
L.append("")
|
||||||
|
|
||||||
|
L.append("INSERT INTO `creature` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_CREA))
|
||||||
|
L.append(',\n'.join('(' + ','.join(valeur(c, cc, v, GUID_CREA + n, DIFFICULTE) for c in NOS_CREA) + ')'
|
||||||
|
for n, v in enumerate(crea)) + ';')
|
||||||
|
L.append("")
|
||||||
|
|
||||||
|
if go:
|
||||||
|
L.append("INSERT INTO `gameobject` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_GO))
|
||||||
|
L.append(',\n'.join('(' + ','.join(valeur(c, cg, v, GUID_GO + n, DIFFICULTE) for c in NOS_GO) + ')'
|
||||||
|
for n, v in enumerate(go)) + ';')
|
||||||
|
L.append("")
|
||||||
|
|
||||||
|
if wp:
|
||||||
|
L.append("INSERT INTO `waypoint_data` (%s) VALUES" % ','.join('`%s`' % c for c in NOS_WP))
|
||||||
|
bouts = []
|
||||||
|
for v in wp:
|
||||||
|
vals = [str(map_guid[v[wpc.index('id')]]) if c == 'id'
|
||||||
|
else valeur(c, wpc, v, 0, DIFFICULTE) for c in NOS_WP]
|
||||||
|
bouts.append('(' + ','.join(vals) + ')')
|
||||||
|
L.append(',\n'.join(bouts) + ';')
|
||||||
|
|
||||||
|
io.open(SORTIE, 'w', encoding='utf-8').write('\n'.join(L) + '\n')
|
||||||
|
print('ecrit : %s' % SORTIE)
|
||||||
File diff suppressed because it is too large
Load Diff
+11
-14
@@ -1,23 +1,20 @@
|
|||||||
-- =====================================================================
|
-- =====================================================================
|
||||||
-- Assaut du Rivage brise (carte 1666) -- PLACEMENTS
|
-- Rivage brise -- PLACEMENTS de la carte 1666
|
||||||
--
|
--
|
||||||
-- Transpose depuis le dump world de dufernst/LegionCore-7.3.5, meme
|
-- Transpose depuis le dump world de dufernst/LegionCore-7.3.5, meme
|
||||||
-- lignee uwow que notre fork. Les deux schemas divergent : la
|
-- lignee uwow que notre fork. Les schemas divergent : la
|
||||||
-- correspondance ci-dessous est pilotee par les NOMS de colonnes, et le
|
-- correspondance est pilotee par les NOMS de colonnes, et le
|
||||||
-- generateur s'arrete plutot que de produire un decalage silencieux.
|
-- generateur s'arrete plutot que de produire un decalage silencieux.
|
||||||
--
|
--
|
||||||
-- DECISIONS, etablies sur donnees et non supposees :
|
-- DIFFICULTE : deduite, pas supposee. Les 593 placements portent tous
|
||||||
-- spawnMask 4096 = 2^12 -> spawnDifficulties '12', la difficulte 12
|
-- spawnMask 4096 = 2^12, d'ou spawnDifficulties '12'.
|
||||||
-- etant « Normal Scenario » d'apres Difficulty.db2 du build
|
|
||||||
-- 7.3.5.26972 (type instance 5, 5 joueurs).
|
|
||||||
-- GUID renumerotes a partir de 290100000 (creatures) et 210200000 (objets),
|
|
||||||
-- au-dessus de nos maxima 290000114 et 210120986.
|
|
||||||
-- PhaseId : chaine vide cote reference -> 0 chez nous (entier).
|
|
||||||
--
|
--
|
||||||
-- ABANDONNE faute d'equivalent : npcflag2, AiID, MovementID, MeleeID,
|
-- GUID renumerotes a partir de 290100000 (creatures) et 210200000 (objets),
|
||||||
-- isActive (creature), skipClone, personal_size, isTeemingSpawn.
|
-- au-dessus de nos maxima connus 290000114 et 210120986.
|
||||||
-- 12 creatures portaient AiID=7424, une table d'IA propre au coeur de
|
-- PhaseId : chaine vide cote reference -> 0 chez nous (colonne entiere).
|
||||||
-- reference : leur comportement est PERDU et reste a refaire.
|
--
|
||||||
|
-- ABANDONNE faute d'equivalent chez nous : npcflag2, AiID, MovementID,
|
||||||
|
-- MeleeID, isActive (creature), skipClone, personal_size, isTeemingSpawn.
|
||||||
--
|
--
|
||||||
-- Contenu : 593 creatures, 59 objets, 180 chemins (1495 points).
|
-- Contenu : 593 creatures, 59 objets, 180 chemins (1495 points).
|
||||||
-- =====================================================================
|
-- =====================================================================
|
||||||
Reference in New Issue
Block a user