• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
March 28, 2024, 03:24:06 pm

Battle Event Editing

Started by DarthFutuza, March 18, 2019, 12:23:24 pm

DarthFutuza

March 18, 2019, 12:23:24 pm Last Edit: November 22, 2019, 12:31:32 pm by DarthFutuza
Hello helpful forum goers,

I'm trying to figure out how to add new mid-battle events (sorry if I'm using the wrong term, might be why I can't find instructions on what I want to do).  I get the impression this has something to do with modifying the attack.out, but I'm not really sure where to start.  What I want to do is this: Take a battle without a mid-battle event, say Eldibis/Deep Dungeon, and add a condition with something like if(Ramza's HP < 25%) startDialogueEvent();  And then Ramza would yell something at Eldibis or whatever and then go back to fighting.

Do I need to overwrite one of the pre-existing event slots (say 491 since its unused), or can I just use the existing battle event (115 I think?) and add what I need to it using EasyVent?  Where does editing the Attack.out come in, etc?
  • Modding version: PSX

Nyzer

You'll need to mess with event conditionals for that. It will take a whole new event, too - I mean, maybe in theory ypu could just use If commands to pack it all in the pre-battle event and just refer to it again but I honestly don't know.

http://ffhacktics.com/smf/index.php?topic=6694.0

I've never set this up myself so I couldn't tell you more than that, sorry.
  • Modding version: Other/Unknown

3lric

March 18, 2019, 09:14:58 pm #2 Last Edit: March 21, 2019, 10:16:53 pm by Xifanie
You need to edit the attack.out event conditions spreadsheet and then apply that data to your attack.out file (either via hex edit or using orgASM). You can find the conditions sheet in ravens old tutorial, or in his workbooks. I prefer the former, but thats just me.

I wrote a short tutorial on editing worldmap flow, but the idea is pretty much the same.

Ive done extensive work with event conditions, so if you have more questions, dont hesistate to ask. Though i cant always promise a prompt response (dont ask in PM though, its better if its public so other people can get an answer about it too)


EXAMPLE:

This here is the Undead Algus battle, from WotL that we ported to TLW

0100FD01010019000601
01007E0000000400A500040003000500A50001000500030001000B00A50019000701
01007F0000000400A500040003000500A50001000500030001000800A500190019000801
0600A500000019000901

So lets break this down, taking into account that these are in reverse hex bytes, we will break these down into 4 numbers each to keep it simple

The first condition:
this one is pretty straight forward, standard event call



0100        FD01        0100        1900        0601       
IFVariable 01FD= 1Run Event ->0106



The second condition:
this one is full of untrimmed WotL Fuckery, but a good example to learn from I guess



0100        7E00        0000        0400        A500        0400        0300        0500        A500        0100        0500        0300        0100        0B00        A500        1900        0701       
IFVariable 007E= 0Unit is Present ->00A5Unit is Present ->0003Unit is Alive ->00A5TRUEUnit is Alive ->0003TRUEUnits Turn ->00A5Run Event ->0107


So in this one, if variable 7E is 0, and both (00A5) Algus and (0003) Ramza are present and Alive, then event number 107 will play on Algus' next turn. At the end of that event, variable 7E is changed to 1 (in the event itself, via a event command), which makes it so the event doesn't simply replay on an infinite loop.


The third condition:
this one is full of more untrimmed WotL Fuckery, but still good example to learn from I guess



0100        7F00        0000        0400        A500        0400        0300        0500        A500        0100        0500        0300        0100        0800        A500        1900        1900        0801       
IFVariable 007F= 0Unit is Present ->00A5Unit is Present ->0003Unit is Alive ->00A5TRUEUnit is Alive ->0003TRUEUnits Health ->00A5Less than 25%     Run Event ->0108


So in this one, if variable 7F is 0, and both (00A5) Algus and (0003) Ramza are present and Alive, but Algus' health is below 25%, then event number 108 will play. At the end of that event, variable 7F is changed to 1 (in the event itself, via a event command), which makes it so the event doesn't simply replay on an infinite loop.

Keep in mind that Percent values are in hex, we use 19 here, because 19 in hex is 25 in decimal.


The fourth/last condition:
another one that is pretty straight forward, standard closing event for a boss




0600        A500        0000        1900        0901       
Unit is Dead ->00A50000Run Event ->0109



I hope this makes sense. I haven't used tables on the forum in quite some time, so this took longer to explain than i thought it would lol

EDIT: I also wanted to add, the reason I said these are sort of an untrimmed WotL fuckery type is mess is because we really don't need to check that both Ramza and Algus are present in the above strings, we know they are, because Algus is set via ENTD with his 00A5 ID (for TLW) and Ramza is required in the battle and in chapter 4 where this event takes place, he has his 0003 ID, so even checking for those two things is a bit redundant, but I just took the commands as they were and posted them for breakdown, since it also helps if you ever have a character who could potentially have a bonus scene in a battle based on whether or not they are present, like Agrias does at Golgorand if she is in the battle.
  • Modding version: PSX

DarthFutuza

Okay thanks for the information guys, I didn't realize attack.out dealt with mid battle conditions as well as other things.  Looks like I will need to reserve a new event and edit the attack.out to point to it after setting up a condition.  Thanks for the hex tutorial Elric should be helpful, though I've done this thing before its just been a while so its a good refresher.  I'll give it a try and let you know how it goes.
  • Modding version: PSX

Nyzer

And yeah, with Elric detailing all that, I'm pretty sure you could indeed just combine it all into one event if you used variable checks and JumpForward.
Provided you have space in the event for that, anyway.
  • Modding version: Other/Unknown

3lric

Quote from: DarthFutuza on March 19, 2019, 02:34:55 pm
Okay thanks for the information guys, I didn't realize attack.out dealt with mid battle conditions as well as other things.  Looks like I will need to reserve a new event and edit the attack.out to point to it after setting up a condition.  Thanks for the hex tutorial Elric should be helpful, though I've done this thing before its just been a while so its a good refresher.  I'll give it a try and let you know how it goes.


It wasnt really a hex tutorial. It was a mini tutorial on how some of the commands work and letting you know its in reverse hex bytes. Knowing how to hex edit doesnt immediately mean you know what our commands are, lol.

Youre welcome either way though
  • Modding version: PSX

DarthFutuza

Quote from: Elric on March 20, 2019, 06:28:50 pm
It wasnt really a hex tutorial. It was a mini tutorial on how some of the commands work and letting you know its in reverse hex bytes. Knowing how to hex edit doesnt immediately mean you know what our commands are, lol.

Yeah, my bad I didn't really know how to refer to it since I hadn't read it in full yet, it was useful regardless now that I have gotten to it.  :D

Quick question, a lot of events I'm looking through seem to look for some seemingly extra variables on most of the event condition checks.
eg:

  0100 7D00 0000 0100 8000 0000       0400 2400       0500 2400            0100      0400 2A00          0500 2A00      0100    0B00           2A00              1900          C001
//if   varD7==0   if  var08==0       ifUnitExists(42)      ifHP(Meliadoul HP > 1%)     ifUnitExists(A2) ifHP(Vormav > 1%) ifATReached(Vormav) LoadEvent(01C0)

Here it checks if both 007D and 0008 are set to 0.  Do we know why it does this and why its relevant/needed?  As you explained, most events set a variable to 1 to indicate its done the event and we don't need to do it again.  But why two different ones?  Is this standard procedure for multiple chained events (set multiple variables for each one)?  (I checked on the wiki's variable reference and it seems like these are temporary/unknown variables so I'm not sure what else they would be.)

Edit: Bleh spacing
  • Modding version: PSX

3lric

March 21, 2019, 12:48:17 am #7 Last Edit: March 21, 2019, 01:07:57 am by Elric
Variable 7D is the temp variable that is used in the event itself, to make sure that it doesnt repeat, as mentioned.

Variable 08 is end of battle.

in that case those would be two very different things,
<--(Ignore this derp, dunno what i was talking about here) however you broke it down wrong. The bytes are reversed, not the hex in the bytes themselves

Example: 0123 would be 2301, not 3210.

So it's not Variable 08, but rather Variable 80. Which was intended to be used for 2 things and was never actually utilized in game.

EDIT: Hold for more info




0100     7D00     0000     0100     8000     0000     0400     2400     0500     2400     0100     0400     2A00    0500     2A00     0100     0B00     2A00     1900     C001     
IF     VARI 7D     ==00     IF     VARI 80     ==00     UNIT PRESENT ->     ID=24     UNIT ALIVE ->     ID=24     IF     UNIT PRESENT ->     ID=2A    UNIT ALIVE ->     ID=2A     IF     UNIT TURN ->    ID=2A     RUN EVENT ->     01C0     

  • Modding version: PSX

DarthFutuza

March 21, 2019, 12:51:19 am #8 Last Edit: March 21, 2019, 01:06:33 am by DarthFutuza
Ah okay that makes sense on that one.  Is variable 08 the standard way to check to see if the battle is over/still happening or unique to this instance/event?  I didn't see any reference to that on the variable reference, maybe its just out of date.

EDIT:
Quote from: Elric on March 21, 2019, 12:48:17 am
however you broke it down wrong. The bytes are reversed, not the hex in the bytes themselves

Example: 0123 would be 2301, not 3210.

Oh yeah, you're right.  Good catch.  Mel is totally 2A, not 24.  I messed that up in my head because 2A == 42 in deci, whoops.  (The other stuff is obviously backwards too XD).
  • Modding version: PSX

3lric

Quote from: DarthFutuza on March 21, 2019, 12:51:19 am
Ah okay that makes sense on that one.  Is variable 08 the standard way to check to see if the battle is over/still happening or unique to this instance/event?  I didn't see any reference to that on the variable reference, maybe its just out of date.


You are misunderstanding. The variable in that event is 80, not 08. 80 was intended to be used for something, but ended up not being utilized in game.

This quote from Cheetahs tutorial might make more sense for you

QuoteExample 1: Normal

Orbonne Monastery
ENTD: 183

01 00 FD 01 01 00 19 00 04 00

Orbonne Battle (Gafgarion and Agrias chat)
01 00 7F 00 00 00 01 00 80 00 00 00 04 00 17 00 04 00 34 00 0B 00 17 00 05 00 17 00 01 00 05 00 34 00 01 00 19 00 05 00

Orbonne Battle (Abducting the Princess)
01 00 80 00 00 00 16 00 19 00 06 00

First Line: Checks that boolean "FD 01" is present and runs even script "04 00". This is the standard opening of every event or battle.

Second Line: Checks that booleans "7F 00" and "80 00" are not present. This is because part of the event that is run with this activates boolean "7F 00" so that this Event Conditional will not trigger multiple times. It checks that "80 00" hasn't been run because that is the end of the battle, preventing this script to be run after the end of the battle had occurred. The game then checks to see that units "17" and "34" are present, checks that it is unit "17" turn, and that units "17" and "34" are both alive. Then runs event "05 00", which happens to contain the boolean "7F 00" so that it will be considered present.

Third Line: Checks to make sure boolean "80 00" is not present. Checks to see that all enemies are dead. Runs event script "06 00".


This ^ is very old info, so when we pair it with what we have on the wiki, we know that:

Quote0x0080    0x8005791C    0x01       Orbonne: Gafgarion's Turn (unused)
Mandalia: Victory (unused)


So i apologize for mispeaking, it wasn't for the end of the battle (except for mandalia, which it was also unused at)

As to why it would be used in any other event, i cannot say for certain, however it could be that they intended to have more types of things that could be checked for, that were never implemented, or it could just be a bit of junk code that was never removed.
  • Modding version: PSX

DarthFutuza

All good this helps a lot.  80 is the beginning of a new set of stuff in memory, plus when size switches from words to the miscellaneous bit section.  Also, probably not coincidence that happens after 128 total words (which is ~2048 bits which is the max memory size of the playstation's RAM if I recall right).  I dunno why it would necessarily need to check that, but it might be some sort of max memory/capacity check.

EDIT: Nope can't be that, playstation has 2 MB lol, not 256 bytes.  ¯\_(ツ)_/¯
  • Modding version: PSX

3lric

The more you look thru the bits of the game code, the more you will find weird things that don't make much sense.

There is a ton of redundancies in the worldmap conditions as well, but i don't know that anyone has ever bothered to trim it and remove any redundant coding yet. Kinda doubt it since like, all of 5 people even touch that sheet, lol.
  • Modding version: PSX

DarthFutuza

I might try that next, but what I had in mind for my changes isn't really that big of a scope to require new map stuff.

Thanks to your help I was able to get the last bit of what I was missing working and I understand attack.out pretty well.  Now I just have to add details and polish things up.  Maybe add one more event depending on how ambitious I'm feeling.


Woo, battle events.
  • Modding version: PSX

3lric

Events are easy, ive made over 200 of em :P

You just gotta want it (and have a lot of motivation)
  • Modding version: PSX

RJ Cid

Hello all!

Been learning more about some sprite editing and now that I'm getting familiar with CDMage I'm curious about a few things...

In vanilla, Cloud comes in at LV.1 and this was considered unpopular and changed in 1.3 (which is the version I'd like to practice the editing on ;) ). I actually prefer to get some of my special characters at LV.1 so that I have more control over their leveling progressions. Are there any drawbacks to doing this? And how would I go about making it happen?

Also, I'm having the worst time getting the event portraits to change colors... Looked into a sprite editing tutorial video and read everything posted on this site, but no matter what combo I implement, I can't get the portrait to out of those reverse colors. Any common mistakes I should consider? I'm using the sprite files from this site, and everything else changes over just fine.

Lastly, how do I edit abilities? I'd like to add one, or make it learnable like Ultima to a certain class what can't be fully mastered. You can just answer that one with a link on this site. Thank you so much... I love you  :cool:

Nyzer

Best not to jump in to someone else's topic to post unrelated questions, dude.

QuoteIn vanilla, Cloud comes in at LV.1 and this was considered unpopular and changed in 1.3 (which is the version I'd like to practice the editing on ;) ). I actually prefer to get some of my special characters at LV.1 so that I have more control over their leveling progressions.
... how would I go about making it happen?


FFTPatcher. Specifically the ENTD tab.

QuoteAre there any drawbacks to doing this?


Well, if you intend for your mod to be playable by other people, you can easily end up convincing your players not to use that character.

There's a potential workaround there, though. If you're never going to use that party member in any further events, and thus don't need them to have a single specific Unit ID, you can always add a duplicate, not-present unit at level 1 and give the player a choice before the end of the recruitment event as to whether they'd want a level 1 character or a matching-party-level character. Depending on their choice, remove the one used in the event while adding in the duplicate, then end the event.

It's not a great workaround, mind you. It's always best to just have one unit ID for your special character.

A better workaround would be to adjust the character's level directly, which I believe is possible through some complicated event editing - there's a method to set up variables to point at a character's stats in a way that allows you to adjust them - but I don't yet know how it's done, myself.

QuoteAlso, I'm having the worst time getting the event portraits to change colors... Looked into a sprite editing tutorial video and read everything posted on this site, but no matter what combo I implement, I can't get the portrait to out of those reverse colors. Any common mistakes I should consider? I'm using the sprite files from this site, and everything else changes over just fine.


Reverse colors? I don't know what you're talking about.

Best guess is you're trying to use the same palette for both the sprite and the portrait, and it doesn't work that way. Portraits use Palette 9 and above. Best to use GraphicsGale, as it lets you see and adjust your 16-color palettes at all times. Though it takes a small amount of fiddling to switch between current palettes.

QuoteLastly, how do I edit abilities? I'd like to add one, or make it learnable like Ultima to a certain class what can't be fully mastered. You can just answer that one with a link on this site. Thank you so much... I love you  :cool:


Again, FFTPatcher. This time, the Abilities and Skill Sets tabs. Look at how skills like Ultima and Zodiark work for reference. If you know how some of them have been altered in Jot5 you can open the release version of Chapter 1 and see some other options as well (though a fair number of ability changes are also due to ASM hacks, which are done with a different tool and can't be seen with FFTPatcher).

FFTPatcher is a very simple tool with a very wide scope of what it can change; I'd strongly recommend you spend a lot of time going through it and learning what you can do, as poking around with it can save you a ton of questions in the future.
  • Modding version: Other/Unknown

3lric

Load the sprite in palette editor by Xif, to get rid of the reverse colors in the portrait
  • Modding version: PSX

RJ Cid

Thanks Elric! Much obliged  :cool:

DarthFutuza

November 22, 2019, 12:31:10 pm #18 Last Edit: November 26, 2019, 06:29:24 pm by DarthFutuza
I figured I'd just keep going with this topic since I'm editing my event again to try and add some more features and have more event questions.

1) I wanted to try adding another new event, but I wanted to set a variable that I can have the world instructions check for when a map is visited.  That said I'm not sure how to actually set that variable.  There's a SETVar (175) option available in EasyVent Editor, that appears to do what I want, but it mentions that I have to have an event instruction upgrade hack.  I was just wondering if the hack is necessary to set variables, or if there's a simpler way/another tool that could be used just for editing variables before I bother adding the hack?  Information is just so scattered and there's a ton of out of date stuff that's been replaced with newer methods I thought I should just check first, before I go ahead.  Nyzer answered this.  :)  Use the add/AND/or etc cmds silly.

2) Is there a Brave Story editing tutorial somewhere?  I just want to add a new character entry and update a previously existing one with more info as a result of my new event.  I noticed Elric mentioned it was coming soon, but I couldn't find anything else.  I suppose this probably works with some variation on the SETVar command, where I activate one of the unused slots to 'reveal' it and then use tacttext to supply the text? Solved.  See here.

3) Is there any information available on using rumors to trigger events/changing what rumors show up in the bar/adding new rumors that when listened to, set/modify variables?  (Sorta like how the vanilla game did it with the Beowulf/Cloud/Reis sidequest)?  I imagine that's probably pretty similar to the previous question, of setting the variable to change which rumors show up, along with a little extra something somewhere to tell the game to check if the player bothered reading the rumor.
  • Modding version: PSX

Nyzer

1) SET is only available with the upgrade, but other commands such as ZERO and ADD are just available normally.
  • Modding version: Other/Unknown