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 - Tirlititi

Pages: 1 [2] 3 4 ... 26
Still, if you link Beatrix's commands, it saves up space for adding more spells to another command.

You can't use HW after doing that modification; that's something you have to do last.
Well, actually, I'm not sure of what are the consequences of using HW after doing that engine modification... But the limit is hardcoded in HW and the program can't catch that the limit was increased with dnSpy.

If her White Magic and her trance command use the same spells, you can avoid using dnSpy though. Simply select either one of these commands and link it to the other: doing this saves up spell slots.

You can't add many spells inside commands in HW. Using dnSpy and the guide you linked is meant to bypass the limit in HW. Since you're using the Beatrix mod, I guess, that limit is already reached and that's why you need to use dnSpy.

You didn't show the error.
Maybe that's a missing comma.
Maybe that's caused by a non-automatic type conversion: dnSpy does that a lot, you need to add type conversion to many places, like:
Code: [Select]
varshort = something + 16; // Error
varshort = (short)(something + 16); // Use this instead if the compiler complains: write the required converted type and wrap the computation inside parentheses

He's surely not defeated by the battle ending script (there's surely a line like "RunBattleCode( EndBattle, VICTORY )") so the reward specific to Baku is not given, only the reward of the group.
Make sure to flag him as defeated right before that line ending the battle:
Code: [Select]
set SV_FunctionEnemy[DEFEATED_ON] =$ 1You could also kill him for good with "set SV_FunctionEnemy[HP] =$ 0" but that would trigger other things like his death cry (I don't think he has one though), his death animation and fading... so that's a less good option.

Maybe there is some protection against this spell?

Well, actually, there are several protections. Of course, you can jump with Freya to avoid it, Auto-Life to survive to it and also it doesn't target all the party in this fight but *only* 3 characters. It can't be avoided with magic evasion though.
But then, I'm saying that there is yet another protection.

Congrats nonetheless! It sure is meant to be an harder fight than Ozma.
I don't know how much of that fight you've seen actually, because it's also meant to have some replay value ^^

It requires a lot of script writing. It's better if you are familiar with programing but in any case, you should read a bit about how to do simple things with scripts here, here and here for instance.

In order to add a character to the party without asking the player's opinion (like when Vivi joins in the Prima Vista), it's this line:
Code: [Select]
set AddParty(8)"8" is an ID for Beatrix's character slot (0 is for Zidane, etc... Marcus shares Eiko's character slot).
It works only if there are less than 4 characters already. You can remove a character beforehand using this:
Code: [Select]
In order to enable Beatrix in the party selection menu, you must add her in party's reserve:
Code: [Select]
set Setting_PartyReserve = 511
Note that it's a bit flag list (it works just like SV_Target in battle scripts). Usually, this party reserve is set to 255 for all the eight normal characters, so adding 256 to that value adds Beatrix.
Party reserve is reseted at different points during the game (when characters are temporarily splitted apart, etc...) so you need to take that into account.
To display the party selection menu, it's this:
Code: [Select]
if ( IsInParty(0) ) {
    Party( 4, 1 ) // Form a party of 4 characters and lock Zidane inside
} else {
    Party( 4, 0 ) // Form a party of 4 characters without locking any character inside

I translated everything that was required so you can play in any language, yes (the mod even unlocks the japanese language that is not available by default).

You are correct.

The p0data2.bin contains both datas of the enemies (AF) and textures of the battle scenes (Fraggoso's NPC mod).
You can't use AF without the datas of the enemies; there won't be obvious bugs for some time (except that enemies are not changed from vanilla) but it would eventually crash on some key fights.

2 solutions:
• Just use the p0data2.bin of AF and play with non-upscaled battle scene textures,
• Merge the two p0data2.bin. You can do that using just the "Unity Assets Viewer" tool that is included in Hades Workshop:
1) Install the p0data2.bin of Fragosso's NPC mod (the other files are irrelevant during the whole merging),
2) Open the Unity Assets Viewer (in HW's "tools") and open the game with it (selecting the FF9_Launcher.exe),
3) Open the archive p0data2 inside the UAV and sort the files by their type,
4) In the UAV's options, make sure that the "Automatically convert images" is deactivated ("Don't convert"), it makes things go better,
5) Select all the files of type "Texture2D", right-click and "Export selection"; that's the files upscaled by Fragosso,
6) Verify that a folder "HadesWorkshopAssets" has been created in FF9's folder, containing all the exported files (you shouldn't be able to see the images as they are not converted),
7) Close everything, install the p0data2.bin of the AF mod, reopen the UAV, reopen the game with it, reopen the p0data2, sort the files by type,
8‍) Select all the files of type "Texture2D" again, right-click and "Import selection". It should print a success message.

Once that's done, you have a p0data2.bin that contains both Fragosso's HD battle scenes and AF's enemy modifications.

I didn't do it myself because, as you said, that makes huge files to upload and I didn't want to multiply the versions "AF + Fragosso's HD backgrounds" / "AF + Fragosso's HD backgrounds + Fragosso's NPC" / "AF + Fragosso's NPC"...

About the frogs, it's in the scripts of the ponds:
1) In the "SpeakBTN" functions of the catchable frogs (Baby, Male, Female, Gold), there's a switch for the appearance of Quale:
Code: [Select]
            switchex 8 ( GetFrogAmount ) {
            case 2 ; 5 ; 9 ; 15 ; 23 ; 33 ; 45 ; 99:
                set VAR_GlobUInt8_64 = 2
2) In the "Main_Loop", there's most of the cutscene's code, in particular the line "if ( GetFrogAmount == 99 ) {" triggering the battle.
The other rewards are also there, a bit after that line (in the "else" branch).

About the enemy targeting only Zombie characters, you can use that in an enemy script (the ATB function typically):
Code: [Select]
if ( ((GetRandom % 100) < 50) && ( FirstOf(SV_FunctionEnemy[MP]) >= 18 ) ) { // Example: 50% of chances to cast Life if there's a Zombie character and if the enemy has 18 MP or more
    set SV_Target = Matching( SV_PlayerTeam[STATUS_CURRENT_A], 64 ) // All the Zombie characters
    if ( #SV_Target ) { // Same as "if ( SV_Target ) {" or "if ( (#SV_Target) != 0 ) {"
        set SV_Target = RandomInTeam(SV_Target) // Pick only one of them
        Attack( ... ) // Cast Life
// etc... do something else if Life is not chosen for any reason

So? Have you tried doing that?
But it can't be done for the PSX version. It's a modification of the game's engine, so it's for PC.

Update to v0.41c:
- Added script file batch importing: you can now write script functions with your favorite text editor and import it back when you're done,
- Fixed bugs with text and UI text batch importation; also, the text IDs now start from 0 instead of 1 in the exported batches (so they match with the text ID inside scripts),
- Added more unused/dummied datas (for enemies mainly) that can be recycled when modifying the game's source code; also added enemy attack targetting informations (they are mostly unused, except for deciding if Cover triggers if I'm not mistaken),
- Listed more script functions and general variables in the script editor,
- Fixed a bug with Qu's Marsh's dialogs (it was actually caused by a "mobile" version of the dialogs; I think it's unused),
- In the Randomizer, the Prison Cages' "Absorb" spell is not randomized anymore,
- Fixed another bug with spell animation sequencing.

I am retiring from FF9 modding (presumably definitively). I don't think that I'll update this tool any further. The code is on Github though and I'll still answer questions, so here you go.

At some point, I wanted to register the local variables of the Hot & Cold scripts but it is quite a big system and that work went on standby...
The main function (the one deciding the reward at least) is "Barrel_41" in the Chocobo Forest, "Barrel_38" in the Lagoon and "Barrel_46" in Air Garden. It's always the same. Here is that function with most of variables given a name.

The part you're interested in is close to the top of the function:
Code: [Select]
            switch 3 ( Chocobo_ChocoColor ) from 1 {
            case +0:
                if ( Hot&ColdField == 1 ) {
                    set ChocographAvailableList |= 8 // 4th Chocograph (Yellow to Light Blue)
                    set ChocographLastAvailableFlag = 1
            case +1:
                if ( ( Hot&ColdField == 2 ) && ( Global_ScenarioCounter >= 9400 ) ) {
                    set ChocographAvailableList |= 2048 // 12th Chocograph (Light Blue to Red)
                    set ChocographLastAvailableFlag = 1
            case +2:
                if ( ( Hot&ColdField == 1 ) && ( Global_ScenarioCounter >= 9400 ) ) {
                    set ChocographAvailableList |= 8192 // 14th Chocograph (Red to Deep Blue)
                    set ChocographLastAvailableFlag = 1
                set ChocographLastAvailableFlag = 0
Without renamed variables (as it appears in Hades Workshop), it's this part:
Code: [Select]
            switch 3 ( Chocobo_ChocoColor ) from 1 {
            case +0:
                if ( Chocobo_CurrentField == 1 ) {
                    set VAR_GenInt24_172 |= 8
                    set VAR_LocUInt8_8 = 1
            case +1:
                if ( ( Chocobo_CurrentField == 2 ) && ( General_ScenarioCounter >= 9400 ) ) {
                    set VAR_GenInt24_172 |= 2048
                    set VAR_LocUInt8_8 = 1
            case +2:
                if ( ( Chocobo_CurrentField == 1 ) && ( General_ScenarioCounter >= 9400 ) ) {
                    set VAR_GenInt24_172 |= 8192
                    set VAR_LocUInt8_8 = 1
                set VAR_LocUInt8_8 = 0
So you see, you only need to increase the scenario counter lower bound for this special chocograph availability. Here are a few key scenario counter values (the first ones are named in the game's source code and I'm not always sure of the meaning, the last ones are values I searched myself in different field scripts):
Code: [Select]

Hilda Garde obtained = 10400
Ipsen Castle entered = 10500
Ipsen Castle done = 10600
Eiko+Dagger gone to Shrine = 10620
Amarant+Freya gone to Shrine = 10640
Steiner+Vivi gone to Shrine = 10660
Shrines done = 10700
Disc 4 = 11100

Yes, it's Moguri.
Alt+Space switches between 16:9 and 4:3.

The command that allows you to trance manually over 50% of trance gauge is Zidane's last skill. It gets available at the end of disc 2, so around the Iifa Tree sections.

It has been done with a previous version of the mod. I am not sure whether it's still possible (in particular, Necron is harder than when it was first done and it was already a bag of pain) but I am sure that Sealion is not a wall.

By the way, Number 1 has Protect, so he's very resistant to physical attacks but weak to magic attacks.
Sealion has Shell so it's the other way around.

The Moguri folder is setup when installing the mod (the installer asks for a folder).
You can also see what it is from the game's folder ("FINAL FANTASY IX"): there should be a file "Memoria.ini". Open that file with a text editor (eg. notepad) and look at the field "MoguriFolder" in the "[System]" section.

Yes, you only need to enable that option when installing the Moguri mod.

Well, there's a link in the mod's topic.
It is very recent indeed (I'm still working on adding a "Beatrix only" and "Moguri + Beatrix only" version).

@levantine: Have you tried the latest release? I specifically made a "Moguri Mod + Alternate Fantasy" version.

It's not possible to make it look nice, unfortunatly :/
The spell animations are the biggest black box of the game now because it's delegated to an external DLL in the Steam version and I can't access its source code, either to see how it works or to modify them (all the possibilities and informations for that section were obtained the old way: guessing and testing).

You may however make Shell's animation hit all the targets in effectivity. For that, you simply need to change the line "Effect Point: 1st target" to "Effect Point: all targets" in its Spell Animation sequence. It will only display the effect on the 1st character though... so I guess that Mighty Guard's animation is still a better choice anyway.

No, the .hws wouldn't hold that change.
That's a real problem for me as well as I would largely prefer to have only 1 file for the mod, but the nature of the change is just not embeddable in a .hws... so I decided that I would distribute the C# code as well (generating the mod then requires Memoria or dnSpy in addition to HW).
Using Memoria, it's simply a .cs file to share in addition to the .hws (and then I think that you need to run Memoria's script compiler, but that's easy).

In any case, the default way to share a mod is not to share the .hws (+ maybe C# code) but to share the generated Steam files (p0data, DLL...).
Even if it creates mod compatibility problems, that's the easiest way to do it, both for the modder and the user.

Hello Clem Fandango. Sorry I didn't see your message before.

It is not possible to do that without modding the battle engine. It can be done either with Albeoris's Memoria tool or with dnSpy, but not directly with HW (or only with added difficulties for no reason). In both case, it's a bit of C# coding.

Using Memoria, you need to change the script of Phoenix Downs (inside "Scripts/Sources/Battle/0072_ItemPhoenixScript.cs"):
Code: [Select]
public void Perform()
if (!_v.Target.CanBeRevived())

if (_v.Target.IsZombie)
_v.Context.Flags |= BattleCalcFlags.Miss; // Add this line
return; // Add this line
// if ((_v.Target.CurrentHp = (UInt16)(GameRandom.Next8() % 10)) == 0) // Remove this line
// _v.Target.Kill(); // Remove this line
else if (_v.Target.CheckIsPlayer())
if (_v.Target.IsUnderStatus(BattleStatus.Death))
_v.Target.CurrentHp = (UInt16)(1 + GameRandom.Next8() % 10);


Using dnSpy, you need to change the method "btl_calc::CalcMain" and more specifically the "case 72":
Code: [Select]
if (Status.checkCurStat(target, 64u) || btl_util.CheckEnemyCategory(target, ENEMY.ENEMY_CATEGORY_UNDEAD))
calc_VAR.flags |= 1; // Add this line
// Remove the following lines, "if ((target.cur.hp = (ushort)(Comn.random8() % 10)) == 0)" and "SetEnforceHP0"
else if (btl_calc.CheckNotPlayerMiss(calc_VAR))
// etc... no change there

No it's not. If it misses, that surely means that you don't have any more ethers :o
It's not a free MP recovery.

No, sorry.

Pages: 1 [2] 3 4 ... 26