ShrineFox / BotW-Actor-Editor

C# Program to automate swapping Actor Pack physics files using Python
2 stars 2 forks source link

Files should be renamed to their target #1

Open GingerAvalanche opened 3 years ago

GingerAvalanche commented 3 years ago

BotW only loads one file of any given name to memory. When it needs to load another file, it first checks to see if a file of that name already exists in memory and, if so, uses it. This means that if someone were to copy the actor pack files from one armor to another and then edit them, the game would use the values from whichever file it loaded first for all instances of that file (though it would reset if the file became stale enough to be unloaded from memory, in which case the cycle would repeat).

Prior to this, I used "file name" to mean "name + extension." From now on, "file name" will mean "name stem, without extension." Sorry, I don't really know how better to communicate that.

I'm not fluent in C#, but I've hacked enough Unity games to pretend like I know what I'm talking about, so I'll try to give an outline of how best to fix it, since I don't have an environment set up for coding in C# and don't know how to do so, to open the PR myself.

There's up to 7 things that should be changed:

The file name changes are easy, they should just match the file name of the bxml.

For the folder names, Nintendo went with the BFRES name. That's obtainable by looking in the bmodellist file for the only "Folder" key (Folder: [BFRES name]). You should be able to use the equivalent String.split() on that line on the : (note the trailing whitespace) and grab the second half.

For the reference strings inside bphysics, there's one for each file, bphyssb and hkcl. (Assuming that the actor has both) You should be able to do that with the following:

ChangeSARCValue("bphysics", "support_bone_setup_file_path", "{folder_name}/{actor_name}.bphyssb");
ChangeSARCValue("bphysics", "cloth_setup_file_path", "{folder_name}/{actor_name}.hkcl");

Though it would be cleaner and faster to edit both lines while the file is open once than to open it, write, and close it twice. Though C# can probably still do that faster than python can open, write both lines, and close once, so performance difference is probably negligible.

The PhysicsUser in the bxml wouldn't need to be set to the new bphysics file name, because all the bphysics files in vanilla should already share a name with their bxmls. The vanilla hkcl and bphyssb don't all share a name with their bxmls (the _Head armors for those with mantle variants use _Head_A for their hkcl and bphyssb) but that shouldn't matter because the actor names without _A are still unique and the only references to them are in bphysics, which you'll already be changing anyway. The alternative would be to look in bmodellist for Unit_Name: [actor_name_with_A_if_necessary] and use that for the hkcl and bphyssb files, though it will always be the same as the bxml filename for non-_Head_A actors and the bxml file name should work perfectly well in its place.

Let me know if you have any questions or if you want me to make those changes myself, and I'll see what I can figure out.

ShrineFox commented 3 years ago

Thanks for the advice, I see what you mean. Since it only replaces the file if it finds one of an equivalent extension in the original sarc, I guess I can get away with copying the new physics files and keeping the original name/path (and not change the physicsuser)

ShrineFox commented 3 years ago

I believe the issue has been sufficiently addressed now with version 1.1, lemme know if I misunderstood anything or if it doesn't work as intended.

Now AAMP files copied from the target pack to the source pack use file/directory names derived from the original bmodellist's UnitName and Folder keys. They appear to match the original structure 1:1 when comparing the unmodified SARC to the new one. I've also dropped changing the PhysicsUser value due to these changes and edit both values in bphysics at once like you suggested.

GingerAvalanche commented 3 years ago

That's exactly what I meant, thanks.

I'm very tired right now, so I might be reading it wrong, but it seems like there might be a bug: if the target pack doesn't contain a file, then this line will find nothing, and so the deletion of the source pack's version of the file inside that loop will never occur. For example, some leg armors don't have cloth hkcl or bphyssb, some do. If you copy one without those to one that has them, then it won't delete the source's existing hkcl and bphyssb. The resulting pack should still work, due to there being nothing referencing those files since there would be no reference lines in the bphysics, but it's still probably a good idea to get rid of them, both for clarity and for ease of downloading for users.

ShrineFox commented 3 years ago

Great catch, think it should be all set now. I just moved the check outside of the loop so it removes them even if it doesn't add anything. Should be fine since it'd replace the AAMP strings with Dummy or something, I'd imagine