Might & Magic X: Legacy > Obecná diskuze k Legacy

Modifikovatelnost datových souborů MMX

(1/3) > >>

Elemir:
Trochu mám obavy tu s podobným tématem začít, ale protože jsem dneska rozkódoval další kus závislostí, tak mě napadlo, že bych tenhle thread mohl rovnou použít jako zápisník pro poznámky :) Spíš bych se chtěl věnovat popisu, ale pokud se někdo rozhodne poznatky využít tak ...

... musím v první řadě upozornit, že jakákoliv modifikace datových souborů je jen na vlastní nebezpečí. Základem je vždy provádět zálohy originálních souborů, ať je k čemu se vracet. Upravit nějakou drobnost nemusí nutně znamenat v celkovém pohledu hry problém, ale u větších úprav můžete např. narazit na kolizi s budoucími oficiálními patchi. Co si budeme povídat, i Limbic v tom má bordel :D

Základem pro modifikace je herní adresář StaticData, který najdete pod Might and Magic X Legacy_Data -> StreamingAssets. Obsahuje sadu csv souborů s definicemi. K tomu se váže ještě lokalizační soubor loca.xml z příslušného podadresáře cz adresáře Localisation. Pro globální nastavení je třeba zmínit ještě konfigurační soubor config.txt, který je přímo v adresáři StreamingAssets.

csv soubory jsou ve své podstatě definice polí (klasický datový typ), nebo lépe řečeno, jedná se o databázové tabulky. Ve skutečnosti je opravdu velmi jednoduché obsažená data vzít, nasázet do databáze a klidně je využívat (např. naprogramovat MMX jako webbased aplikaci ;)). Základem je porozumět závislostem a umět z toho něco rozumného poskládat. Někdy je totiž třeba změnu provést ve více souborech, ostatně známý bug v Boji s obouručními zbraněmi je jen podobným způsobem přehlídnutá chyba.

A to se mi zrovna hodí k výše uvedenému varování - Limbic tuhle chybu určitě opraví, ale pokud jste to již udělali sami, budete se muset spolehnout, že jste zvolili stejnou cestu opravy, jinak vám to opět nepůjde korektně ;)

Elemir:
config.txt

Elemir:
StaticData, Dovednosti

Protože jsem dneska začal výpisem dovedností, předvedu pár věcí na csv souborech s jejich definicemi.

Základem dovedností jsou 2 soubory - Skills.csv a SkillEffects.csv. Ten první definuje všech 25 dovedností, jejich klíč pro název a popisek, obrázek (ikonku) a ID pro jednotlivé úrovně (Tier1Effects až Tier4Effects).

Např. pro Dýku platí:

1,SKILL_NAME_DAGGER,SKILL_DESC_DAGGER,SPL_skill_weapon_Dagger,"1,2",3,4,3,7,WEAPON

kde

1 ... ID položky (StaticID)
SKILL_NAME_DAGGER ... klíč pro popisek v souboru loca.xml (když to vyhledáte, získáte výraz Dýka ;))
SKILL_DESC_DAGGER ... klíč pro popisek v souboru loca.xml (popisek dovednosti)
SPL_skill_weapon_Dagger ... umístění ikonky v příslušném assetu
"1,2" ... ID pro normální úroveň (odpovídá StaticID 1 a 2 v souboru SkillEfects.csv)
3 ... ID pro expertní úroveň (odpovídá StaticID 3 v souboru SkillEfects.csv)
4 ... ID pro mistrovskou úroveň (odpovídá StaticID 4 v souboru SkillEfects.csv)
3 ... ID pro velmistrovskou úroveň (odpovídá StaticID 3 v souboru SkillEfects.csv)
7 ... nemám ponětí ;)
WEAPON ... kategorie dovednosti, tady zbraň (MMX zná jen 3, další dvě jsou MISC a MAGIC)

Díky tomuto znáte tedy propojení popiskových klíčů se souborem loca.xml a zároveň víte, kde hledat definice pro jednotlivé úrovně dovednosti. Pokud nyní koukneme do souboru SkillEffects.csv a vytáhneme si potřebná StaticID, získáme:

normální úroveň (Tier1Effects)

1,SKILL_EFFECT_DAGGER_ATTACK,SKILL_EFFECT_DAGGER_CURRENT_ATTACK,FALSE,TRUE,IS_EQUIPED              ,INCREASE_ATTACK_VALUE,2,PER_SKILL_LEVEL

expertní úroveň (Tier2Effects)

2,SKILL_EFFECT_DAGGER_DAMAGE,SKILL_EFFECT_DAGGER_CURRENT_DAMAGE,TRUE,TRUE,IS_EQUIPED,                    INCREASE_DAMAGE_SKILL_BONUS,0.04,PER_SKILL_LEVEL

mistrovská úroveň (Tier3Effects)

3,SKILL_EFFECT_DAGGER_STRIKE,,FALSE,TRUE,FOR_EACH_EQUIPMENT,ADDITIONAL_STRIKE,0,NONE

velmistrovská úroveň (Tier4Effects)

4,SKILL_EFFECT_DAGGER_CRIT_CHANCE,,TRUE,TRUE,FOR_EACH_EQUIPMENT,INCREASE_CRITICAL_HIT           _CHANCE,0.1,FIXED

a opět, velkými písmeny jsou uvedené popiskové klíče pro soubor loca.xml ... vlastně tu nic jiného ani nenajdeme. Takže si nejprve najdeme ještě patřičné klíče v souboru loca.xml, abychom tomu mohli lépe porozumnět:

<LocaData id="SKILL_NAME_DAGGER">Dýka</LocaData>
<LocaData id="SKILL_DESC_DAGGER">Jelikož jsou dýky lehké a malé, často jsou přehlíženy jako neúčinné zbraně. To je pravda, pokud je mají v rukách amatéři. V rukách skutečného mistra se však stávají smrtícími nástroji. Žádná zbraň není tak skvělá v opakovaných a přesných zásazích životně důležitých míst.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_CURRENT_ATTACK">Zvyšuje {0}hodnotu útoku{1} o {2}.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_CURRENT_DAMAGE">Zvyšuje {0}poškození{1} o {2} {0}%{1}.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_ATTACK">Vaše {0}útočná hodnota{1} s dýkami se zvýší o {2} za {0}každou úroveň této dovednosti{1}.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_DAMAGE">Vaše {0}poškození{1} s dýkami se zvýší o {2} {0}%{1} za každou {0}úroveň této dovednosti{1}.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_STRIKE">Za každou drženou dýku získáte {0}jeden útok navíc{1}.</LocaData>
<LocaData id="SKILL_EFFECT_DAGGER_CRIT_CHANCE">Vaše {0}šance na kritický zásah{1} se zvýší o {2} {0}%{1} za každou drženou dýku.</LocaData>

Hezké, že? Nyní se můžeme vrátit k výpisu ze SkillEffects.csv. Vezmeme hned první položku:

1,SKILL_EFFECT_DAGGER_ATTACK,SKILL_EFFECT_DAGGER_CURRENT_ATTACK,FALSE,TRUE,IS_EQUIPED                    ,INCREASE_ATTACK_VALUE,2,PER_SKILL_LEVEL

a hledáme odpovídající klíč z loca.xml SKILL_EFFECT_DAGGER_ATTACK, SKILL_EFFECT_DAGGER_CURRENT_ATTACK. Klíče INCREASE_ATTACK_VALUE,2,PER_SKILL_LEVEL tu sice nenajdeme, ale jedná se o zápis hodnot (Type,Value,Mode) z čehož pro nás je důležitá ta číslovka 2 (zvyšuje hodnotu útoku o 2 za úroveň). Teď to spárujeme:

SKILL_EFFECT_DAGGER_ATTACK = Vaše {0}útočná hodnota{1} s dýkami se zvýší o {2} za {0}každou úroveň této dovednosti{1}.
SKILL_EFFECT_DAGGER_CURRENT_ATTACK = Zvyšuje {0}hodnotu útoku{1} o {2}.

Už je to čitelnější. Hodnoty v závorkách jsou tzv. masky, ve finále jsou nahrazeny konkrétními parametry. {0} a {1} jsou formátovací (tučně, modře). Důležitá je značka {2}, která se nahradí hodnotou definice dovednosti, tedy je to ona "2" ze zápisu INCREASE_ATTACK_VALUE,2,PER_SKILL_LEVEL (Type,Value,Mode). Podobně můžeme pokračovat dále.

Díky tomu můžeme předefinovat hodnoty útoku, pravděpodobnost kritického zásahu, nebo např. počet útoků v kole -> když např. v řetězci ADDITIONAL_STRIKE,0,NONE změníte 0 na 5, zvýší se počet útoků v expertní úrovni o 5, ve velmistrovské pak o dalších 5 (v Skills.csv  je totiž Tier2Effects roven Tier4Effects). Nebo si pro obě úrovně nadefinujeme jiné počty útoků, prostě jen změníme v Skills.csv patřičné ID (např.  Tier4Effects bude 200) a ve SkillEfects.csv přidáme patřičný řádek se StaticID 200 a doplníme jeho chování.

Jak vidno, není to zas tak složité :D

Elemir:
StaticData, Magie

Pracovat s magií je už o kousek komplikovanější, protože je provázána většími závislostmi. Základním souborem definic je CharacterSpellsStaticData.csv, na který jsou potom navázány soubory PartyBuffs.csv (doplněk pro kouzla mající efekt na družinu, např. Ochrana proti ohni), MonsterBuffs.csv (doplněk pro kouzla mající efekt na monstra, např. Zapletení) a SummonStaticData.csv (doplněk pro kouzla s efektem vyvolávání, např. Cyklón).

Poznámka: soubor PartyBuffs.csv obsahuje také definice soch poskytujících bonusy.

CharacterSpellsStaticData.csv obsahuje hezkou řádku definic, které dokonale popisují každé kouzlo (název, popis, efekt/poškození, potřeba many apod.). Pro ilustraci přikládám definici kouzla Ohnivý šíp:

3,SPELL_FIRE_BOLT,SPELL_FIRE_BOLT_DESCRIPTION,NONE,NONE,NONE,SKILL_FIRE_MAGIC,NOVICE,    SPL_fire_FireBolt,
"FIRE,25,35",4,SINGLE_MONSTER,0,FX/FireBolt,20,0,NONE

3 ... klasicky StaticID
SPELL_FIRE_BOLT ... klíč pro jméno (loca.xml)
SPELL_FIRE_BOLT_DESCRIPTION ... klíč pro popis (loca.xml)
NONE ... podmínky zrišení kouzla
NONE ... efekt na družinu
NONE ... efekt na monstra
SKILL_FIRE_MAGIC ... potřebná dovednost
NOVICE ... potřebná úroveň dovednosti
SPL_fire_FireBolt ... umístění ikonky v assets
"FIRE,25,35" ... typ poškození, základ min. a max. damage (25-35)
4 ... dosah střely (4 čtverce)
SINGLE_MONSTER ... typ cíle (jedno monstrum)
0 ... ID pro soubor SummonStaticData.csv
FX/FireBolt ... identifikace animace
20 ... stojí many
0 ... základní cena kouzla (tady 0, protože Ohnivý šíp se dostává automaticky za naučení mgie ohně)
NONE ... je závislé na konkrétní třídě? (např. Paladin vs Přikládání rukou)

Jedná se o klasické útočné kouzlo bez speciálních požadavků. U Cyklónu by třeba bylo definováno i SummonID, odkud by se pak teprve dočetl patřičný efekt. Podobně u ochranných kouzel sesílaných na celou družinu. Ostatně si to hned můžeme ukázat na kouzle Ochrana před ohněm:

1
SPELL_FIRE_WARD
SPELL_FIRE_WARD_DESCRIPTION
NONE
FIRE_WARD ... klíč pro soubor PartyBuffs.csv
NONE
SKILL_FIRE_MAGIC
NOVICE
SPL_fire_FireWard
... u efektu není definována žádná hodnota, protože ta je odečtena právě ze souboru PartyBuffs.csv
1 ... dosah kouzla je jasný, jedná se přeci o družinu
PARTY ... typ cíle družina
0
FX/NoEffect
10
350
NONE

Když poté koukneme na klíč FIRE_WARD do souboru PartyBuffs.csv, uvidíme následující:

1,FIRE_WARD,PARTYBUFF_FIRE_WARD_NAME,PARTYBUFF_FIRE_WARD_DESCRIPTION,SPL_fire_FireWard,4,FALSE,TRUE,
0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,FALSE,FX/Buffs/WardBuffFX

První hodnoty jsou jasné (klíče pro loca.xml), číslo 4 určuje základní délku trvání kouzla a ta halda čísel dále je pak základní hodnota navýšení pro konkrétní atribut. V tomhle případě kouzlo trvá 4 kola a v základu zvyšuje odolnost proti magii ohně o 5.

Se závislostmi na souborech MonsterBuffs.csv a SummonStaticData.csv se pracuje obdobně. Za povšimnutí stojí poznámka, že mezi specifikacemi najdete i efekty z dovednosti Válečnictví, protože u nich se v principu opravdu jedná o typ magie.

Elemir:
Pokračování Magie

Potřeboval jsem se nějakým elegantním způsobem dostat k možnosti učit se kouzla Magie temnoty a podívat se i na bonusy dovednosti Válečnictví, které se chovají taktéž jako kouzla. Jenomže v družině jsem neměl nikoho, kdo by to dokázal. Měl jsem proto dvě možnosti, buďto si sehnat save s patřičnými povoláními (případně hru rozehrát znovu s nimi), nebo to zkusit vyřešit předefinováním chování kouzel vs dovednosti. Asi nemusím dodávat, že jsem se rozhodl pro druhou možnost :D.

Rozhodně nejsem první, kdo se zkoumáním datových souborů hry zabývá a na oficiálním fóru jsem našel odkaz na Wiki jedné skupinky, kde byla popsána jednoduchá úprava bez známých vedlejších efektů. Když jsem seděl nad svým problémem, tak jsem si na to vzpomněl a rozhodl se zkusit podobný postup aplikovat i na bonusy Válečnictví, což představuje o stupeň více závislostí. Začnu ovšem od toho jednoduššího.

V principu se nejedná o nic převratného, opět platí, že i jednoduchý zásah může mít značný vliv. Vezmu jako příklad kouzlo Jiskry. V souboru CharacterSpellsStaticData.csv najdeme:

22,SPELL_AIR_SPARKS,SPELL_AIR_SPARKS_DESCRIPTION,
NONE,NONE,NONE,SKILL_AIR_MAGIC,
NOVICE,SPL_air_Sparks,"AIR,10,20",1,ALL_ADJACENT_MONSTERS,0,FX/Spark s,15,350,NONE

Podstatný je pro nás modře zvýrazněný klíč SKILL_AIR_MAGIC, který definuje příslušnost kouzla ke konkrétní škole magie. Pokud ho změním např. na SKILL_FIRE_MAGIC, bude se kouzlo Jiskry schopné naučit postava s patřičnou úrovní (NOVICE = normální) dovednosti Magie ohně. Kouzlo tak úplně vypadne ze školy Magie vzduchu.

Samozřejmě by šlo také pomocí nového StaticID kouzlo naklonovat a obě ID by se lišily akorát školou magie. Jen byste narazili na problém, že by kouzlo nebylo ve hře normálně dostupné - nenabízel by ho např. žádný učitel kouzel (pokud byste kouzlo nenadefinovaly rovnou jako bonus k odemčení školy magie). V takovém případě totiž musíte sáhnout i do souboru SpellOffers.csv, kde některému z učitelů doplníte do seznamu SaticID svého "nového" kouzla. Jak vidno, úprava jako taková je celkem triviální, ale zbytek kolem už je komplikovanější ;)

Poznámka: Teď si uvědomuju, že jsem celou dobu zamlčel jedno upozornění. Mě to přišlo jako samozřejmost, ale pro ty z vás, kdo se v databázích a spol. moc neorientují - "Každý datový soubor smí mít jen jedno unikátní StaticID!" Nelze mít vedle sebe dvě stejné hodnoty, protože by je hra nedokázala od sebe rozlišit a vedlo by to k problémům. Řádky, které začínají znakem # se berou jako komentáře a hra je nenačítá.

Přemapování Válečnictví

Pokud si budeme chtít troufnout i na takovou změnu, jako je přemapování bonusů Válečnictví na jinou dovednost, třeba právě jinou školu magie, pak musíme v první řadě předefinovat příslušnost všech bonusů do nově vybrané školy. Jedná se o následující položky ze souboru CharacterSpellsStaticData.csv:

71,WARFARE_CHALLENGE,WARFARE_CHALLENGE_DESCRIPTION,
NONE,NONE,PROVOKE,SKILL_WARFARE,
NOVICE,SPL_warfare_Challenge,,1,SINGLE_MONSTER,0,FX/NoEffect,5,0,NONE
72,WARFARE_SKULL_CRACK,WARFARE_SKULL_CRACK_DESCRIPTION,NONE,NONE,MEMORYGAP,
SKILL_WARFARE,EXPERT,
SPL_warfare_SkullCrack,,1,SINGLE_MONSTER,0,FX/NoEffect,10,0,NONE
73,WARFARE_UNSTOPPABLE_ASSAULT,WARFARE_UNSTOPPABLE_ASSAULT_DESCRIPTION,NONE,NONE,NONE              ,
SKILL_WARFARE,EXPERT,SPL_warfare_UnstoppableAssault,,1,SINGLE_MONSTER,0,FX/NoEffect,              10,0,NONE
74,WARFARE_INTERCEPT,WARFARE_INTERCEPT_DESCRIPTION,NONE,NONE,NONE,
SKILL_WARFARE,MASTER,SPL_warfare_Intercept,,1,SINGLE_PARTY_MEMBER,0,FX/NoEffect,15,0              ,NONE
75,WARFARE_FURIOUS_BLOW,WARFARE_FURIOUS_BLOW_DESCRIPTION,NONE,NONE,NONE,
SKILL_WARFARE,MASTER,SPL_warfare_FuriousBlow,,1,SINGLE_MONSTER,0,FX/NoEffect,0,0,NON              E
76,WARFARE_TAUNT,WARFARE_TAUNT_DESCRIPTION,NONE,NONE,PROVOKE,
SKILL_WARFARE,GRAND_MASTER,SPL_warfare_Taunt,,1,ALL_MONSTERS,0,FX/NoEffect,45,0,NONE              
77,WARFARE_FLAWLESS_ASSAULT,WARFARE_FLAWLESS_ASSAULT_DESCRIPTION,NONE,NONE,NONE,
SKILL_WARFARE,GRAND_MASTER,SPL_warfare_FlawlessAssault,,1,SINGLE_MONSTER,0,FX/NoEffe              ct,25,0,NONE90,WARFARE_SHATTER,WARFARE_SHATTER_DESCRIPTION,NONE,NONE,SUNDERING,
SKILL_WARFARE,NOVICE,SPL_warfare_Shatter,,1,SINGLE_MONSTER,0,FX/NoEffect,5,0,NONE

kde všechny klíče SKILL_WARFARE zaměníme např. za klíč SKILL_LIGHT_MAGIC. Tím určíme příslušnost těchto bonusů k Magii světla. Nyní už stačí jen provést přemapování hodnot Tier1Effects až Tier4Effects v souboru Skills.csv:

originální položky Válečnictví a Magie světla -

11,SKILL_NAME_WARFARE,SKILL_DESC_WARFARE,SPL_skill_misc_Warfare,"135,136,172","137,138","139,140","141,142",0,MISC
23,SKILL_NAME_LIGHT_MAGIC,SKILL_DESC_LIGHT_MAGIC,SPL_skill_magic_Light,"53,164",54,55,"110,56",1,MAGIC

Prostě jen vezmeme zeleně zvýrazněnou část a přepíšeme s ní tu modře zvýrazněnou. Tím hře řekneme, že k dovednosti Magie světla se vážnou válečnické bonusy

23,SKILL_NAME_LIGHT_MAGIC,SKILL_DESC_LIGHT_MAGIC,SPL_skill_magic_Light,
"135,136,172","137,138","139,140","141,142",1,MAGIC

... tedy následující řádky ze souboru SkillEffects.csv se přiřadí k Magii světla:

135,SKILL_EFFECT_WARFARE_MANA,SKILL_EFFECT_WARFARE_CURRENT_MANA,
FALSE,TRUE,NONE,INCR   EASE_MAXIMUM_MANA,2,PER_SKILL_LEVEL
136,SKILL_EFFECT_WARFARE_LEARN_CHALLENGE,,FALSE,TRUE,NONE,LEARN_SPELL,71,NONE
137,SKILL_EFFECT_WARFARE_LEARN_SKULL_CRACK,,FALSE,TRUE,NONE,LEARN_SPELL,72,NONE
138,SKILL_EFFECT_WARFARE_LEARN_UNSTOPPABLE_ASSAULT,,FALSE,TRUE,NONE,LEARN_SPELL,73,NONE
139,SKILL_EFFECT_WARFARE_LEARN_INTERCEPT,,FALSE,TRUE,NONE,LEARN_SPELL,74,NONE
140,SKILL_EFFECT_WARFARE_LEARN_FURIOUS_BLOW,,FALSE,TRUE,NONE,LEARN_SPELL,75,NONE
141,SKILL_EFFECT_WARFARE_LEARN_TAUNT,,FALSE,TRUE,NONE,LEARN_SPELL,76,NONE
142,SKILL_EFFECT_WARFARE_LEARN_FLAWLESS_ASSAULT,,FALSE,TRUE,NONE,LEARN_SPELL,77,NONE
172,SKILL_EFFECT_WARFARE_LEARN_SHATTER,,FALSE,TRUE,NONE,LEARN_SPELL,90,NONE

Červeně jsou zvýrazněny StaticID pro svázání s konkrétním bonusem ze souboru CharacterSpellsStaticData.csv. Pokud bychom bývali nepředefinovali dovednosti (školy magie) u jednotlivých bonusů v CharacterSpellsStaticData.csv, hra by nám sice pod Magií světla hlásila navázané bonusy, ale postava by je nedokázala odemknout, protože by nesouhlasila škola magie! (Prostě bychom na to neměli odbornost.) Ovšem takhle nám přiřazení bonusů k úrovni dovednosti Magie světla bude fungovat v pořádku. Např. odemčením Magie světla se postava automaticky naučí bonusy Výzva (StaticID 71) a Roztříštění (StaticID 90).

Edit: Samozřejmě nemusíte kvůli tomu hned rušit původní definici Magie světla, klidně je možné ji nechat v základu stejnou a jen ji o bonusy doplnit, např.

23,SKILL_NAME_LIGHT_MAGIC,SKILL_DESC_LIGHT_MAGIC,SPL_skill_magic_Light,
"53,164,136,172","54,137,138","55,139,140","110,56,141,142",1,MAGIC

zachová původní koncept, ale za každou úroveň postava ještě získá 2 válečnické bonusy. Samozřejmě stále platí, že všechny načítané válečnické bonusy musí být předefinované pro Magii světla.



Předefinování defaultního kouzla

Podobně funguje i provázání školy magie s defaultním kouzlem. Např. pro Magii vody najdeme ve Skills.csv záznam:

20,SKILL_NAME_WATER_MAGIC,SKILL_DESC_WATER_MAGIC,SPL_skill_magic_Water,
"41,153",42,43,"107,44",1,MAGIC

Zajímá nás v principu jen Tier1Effects, kde podle něj v souboru SkillEffects.csv najdeme řádek, který defijuje defaultní kouzlo:

153,SKILL_EFFECT_WATER_LEARN_SPELL_4,,FALSE,TRUE,NONE,LEARN_SPELL,34,NONE

... 34 je StaticID pro kouzlo Ledový šíp (CharacterSpellsStaticData.csv).

Pokud ho budeme chtít jen zaměnit např. za defaultní kouzlo Magie temnoty (Stínový plášť), pak jen změníme propojení v Tier1Effects, kde hodnotu 153 zaměníme za 168:

20,SKILL_NAME_WATER_MAGIC,SKILL_DESC_WATER_MAGIC,SPL_skill_magic_Water,
"41,168",42,43,"107,44",1,MAGIC

Ovšem aby to fungovalo, musíme zároveň u kouzla Stínový plášť změnit dovednost z Magie temnoty na Magii vody. Anebo to prostě celé provázat přes nové definice ID.

Navigace

[0] Seznam témat

[#] Další strana

Přejít na plnou verzi