#Baton Pass / Shifting / Passing in Persona 4 Golden

13 messages · Page 1 of 1 (latest)

slim ocean
#

Hey all, I have begun the process of digging into the EXE & scripts to hopefully be able to add some sort of turn changing functionality like in modern atlus games.

At the very bare minimum, I think it would be most easy and possible to implement Metahpors' pass functionality by:

  • Enabling a temporary flag within the same turn IF the current party member hits a weakness. (and reset or delete on turn end)
  • When a keybind button is pressed, ONLY if the temp weakness hit flag is toggled, we add the current party member at the end of the turn list and move the turn on to the next party member in order

Any pointers to specific functions, advice, feedback, or if anyone wants to outright takeover, please be my guest. Thanks.
I think this would be the easiest implementation and then from there you can add UI, some visual event like in other games, and specific party member picking(like P5R and P3R, because I think this is the hardest part of the mod yet not essential is why it should come later). But I also think passing would be much more balanced for P4G without any additional changes.

Currently, I believe I have learned a few things decompiling the main EXE.
Within the BattleUseSkill annotated function:
The weakness is identified and handled in the following block of code:
if (((0 < local_240) && ((info->field321_0x173 & 3) == 1)) && (info->Unit->IsEnemy == 0)) {
uVar25 = 0x18;
goto LAB_1400579a9;
}

because the variable local_240 is incremented earlier in the code whenever a target is found to have a weakness to the skill being used. Specifically, where each target (pBVar23) is processed:
if ((*(uint *)(&pBVar23->field_0x174 + (ulonglong)isEnemy * 0x20) & 0x100000) != 0) {
local_240 = local_240 + 1;
local_2a4 = local_2a4 | *(ushort *)&pBVar23->field_0x176;
}
The condition checks if the target has a weakness flag set (0x100000), and if so, increments local_240.

The if statement checks if any target had a weakness (local_240 > 0), when the conditions are true, uVar25 is set to 0x18 (??) and calls LAB_1400579a9 to handle the weakness hit. I think this function displays or processes the weakness hit effect.
It's preparing an action (pTVar20) with specific properties related to the weakness hit. Heres the function:
LAB_1400579a9:
local_328 = local_328 & 0xffffffff00000000;
pTVar20 = (TurnInfo *)FUN_1400c02d0(info,uVar25);
*(undefined *)pTVar20 = 5;
*(undefined8 **)&pTVar20->field_0x8 = puVar18;
*(float *)&pTVar20->field_0x88 = (float)(int)local_2f4;
pTVar20->field146_0xa0 = uVar29;

anyways thats a little off course but after setting up the action, it executes it:
FUN_1400b1090(pTVar20, 1);

which appears to be responsible for adding a TurnInfo object to a global action queue or list of which I don't understand.

....

Basically, I just need to figure out exactly where the weakness is exactly exploited, then I can create a variable/flag/event that exists only for the current turn(or re use another), then I would need to find out where and how turn order is handled(likely the hardest part) and just pass it on to the next team member basically by brute forcing ending the current turn, and then just adding another turn or team member back into the turn list(maybe some logic of only going to the next party member in the turn list is also needed for every non-advantage turn). Basically you could get away with just a random keybind that does it for now, i wouldnt be suprised if the actual logic involves less than 30 lines of assembly code.

slim ocean
#

Okay, further development. I think i have a good general idea of what to do:

for the BtlUnitInfo struct, we can add an additional member bool WeaknessHitFlag, assuming this is exactly what i think it is.
then ASSUMING im right about where the weakness is identified, I can just change the bool there to true since it means THIS player hit THAT enemies weakness.
Later, we can set it to false when the right key is pressed before switching units. Thankfully, as a new flag, if its brute forced like this it wont require any logic of determining if the one who hit the weakness is an enemy or not, it's just set until used, and only the player can use it.

Only thing left to determine where it actually is is the entire structure of how turns and turn order work because we need to be able to reset the flag if it isnt used(at the very end of a turn) and all the intricacies of "passing to the next party member". there is a LOT to sift through and its practically all gibberish between the annotated EXE and decompiled C

could save the logic of resetting the flag if used and allow that party member to always keep a pass in any of their turn after to save logic/time, and could be a cool feature that sets it apart from metaphor.

RELEVANT ANNOTATED FUNCTIONS:

BattleUseSkill - For Determining Weakness Hits, Unconventional as it is UI-based but likely fine
Process, BtlPanelMainThing, ConfigMenu/CommandMenu - For UI implementation

"TurnInfo"

slim ocean
#

@raven sphinx Hoping you can help me a bit when you get the chance since you annotated the EXE.
I'm assuming most of these functions are translated from the decompiled functions(specifically the ones below), and not external debugging ones. Not sure if it's best to build off of it, but it seems it would be more effective to patch the actual EXE while using it as a reference, but not sure the best way to translate what and where with Ghidra at least.

I'm seeing resources for Inaba EXE patcher and Aemulus(to make these changes), and I think I know what needs changed and where to get a super barebones implementation in, but the only questions I have relate to whether or not I'm right about these and if im on the right track:
-BtlUnitInfo(flagging players)
-BattleUseSkill(weakness identifying)
-TurnInfo?(everything related to the turn structure and global queue its got going)
-(Everything BattleKeybinds, etc just to be able to have a key call a function to end the turn or something)

Any help is appreciated, sorry for the info dump 😅

raven sphinx
#

Aemulus is for the 32 bit version of the game so that's not going to help. You can use Inaba for the patch if you want. I have a feeling you'll want to make it a proper Reloaded code mod later on especially if you want to do fancy stuff like adding new UI elements but Inaba is good for quick prototypes since it's basically just assembly.

#

As for the labelling of things almost all of it will be stuff I just made up. The game has no symbols or anything like that, stuff is just labelled based on what I think it probably does

#

I say most because there are some functions which have string names associated with them but the vast majority I completely made up

slim ocean
#

Yeah that makes sense, I was trying to read things myself i wasnt sure how sure you were about some of it.

raven sphinx
#

Most of that I'm probably not very sure about lol. I don't remember doing much at all with battle code.

slim ocean
#

yeah i saw a lot of it was UI decyphering because you can see exactly what files it pulls

#

I got confused about the Inaba Exe patcher wiki also because i was under the P4G 2020 tab

raven sphinx
#

If you need help with getting the code patched or stuff like that I can help but I probably can't give any specific advice on what code you should be looking at without actually having a look myself

raven sphinx
#

The stuff about the 32 bit version that's still on the page is only for legacy stuff. I don't really expect anyone to actually use it for that version of the game anyway