Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - DV

Pages: [1]
1
Releases / Re: Final Fantasy IX PC Complete Sounds Fix
« on: 2022-03-31 12:16:20 »
Better late than never but i made my own FFIX Sounds Fix ;) More complete than this one i have tested !

I fixed the sounds below :

- Some sounds used in the menu (the most used anyway).
- All magic spells (Black, White, Blue + the casting spell effect).
- All summons (Dagga and Eiko), include long and short versions.
- All skills/technics from characters (Skill, Dyne, Dragon, Flair, Elan, Swd Art, Swd Mag, Jump, Throw, Focus, Eat, Cook).
- All items usuables in fight (Potion, Hi-Potion, Ether, Elixir, Phoenix Down, Echo Screen, Soft, Antidote, Eye Drops, Magic Tag, Vaccine, Remedy, Annoyntment, Dark Matter, Gysahl Greens, Dead Pepper, Tent, Ore).
- All enemy attacks (including special moves like Ultima or the death of certain bosses.)
- All weapons attacks (player and enemies).
- Somes sounds from Tetra Master.
- Three sounds of Choco when he digs and finds treasures in "Chocobo Hot and Cold".

Need Memoria to use my fix.
You can find more informations on my Steam page : https://steamcommunity.com/app/377840/discussions/0/3189117724409401717/

2
For you ChikoLad :

1)
Code: [Select]
03.08.2020 10:04:18 |E| [SoundLib] File not found AT path: Sounds/Sounds01/BGM_/music123.akb
It's seem that the issue, are you sure your BGM is located in StreamingAssets folder ?

When the game will use your music, it will automatically create an .akb file to be able to use it in game: you just have to create an .ogg file for it to work.

But right now, it looks like it can't find your file... Check the path in Memoria.ini to make sure it's directed to the right folder.
If you still have doubts, you can use the "Export" function in Memoria.ini and see in which folder it will export the files (which is logically the same path).

2) You need to check the Script, on Beatrix_ATB and remove this :

Code: [Select]
    if ( turncounter < 10 ) {
        set turncounter++
    } else {
        set finishfightflag = 1
    }
    if ( finishfightflag && ( !( #Matching(SV_PlayerTeam[STATUS_CURRENT_B], 64) ) ) ) {
        set climhazzardwaiting = 1
        set #( SV_Target = SV_PlayerTeam )
        Attack( 5 )
        return
    }

After that, you need to adjust her HP and you can remove this part too on Beatrix_Loop (if you want her "Die" animation or not... as you want !)

Code: [Select]
if ( !endflag ) {
        if ( #( SV_FunctionEnemy[HP] <=$ 10000 ) ) {
            set finishfightflag = 1
        }
        if ( finishfightflag ) {
            set SV_FunctionEnemy[HP] =$ FirstOf(SV_FunctionEnemy[MAX_HP])
            set SV_FunctionEnemy[ATB] =$ FirstOf(SV_FunctionEnemy[MAX_ATB])
            if ( climhazzardwaiting ) {
                if ( #Matching(SV_PlayerTeam[STATUS_CURRENT_B], 64) ) {
                    set climhazzardwaiting = 0
                    set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1
                } else {
                    if ( GetAttacker == SV_FunctionEnemy ) {
                        if ( GetTarget && ( #( NotMatching(SV_PlayerTeam[STATUS_CURRENT_A], 257) & NotMatching(SV_PlayerTeam[STATUS_CURRENT_B], 64) ) ) ) {
                            set endflag = 1
                            Wait( 5 )
                            if ( GetBattleState != 4 ) {
                                return
                            }
                            RunBattleCode( 32, 0 )
                            while ( GetBattleState != 1 ) {
                                Wait( 1 )
                            }
                            set #( SV_Target = SV_FunctionEnemy )
                            AttackSpecial( 7 )
                            while ( IsAttacking != 0 ) {
                                Wait( 1 )
                            }
                            RunBattleCode( 33, 1 )
                            return
                        }
                    }
                }
            } else {
                if ( !( #Matching(SV_PlayerTeam[STATUS_CURRENT_B], 64) ) ) {
                    set SV_FunctionEnemy[PREVENT_ATTACK] =$ 1
                }
            }
        }
    }

3) Yes of course, you can make an attack which call "Trance" function. You can simply copy/paste "Trance Full" from BlackWaltz 3 for example and use his script on ATB.
After that, you need to precise the target for "Trance Full"

You can uses theses script if you want :
On Loop function, at the end (if the script already have this part.. skip)
Code: [Select]
  set #( zidane = ( SV_PlayerTeam[MODEL_TYPE] ==$ 0 ) )
        set #( zidane |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 1 ) )
        set #( vivi = ( SV_PlayerTeam[MODEL_TYPE] ==$ 2 ) )
        set #( dagger = ( SV_PlayerTeam[MODEL_TYPE] ==$ 3 ) )
        set #( dagger |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 4 ) )
        set #( dagger |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 5 ) )
        set #( dagger |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 6 ) )
        set #( steiner = ( SV_PlayerTeam[MODEL_TYPE] ==$ 7 ) )
        set #( steiner |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 8 ) )
        set #( quina = ( SV_PlayerTeam[MODEL_TYPE] ==$ 9 ) )
        set #( eiko = ( SV_PlayerTeam[MODEL_TYPE] ==$ 10 ) )
        set #( eiko |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 11 ) )
        set #( freya = ( SV_PlayerTeam[MODEL_TYPE] ==$ 12 ) )
        set #( amarant = ( SV_PlayerTeam[MODEL_TYPE] ==$ 13 ) )
        set #( marcus = ( SV_PlayerTeam[MODEL_TYPE] ==$ 15 ) )
        set #( ciblagepola = ( SV_PlayerTeam[MODEL_TYPE] ==$ 16 ) )
        set #( ciblagepola |= ( SV_PlayerTeam[MODEL_TYPE] ==$ 17 ) )
        set #( beatrix = ( SV_PlayerTeam[MODEL_TYPE] ==$ 18 ) )

If you want to use this part, don't forget to use theses variables :
Code: [Select]
allocate 51

global uint16 zidane VAR_GlobUInt16_24
global uint16 vivi VAR_GlobUInt16_26
global uint16 dagger VAR_GlobUInt16_28
global uint16 steiner VAR_GlobUInt16_30
global uint16 quina VAR_GlobUInt16_32
global uint16 eiko VAR_GlobUInt16_34
global uint16 freya VAR_GlobUInt16_36
global uint16 amarant VAR_GlobUInt16_38
global uint16 marcus VAR_GlobUInt16_40
global uint16 ciblagepola VAR_GlobUInt16_42
global uint16 beatrix VAR_GlobUInt16_44

local uint8 tranceflag VAR_LocUInt8_46

On ATB function :

Code: [Select]
    if ( !tranceflag ) {
        set tranceflag = 1
        if ( #( NotMatching(SV_PlayerTeam[STATUS_CURRENT_A], 4419) & CHARACTER ) ) {  <=== Choose your CHARACTER (from variables)
            set #( SV_Target = CHARACTER ) <=== Choose your CHARACTER (from variables)
            Attack( 4 )  <===== Use Attack which call Trance !
            return
        }
    }

As far as I'm concerned, you just have to take inspiration from already existing scripts... just have a look and you'll see that it's very simple ^^

4) Yes, just add some Battle Texts (just below the list of attacks and enemy groups).
You can call them by using Attack Animation (using Battle Text, for example Climhazzard from Beatrix) or using BattleDialog([INSERT ID NUMBER]) on Script.

3
Hi everyone, i have a little question too...

I am currently working on CD1 (Steam version ofc) but i have something strange.

I edit Phoenix Pinion into Ether + but i got something weird : I confronted somes ennemis on Guismar's Cavern and died but.... Phoenix appears  :? :? !! (I didn't have Eiko lol)

So it seems my Ether + use Rebirth Flame mechanic, i just add 99 Ether + on my save and Phoenix comes again... when i remove all my Ether +, only get Game Over.

I don't know why this happens, i never edit script from Phoenix or something... i can't find the formula about Rebirth Flame : (No. of Phoenix Pinion/256) * 100%.

Someone have an idea about that ?  :-X

PS : One on my player record this => https://www.youtube.com/watch?v=z2kscLduWFc

EDIT : I just add "Phenix" on Ether + abilities, that's fix the softlock... but still didn't know why that's summon Phenix.

EDIT2 : I just did another test at the beginning of the game (first zone, juste before PrisonCage, with solo Zidane). I get 99 Ether + on my inventory.... Phoenix still appears  :?

EDIT3 : I test with Memoria without my mod, give 99 Phoenix Pinion on same spot => No Phoenix appears.

But i just found the function which call Rebirth Flame ! (btl_sys on FF9 folder)

Code: [Select]
for (BTL_DATA next3 = ff9Battle.btl_list.next; next3 != null; next3 = next3.next)
{
if (btl_util.getSerialNumber(next3) - 10 <= 1)
{
if (Status.checkCurStat(next3, BattleStatus.Petrify | BattleStatus.Venom | BattleStatus.Zombie | BattleStatus.Stop))
{
break;
}
if (btl_cmd.CheckSpecificCommand(next3, BattleCommandId.SysLastPhoenix))
{
return;
}
if (ff9item.FF9Item_GetCount(249) > Comn.random8())
{
UIManager.Battle.FF9BMenu_EnableMenu(true);
btl_cmd.SetCommand(next3.cmd[0], BattleCommandId.SysLastPhoenix, 73U, btl_scrp.GetBattleID(0U), 1U);
return;
}
}
}
ff9Battle.btl_seq = 1;
UIManager.Battle.SetBattleFollowMessage(5, new object[0]);

I just edit ID item from Ether + to Phoenix Down => Works !.... but Phoenix still appears without Eiko.

I modify this line : if (btl_util.getSerialNumber(next3) - 10 <= 1) by something else like if (btl_util.getSerialNumber(next3) == 7) : Phoenix isn't coming anymore (but i am pretty sure i break Rebirth Flame for the moment...).

I didn't know where to find the Eiko death condition to trigger Rebirth Flame... still searching !

4
Hi! I hope you're having a good weekend :)

I come back with a little question : how does translation works on HW? Since I've been using it, everything is grayed out ^^ It's not implemented yet?


5
Thank you again for your quick and detailed response Tirlititi  ;)

I didn't update Memoria yet (i don't want to break something....  :-X) but I'm almost done finishing the CD1 (I'll make a demo I think).

As soon as I finish this first part, I'll do a last run and I'll make some tests with your proposition (because I have a mob that uses a kind of "Slowaga" and I'd like to make the animation cooler ^^)

Need to make both .dll from Moguri (which I am currently using) and Memoria too...  :'(

6
Sorry for double post but i have a little question about Spell Animations : is it possible to duplicate an existing animation ?

For example, i want to create a "Slow (Multi)", without changing the existing one (Slow).

I see some unused spell animation but how can we interact with them ?

7
Hello everyone, I hope you're well!

I have a small question that does not concern HW but Memoria Scripts (precisely C#, because I'm a beginner in this...)

I'm trying to modify a magic, which basically takes into account the PV difference but i want to use a logarithm function instead.

Here is the test code i am using :

Code: [Select]
double factor = Math.Abs(Math.Round(Math.Log((double)(this._v.Caster.CurrentHp / this._v.Caster.MaximumHp)), 2));
this._v.NormalMagicParams();
this._v.Caster.PenaltyMini();
this._v.Target.PenaltyShellAttack();
this._v.PenaltyCommandDividedAttack();
this._v.CasterCommand.BonusElement();
if (this._v.CanAttackMagic())
{
this._v.TargetCommand.CalcHpDamage();
this._v.TargetCommand.TryAlterMagicStatuses();
this._v.Target.HpDamage = (short)factor;
}

The final formula will be something like this :
Code: [Select]
short hpDamage = (short)Math.Min(9999, this._v.Context.PowerDifference * (int)this._v.Context.EnsureAttack * factor);
However, on my first code, the HpDamage always shows 0.
Trying with/without Math.Round (to have more precision) and Convert.ToInt16 => That's doesn't work.

Can't the game use this kind of complex functions or am I on the wrong way ?

Thanks in advance  :lol:

EDIT : Whatever... i found it. Sorry for this useless post  :-[

Code: [Select]
public void Perform()
{
int factor = (int)Math.Abs(Math.Floor(Math.Log((double)this._v.Caster.CurrentHp / (double)this._v.Caster.MaximumHp)));
this._v.NormalMagicParams();
this._v.Caster.PenaltyMini();
this._v.Target.PenaltyShellAttack();
this._v.PenaltyCommandDividedAttack();
this._v.CasterCommand.BonusElement();
if (this._v.CanAttackMagic())
{
this._v.TargetCommand.CalcHpDamage();
this._v.TargetCommand.TryAlterMagicStatuses();
short hpDamage = (short)Math.Min(9999, this._v.Context.PowerDifference * (int)this._v.Context.EnsureAttack * factor);
this._v.Target.HpDamage = hpDamage;
}
}

8
I thought it would be a pain to solve this problem but you just need one Tirlititi to solve it in a few minutes... incredible, you impress me ahah!

It works perfectly  ;D... except during my tests : I've just learned something... SFX does the damage too! (I get double damage for each hit, i didn't understand at first  ???)

So, when I use SFX instead of Effect Point, I have the same problem: the damage is only shown for the last SFX applied.

EDIT : I just read again your sentence =>
Quote
The "Run Spell Animation" and "SFX" codes should give the hand to a generic "Spell Animation" and thus show the numbers every time. However, for both of them, it's not possible to have two different generic "Spell Animations" running at the same time.

I suppose that's works too when you use same multiples "SFX" on same animation so. I just realized that it's the SFX that triggers the damage report.

I'll see if I can find a way to do it without breaking everything, otherwise I'll just use the Effect Point ^^. I think i will use Effect Point instead xD Too sad.

Thanks again Tirlititi.

9
I have a little question Tirlititi : currently, i create/edit some moves to make combo attacks (serious lack on FFIX).

But i have a little issue... juste here :



I use "Effect Point" on "Edit Animation" for each hit. Of course that's works but it missing something : showing damage HP for each hit.

With spell animation, it's pretty simple to make this kind of manipulation.
However, with basic enemy attack... it's only show the last hit.

So my question : you think it's possible to show HP value for each hit ? (maybe with DnSpy or something, to edit Effect Point or by using another trick/idea  ;D).

If this is not possible or too complicated, no worries! I'll do without ^^
Thanks in advance !

10

@DV:
1°) Yes, there should be no problem copy/pasting a Ghost in the list of enemies for that battle so you have two different Ghosts; the game doesn't care if they have the same models or such... Just maybe uncheck the option "Edit similar enemies" when you do that. Once your super-ghost is given a different level or name, though, you can enable back that option because it won't be considered similar to the other ghosts by HW anymore.

I never see this option to "Edit similar enemis"..... i am blind lol.
That's perfect o/ Thanks !

2°) You can't do that by default unfortunatly :/
It goes down to the functionalities implemented in btl_scrp. You can see that you can access to the status properties ("GetCharacterData", cases 42-45) but can't modify them ("SetCharacterData", there's no cases 42-45). In AF's source files, there are codes for improving that part though and, in particular, let scripts be able to do that, so you can mod the DLL to add (at least) that feature and then use it in your HW scripts. I am not sure how we will implement all the features I need for AF in a next version of Memoria but it can be safely assumed that for statuses it will be implemented like that (for the new features that were not present at all, such as modifying a spell's stat during the battle, I may make it optional or external...).

Oh ok, i just discover that when testing an IA Boss so... that's not important ^^ Thanks for the clarification !

3°) The 3D models of their attacks' SFX? You can't. They are not in a format that could be recognized by any model ripping software :/
However, Tasior2's FF9 Reverse tool was able to get a couple of very specific SFX models very well, but it's limited (IIRC, the "Correct answer" and "Wrong answer" SFX of the Ragtime Mouse were amongst the only ones to be read thanks to it).

Woops ! I didn't mean SFX but Sound Effect... sorry  ;D
Somes sounds effects on Steam version are... yeah that's something. For example Lancer/Ryuken from Freyja, i swear i can hear a dolphin dying at the end  :o :-D Wth.

I found a .zip with all sounds effects from Characters but can't find from Monsters... any idea to get theses files ?

11
I have 2-3 questions as well ^^

1°) About this part "Properly adding a new enemy to a battle (Steam), i make a special combat with 4 Ghosts (1 King and 3 Minions) : however, they have same stats (i can bypass this with SV_FunctionEnemy so np).

But i can't modify drops for Ghost King for example... it will alter the drops of all the ghosts as well. So my question is : it's possible to separate 2 ennemis with same model, to make 2 distincts ID (something like that) ?

I see the game can do that, some examples with Zaghnol/Mu/Feng from Lindblum or monsters from Treno Arena : there is a way to make that ?

2°) About SV_FunctionEnemy, i see you can edit elemental affinities on battle with SV_FunctionEnemy[ELEMENT_IMMUNE], SV_FunctionEnemy[ELEMENT_WEAK], SV_FunctionEnemy[ELEMENT_ABSORB] and SV_FunctionEnemy[ELEMENT_HALF] (ex : Malboro script)

But i can't edit status effect with SV_FunctionEnemy (STATUS_IMMUNE, STATUS_AUTO and STATUS_CURRENT)... i can read the value in battle (with a Battle Text) but can't find a way to change the value  :-\ is there any way to change that or not by chance?

3°) Not a HW question but.... where i can find all monster attacks SFX from PSX ?  :-D Try to search on .iso/.bin PSX games but... damn ^^ Can't find theses files !

12
It's the exact same sounds used for Thunder-Slash-2 and Thunder-Slash-3. I don't know if you have access to the spell effect IDs in HW (I think not) but they are listed there.

If I understood correctly, sounds in the meta-data are listed by their order of usage.

Oooooohhh... perfect ! That's what i need !  ;D

Indeed, theses IDs are not available on "Spell Animation" but now, that's will be perfect to fix somes crappy sounds (like Thunder Slash or when Steiner cast something... rip my ears)

Thank you again Tirlititi  :)

13
DV, friends, if you notice any problem in the game engine (equipment is incorrectly displayed) or in the Memoria (music is not exported), do not hesitate to write about it:
https://github.com/Albeoris/Memoria/issues


I didn't report this issue atm because I don't know if the problem comes from my side or from Memoria.
I will test tomorrow on my laptop : if the problem happens again, I'll open a ticket on Github :)

By the way, i have a question (for Tirlititi) : it's possible to know exactly which sound effect (.akb files from p0data62 or p0data63) is used by a spell animation ?
I try to find this information on "Environment/Spell Animations"... it doesn't seem to be there (or i can read this kind of information)

For example, can't find SFX files for Thunder Slash (Steiner/Beatrix).

14
Update : 26 November 2023

So here is a little tutorial to add music WITHOUT replacing the existing ones

You will need just Audacity for that but don't worry, it's very simple !

Sorry in advance if I make grammatical or spelling mistakes :)

I) Create/Prepare your soundtrack

First of all, you need to prepare your music with Audacity (or another software if possible).

/_!_\ Open Audacity's config (Ctrl + P), then go in Import/Export and check if the option is enabled => Show Metadata Tags editor before export

On this first step, we need to create two metadata on your file : "LoopStart" and "LoopEnd". Indeed, Memoria can convert .ogg in another format with an AKB header (the important part !).
This header will contain the loop region from your music : this step is essential to make an appropriate OST for FF9.

At the bottom of the screen, right click on numbers and select "samples."



Open your audio file with Audacity and create looping region, you can use labels (Tracks -> Add Label or Ctrl + B).

These labels are optional but are very useful to visualize the loop. Of course, these two points in the song MUST sound exactly the same !



Once your loop is in place, select the region between theses labels and note the number of frames of the loop start and the loop end.



On this example : Loop Start = 4095758 and LoopEnd = 9166785.

Export your file in .ogg format and the metadata window will pop up.

On this window, "Add" two lines and name them EXACTLY : LoopStart and LoopEnd, with their respective values (frames number), like this :



Save as music123.ogg for example and now, you need to create a specific folder on the selected path : StreamingAssets\assets\resources\Sounds\Sounds01\BGM_

II) Add an index for your soundtrack

Download this file from this link => Pastebin link !

Rename it musicmetadata.txt and place it in this folder :
- If you don't use mods => FINAL FANTASY IX\x64\FF9_Data\Resources\resources\embeddedasset\manifest\sounds
- If you use mods, take the folder with the highiest priority and place it here => FINAL FANTASY IX\[YOUR MOD]\FF9_Data\Embeddedasset\manifest\Sounds

On this file, add theses lines at the end :

Code: [Select]
{
      "name": "Sounds01/BGM_/music123",
      "soundIndex": "149",
      "type": "Music"
    }

You must have something like that... carefull with commas !

Code: [Select]
    {
      "name": "Sounds01/BGM_/music121",
      "soundIndex": "148",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music122",
      "soundIndex": "147",
      "type": "Music"
    }, <======= Don't forget the comma here !
    {
      "name": "Sounds01/BGM_/music123",
      "soundIndex": "149",
      "type": "Music"
    }
  ]
}

To check IDs available, you can check here => List of musics (FF9)

Save your musicmetadata.txt.

After that, you can edit "BtlEncountBGMMetaData.txt" (for battles on the field) and "WldBtlEncountBGMMetaData.txt" (for battles on the map) from the ressources.assets to add your music. You can extract these files from Hades Workshop, with the Unity Assets Viewer.

/_!_\ The ID you must use is the "soundIndex" ! For our previous example, the ID will be 149 and not 123 !

If you forget how to change ID music from battle => Changing the battle music of specific battles (Steam)

And... that's all ! Congrats !  ;)

Hopefully, when you will launch a battle with your new soundtrack, Memoria will create your soundtrack with .akb header.

If you encounter any difficulties, don't hesitate to consult the Memoria.log file to see what happens.

Hope that's will be helpfull if you want to make various battle with differents soundtracks !

PS : Didn't test yet but i suppose you can make this same logic with SoundEffect (dictionnary SoundDisplayNames on Memoria and soundeffectmetadata.txt on ressources.assets)

15
Memoria adds a way to import new sounds through the class Memoria.SoundImporter. It requires the sound to be in .ogg format and I guess that you need to setup a "SoundProfile" yourself (setup an unused soundID and the proper SoundProfileType, etc). It must be possible and easier than importing a new 3D model in any case, but don't try to add it inside the archive, only in a sub-folder of the game (or Moguri mod's folder if it's inside "StreamingAssets").

... I just forget export/import option on Memoria.ini  ;D

But, how convinient, Memoria can export all folders EXCEPT... Music...



On Memoria.log, no AudioResourceExporter called... wut

Quote
02.05.2020 06:42:17 |M| [TextResourceExporter] Pass through {Configuration.Export.Text = 0}.
02.05.2020 06:42:17 |M| [GraphicResourceExporter] Pass through {Configuration.Export.Graphics = 0}.
02.05.2020 06:42:17 |M| [FieldSceneExporter] Pass through {Configuration.Export.Field = 0}.
02.05.2020 06:42:17 |M| [BattleSceneExporter] Pass through {Configuration.Export.Battle = 0}.
02.05.2020 06:42:17 |M| [ResourceExporter] Application will now quit. Please disable Configuration.Export.Enabled and restart the game.
02.05.2020 06:42:17 |M| [ResourceImporter] Pass through {Configuration.Import.Enabled = 0}.
02.05.2020 06:42:17 |M| [GameLoopManager] RaiseQuitEvent

Maybe i will try later with an another fresh Memoria instance.

EDIT : I can import music with Memoria but export didn't work.... idk why. I will continue my test with import but i see Memoria create a similar file with .ogg file but i can't read this (no extension and have same name)

EDIT2 : With a HEX editor, i see it's an .akb file but there is a way to read the AKB Header ? I know the size is 304 bytes but there is a way to read this header clearly or extract his informations ?
(Thanks for this answer btw ^^)

EDIT3 : I make some test how we create LoopStart and LoopEnd on .ogg files with Audacity... check !  8-)
I think i finally "decrypt" this akb head with AKB2Header on Memoria.Prime.dll : I didn't find what I was looking for but i learn something.

Spoiler: "Here is an image about AKB Header details • show

I don't know why some values are null but works perfectly with .akb files from UAV !

Red for constant or optional.


Musics played in battles are indeed in these .txt files. They consist of a list of field IDs (or World Map IDs) and for each of them, a list of battle IDs encountered in these fields and the music linked to it. If the battle is not present, then the music is uninterrupted.
For my mod, I simply didn't change these files but I've put a line "Play Music" in the field scripts right before triggering some boss battles (something like "RunSoundCode( MusicID )" although I don't remember which "RunSoundCode" alternative should be used). That solution doesn't work with random encounters though.

I already figure that with theses explications you provided : List of Music ID & Changing the battle music of specific battles (Steam).
I read a lot of informations provided on first page, very usefull for beginner like me ^^ (specially IA, content chest, status and so many things !)

But the point is, i didn't figure how the game correlate "this List of ID Music" on p0data61.

For example, you provide us Dark Messenger's ID is 134. In my research, i found theses lines on FF9DBAll :

Code: [Select]
// Token: 0x04001E7E RID: 7806
public const int SNG_MUSIC095 = 131;

// Token: 0x04001E7F RID: 7807
public const int SNG_MUSIC096 = 132;

// Token: 0x04001E80 RID: 7808
public const int SNG_MUSIC097 = 133;

// Token: 0x04001E81 RID: 7809
public const int SNG_MUSIC098 = 134;

// Token: 0x04001E82 RID: 7810
public const int SNG_MUSIC099 = 135;

// Token: 0x04001E83 RID: 7811
public const int SNG_MUSIC100 = 64;

// Token: 0x04001E84 RID: 7812
public const int SNG_MUSIC101 = 71;

// Token: 0x04001E85 RID: 7813
public const int SNG_MUSIC102 = 77;

SNG_MUSIC098 = 134 (Dark Messenger). And MUSIC098 on p0data91 for Dark Messenger is number 98.

But nothing happen if i change this value... so with your previous answer, i suppose Memoria ignore this file and make this own method (this file seem useless because nothing use it)
But still : if i change 0 to 134 value on a field battle, how the game know 134 = Dark Messenger ?

EDIT : I try to use an unknown ID Music (exemple : 149) on btlencountbgmmetadata.txt and i get theses logs on Memoria.log .

Code: [Select]
03.05.2020 09:02:01 |W| [SoundLib] Music Id: 149 has Exception: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
03.05.2020 09:02:01 |W|   at System.Collections.Generic.Dictionary`2[System.Int32,System.String].get_Item (Int32 key) [0x00000] in <filename unknown>:0
03.05.2020 09:02:01 |W|   at SoundMetaData.GetSoundProfile (Int32 soundIndex, SoundProfileType type) [0x00000] in <filename unknown>:0
03.05.2020 09:02:01 |W|   at AllSoundDispatchPlayer.CreateSoundProfileIfNotExist (Int32 soundIndex, SoundProfileType type, .OnCreateFinish onFinishDelegate) [0x00000] in <filename unknown>:0
03.05.2020 09:02:01 |W|   at AllSoundDispatchPlayer.FF9SOUND_SONG_PLAY (Int32 ObjNo, Int32 vol) [0x00000] in <filename unknown>:0
03.05.2020 09:02:01 |W|   at FF9Snd.FF9AllSoundDispatch (Int32 ParmType, Int32 ObjNo, Int32 Arg1, Int32 Arg2, Int32 Arg3) [0x00000] in <filename unknown>:0

However, i didn't know what is this "Dictionary" : i suppose that's call kind of DB from SoundProfile but i have no idea where to find/consult that or i didn't understand this part... (i just begun C# since few days xD)

Final edit : Ok... i think i found how to add new OST with Memoria :D (without replacing the existing ones)

I will make more explanations after my little nap but i finally found the file which read IDs Music, it's located on resources.assets (viewed with Unity Assets Viewer) => embeddedasset/manifest/sounds/musicmetadata.txt.

Spoiler: show
{
  "data": [
    {
      "name": "Sounds01/BGM_/music000",
      "soundIndex": "5",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music001",
      "soundIndex": "6",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music002",
      "soundIndex": "3",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music003",
      "soundIndex": "4",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music004",
      "soundIndex": "1",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music005",
      "soundIndex": "2",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music006",
      "soundIndex": "0",
      "type": "Music"
    },
    {
      "name": "Sounds01/BGM_/music007",
      "soundIndex": "10",
      "type": "Music"
    },
etc....


On this file, you can add new OST for the game, i just test quickly : seem to work !

Sorry if I didn't make myself clear...  :-\ and thanks again for your quick answer  :)
Sorry for that slightly confusing post  ;D

16
So, sorry for the late answers.

Np, was discovering HW waiting yours answers :)

About Vanish & Venom, thank you for his details !
At this moment on my project, to early to use Vanish/Venom so i will see later :) I take note !

Flee is actually not a multi-target spell animation, but single-target. If you go in HW's panel "Environment -> Spell Animations -> Flee-Skill -> Edit Spell Sequencing", you can see that the damage point and effect point only apply to the 1st target. Change that to apply to all the targets and you'll be able to use a multi-target White Wind with that (I am not 100% sure of the effect on fleeing though; it might bug to trigger fleeing several time simultaneously but I don't think so).

Ooooohh.. ok ! I understand why some ennemy animations can't be cast Multiple (for example : Rainbow Storm to make an Aero spell, only works on single target)
That's interesting... maybe i will check inside this "Spell Sequencing" but i am afraid to break some ennemy attack lol

No, you can't delete files added using UAV and actually... you shouldn't add files either as it bugs and somehow I was never able to make it so new files can be used by the game (it just doesn't find them).
Replacing existing files is okay. Sounds and images are converted back and forth to standard file formats (the raw files couldn't be opened with pretty much all the sound/image readers). 3D models and their animations can be exported to correct FBX files (you need to export the "GameObject" that corresponds to the model, not the "Mesh" entry that usually has the same name and you need to export the textures separatly; sometimes they are not refered automatically correctly in the exported FBX). However, you can barely replace 3D models as it would usually consist of creating new files that the game wouldn't recognize... Using custom 3D models would better be done by reading them out of any archive inside the DLL (last time I've checked, though, I didn't find C# methods for importing FBX models... maybe big libraries like UnityEditor.dll would be required for that).

It's very sad that you can't add music on the game... it seem simple but too bad if game didn't understand.
I try to search on .dll files about how game find BGM during battle : what a mess ! :-o
I tried to invert ID Music without using btlencountbgmmetadata.txt or wldbtlencountbgmmetadata.txt but didn't find the right files.... I found an ID Music List on "FF9DBall" : nothing happen when i invert some music... Same thing on "AudioResources".

I want to understand how that's works !!  :P

Besides, how can we read "AssetBundle" on p0Data61 ? I am interesting to see what there is inside (i think i got some idea but i am too curious  ;D)

Thank you again for yours precisions Tirlititi.

17
I found a bug : when you editing Garnet animation resources (from Prison Cage or if you add her on another battle), HW load few seconds and close.

EDIT : Another question (again !  :evil:), any way to delete file added on assets with UAV ?

18
Thanks for his explanations Tirlititi ! Trying to understand everything you tell me ahah

Quote
(2) What should have most interest for you: the main method, "CalcMain", that contains the bone structure of spell effects, is written in the .cs files that are inside the folder "StreamingAssets\Scripts\Sources\Battle". The names of the files start with the same numbers as the "case" number inside the "Source_BtlCalc.cs" that I provided (for instance, the "case 9: // Magic Attack" is in the file "0009_MagicAttackScript.cs"; Albeoris and I didn't always use the same names but it shouldn't be to hard to go from one to the other).

Oooohh.... ok !  :o Why didn't i see that before lol

Quote
Congrats if you've read and understood this far!
I guess that HW is not such a difficult tool to use, right? :p

HW is a pretty cool software, i respect you (and others modders) to make this kind of tools !
Very easy to edit spells, skills, items and of course... ennemies and IA ! (Didn't test yet model import or background, i will see that later but i success to change content and location of somes hidden chests ^^)

Vive la France !  :-D

Quote
For these other files, you don't need dnSpy a priori. Albeoris made it so you can simply change the scripts using a text editor but it comes with costs...

Maybe i will try to make a hard mod for FFIX (because... why not ^^ it's my favourite FF), that's why i need to access all code on the game. That's will be a long project so i am patient !

I finally create my first edit for Vivi's focus : he lost some HPs to earn some MPs... yeah it's nothing but that's was my first step :D

Spoiler: show
Code: [Select]
using System;

namespace Memoria.Scripts.Battle
{
// Token: 0x0200002D RID: 45
[BattleScript(44)]
public sealed class FocusScript : IBattleScript
{
// Token: 0x0600005C RID: 92 RVA: 0x000023E0 File Offset: 0x000005E0
public FocusScript(BattleCalculator v)
{
this._v = v;
}

// Token: 0x0600005D RID: 93 RVA: 0x00004384 File Offset: 0x00002584
public void Perform()
{
this._v.Target.Flags |= (CalcFlag.HpAlteration | CalcFlag.MpAlteration | CalcFlag.MpRecovery);
short num = (short)(this._v.Target.MaximumHp >> 3);
this._v.Target.HpDamage = num;
this._v.Target.MpDamage = num;
}

// Token: 0x04000051 RID: 81
public const int Id = 44;

// Token: 0x04000052 RID: 82
private readonly BattleCalculator _v;
}
}


However... i have MORE questions !

Tirlititi :


- It's a mess to search something on .ddl : for example, i want to edit Vanish status. How did you search function of this status on DnSpy ? It's seem the software can't search string  :-\
I search on btl_stat or btl_cmd but can't find (or i search on wrong files)

EDIT : Maybe i got something. I found theses lines on BattleTarget +  SBattleCalculator on Memoria folder

Code: [Select]
public void PenaltyBanishHitRate() // i don't understand why Banish, maybe Vanish instead ?
{
if (base.IsUnderStatus(BattleStatus.Vanish))
{
this._context.HitRate = 0;
}

Code: [Select]
if ((v.Command.Data.aa.Category & 8) != 0) // if attack is not magical ?
{
v.Target.RemoveStatus(BattleStatus.Confuse);
v.Target.RemoveStatus(BattleStatus.Sleep);
}
if ((v.Command.Data.aa.Category & 16) != 0)  // if attack is not physical ?
{
v.Target.RemoveStatus(BattleStatus.Vanish);
}

- It's possible to remove paralysis status on Venom ? I remove Venom from SetCounter & SetEnemyCommandBySequenc but that's not enough it seem ^^

EDIT : I think i found it... on btlseq (folder {-} on assembly) but big pain to edit that, so much error CS0266

Code: [Select]
public const BattleStatus ANIM_STOP_STATUS = BattleStatus.Venom | BattleStatus.Stop | BattleStatus.Freeze;
- On HW, i see somes unused effect : i want to make a special effect for Freya's Reis's Wind.
If i create a new script on Memoria.Scripts.dll with an ID which is unused on HW, that's will work ?

EDIT : Yes you can ! ;D But i found another issue....  :'( Try to apply White Wind effect on Flee for example : that's apply only on first character... wut ?
EDIT 2 : Ok seems that Flee is special, i can add White Wind effect on Vivi's Fire => Works perfectly but impossible with Flee (test with Chakra too)


I have more questions but that's will be enough for the moment ahah, i will continue to understand theses .dll files.

PS : I will EDIT my questions if i found it.

19
Sorry for double post, i can't edit my previous message (don't know why  :-\).

After an entire night searching about that, i finally find : i complety forget Memoria use scripts to edit various things.

But Memoria.compiler didn't work on my side (can't find files location, something like else). What a pain lol

So, i use Dnspy to edit Memoria.scripts.dll directly and finally, i can modify Focus and all !

Thanks again Tirlititi for pointing me in the right direction : I hope I hold all the cards this time :)

20
Thank you again for his answer Tirlititi !

....
*after few hours*
Me :


I can now compile new code with your btl_calc class... but i didn't understand something : which Assembly-CSharp.dll I need to edit ?

Maybe i forget to mention that but i use Moguri Mod : when i patch it, Assembly-CSharp.dll is totally different from NMM used with HW : i can't find btl_calc on this .dll patched by Moguri...

Btl_calc is available on Assembly-CSharp.dll from NMM but how i can replace modifications added ? (can't replace .dll otherwise, game have some troubles lol)

I am a little lost ^^




21
Hi everyone,

I want to edit completely Focus and i see you can edit that with CIL or dnSpy... but i have 2 questions :

- First, with Tirlititi's files on dropbox, i find some informations about Focus on Source_btlCalc.cs.
So i found this code on btlCalc with dnSpy

Code: [Select]
case 44:
{
ELEMENT elem2 = target.elem;
if ((elem2.mgc += target.elem.mgc / cmd.aa.Ref.power) > 99)
{
target.elem.mgc = 99;
}
break;
}

But this code only prevent to exceed 99 of magic... no ? If i need to totally change how works Focus, i need to edit this or something else ?

- I never use DnSpy before : i want to edit btl_calc for example but when i compile files, i get a lot of error about some missing method System.UIInt16, System.Object, System.Byte, System.Void, ect...

Spoiler: show



How fix that ? ...  :-[

Thanks you in advance !

22
Hello everyone !

I am very curious how work modding with FFIX and that's why i decide to test HW !
However... i am big newbie with it  :roll: (never use C# on my life lol but i can learn... i think)

For my first experience, i add BigDragon on Evil Forest first zone (light clearing).... yeah, pretty brutal.

I follow theses steps on "Properly adding a new enemy to a battle (Steam)"
Dragon is present with Goblin and Fang, can attack Zidane but i have two issues :

- Dragon is called "Lame" (mean Knife in FR)
- All attacks from Dragon, Goblin and Fang display wrongly : sometimes there's is nothing (text box is empty), or None (EN)/Rien (FR) showed or EnnemyDummy for Dragon



As i said, i follow all steps from Tirlititi, use simply IA for Dragon (with 2/3 DragonClaw and 1/3 Thundaga), compare with other battles....
I didn't edit attacks and IA from Goblin and Fang and i copy all Dragon attacks from his original battle.
After few hours of testing... i am lost.

I am asking your help... i think i am dumb to find why it's broken ;D

Spoiler: Main_Init • show
Function Main_Init
    switch 2 ( GetBattleGroupId ) from 0 {
    case +0:
        InitObject( 2, 128 )
        InitObject( 3, 129 )
        break
    case +1:
        InitObject( 1, 128 )
        InitObject( 3, 129 )
        break
    }
    return


Spoiler: Dragon_Init • show
Function Big_Dragon_Init
    return


Spoiler: Dragon_ATB • show
Function Big_Dragon_ATB
    if ( GetRandom % 3 ) {
        set SV_Target = RandomInTeam(SV_PlayerTeam)
        Attack( 6 )
        return
    }
    set SV_Target = SV_PlayerTeam
    Attack( 9 )
    return


EDIT : Ok so i found why that didn't work.
1) I am dumb
2) I forget to copy ressources.assets from HW... I thought only p0data files store data combat but i was wrong...

Sorry for this useless post :D

23
Hello everyone !

I am very curious how work modding with FFIX and that's why i decide to test HW !
However... i am big newbie with it  :roll: (never use C# on my life lol but i can learn... i think)

For my first experience, i add BigDragon on Evil Forest first zone (light clearing).... yeah, pretty brutal.

I follow theses steps on "Properly adding a new enemy to a battle (Steam)"
Dragon is present with Goblin and Fang, can attack Zidane but i have two issues :

- Dragon is called "Lame" (mean Knife in FR)
- All attacks from Dragon, Goblin and Fang display wrongly : sometimes there's is nothing (text box is empty), or None (EN)/Rien (FR) showed or EnnemyDummy for Dragon



As i said, i follow all steps from Tirlititi, use simply IA for Dragon (with 2/3 DragonClaw and 1/3 Thundaga), compare with other battles....
I didn't edit attacks and IA from Goblin and Fang and i copy all Dragon attacks from his original battle.
After few hours of testing... i am lost.

I am asking your help... i think i am dumb to find why it's broken ;D

Spoiler: Main_Init • show
Function Main_Init
    switch 2 ( GetBattleGroupId ) from 0 {
    case +0:
        InitObject( 2, 128 )
        InitObject( 3, 129 )
        break
    case +1:
        InitObject( 1, 128 )
        InitObject( 3, 129 )
        break
    }
    return


Spoiler: Dragon_Init • show
Function Big_Dragon_Init
    return


Spoiler: Dragon_ATB • show
Function Big_Dragon_ATB
    if ( GetRandom % 3 ) {
        set SV_Target = RandomInTeam(SV_PlayerTeam)
        Attack( 6 )
        return
    }
    set SV_Target = SV_PlayerTeam
    Attack( 9 )
    return

Pages: [1]