Vennobennu Posted August 19, 2013 Share Posted August 19, 2013 (edited) I've been poking around in the chapter events for FE8, and I've noticed something about how the game loads reinforcements. Those of you who hack FE8 may know of the strange and complex ways that it loads reinforcements, but from what I've found, reinforcement events only look complex - they're no more so than FE7 reinforcements in practice.Let's use Chapter 8 as an example:[spoiler=Chapter 8]On Turn 5, this event is triggered: label18: _SETVAL 0x2 0x88B7698 CALL label38 _0x0228 0x7 ENDA Notice how the _SETVAL 0x2 command specifies a location of the ROM; this is the offset of the unit data of the reinforcements (Two mages and a thief in this case). These reinforcements do not appear in the disassembled chapter events, so yo'll have to edit them with Nightmare.Anyway, continuing on, we call label38: label38: _0x1020 0x4 CALL label27 _0x0228 0x9 _LOAD_WHATEVER 0x1 ENUN _0x0220 0x9 _0x1020 0x0 ENDA [...] label27: _0x1020 0x1 _0x0220 0x2 _0x0320 0x8 _SETCONDITION 0x0 0xC 0x0 FADU 16 ENIF 0x0 _0x1020 0x0 ENDA I am pretty sure that the LOAD_WHATEVER 0x1 command is loading units from the offset stored in Memory slot 2, i.e. the value defined from _SETVAL 0x2. It's a form of assembly, essentially.The rest of the code looks opaque, but here's the deal: The majority of it is generic, and can be used for any reinforcement event in the game. Only a very few parts of it are different for different chapters or events, and even then only for special cases (such as when loading player units or triggering a convo during the event).[spoiler=For example...]A different reinforcement event in Chapter 8 goes like this: label17: _SETVAL 0x2 0x88B7648 CALL label38 _0x0228 0x7 ENDA It is exactly the same as the previous event but for where it points to to load units from. They both call to label38 simply to save space. Here's a slightly different case: In Chapter 10B, the game uses a single turn event to load two sets of reinforcements, one after another: label24: _SETVAL 0x2 0x88C30A0 CALL label39 _SETVAL 0x2 0x88C312C CALL label66 _0x0228 0x7 ENDA The first CALL is normal: label39: _0x1020 0x4 CALL label38 _0x0228 0x9 _LOAD_WHATEVER 0x1 ENUN _0x0220 0x9 _0x1020 0x0 ENDA label38: _0x1020 0x1 _0x0220 0x2 _0x0320 0x8 _SETCONDITION 0x0 0xC 0x0 FADU 16 ENIF 0x0 _0x1020 0x0 ENDA Notice how these events are identical to the ones used in Chapter 8. But the second is a little different: label66: _0x1927 _SETCONDITION2 0x0 0xC 0x0 _0x1922 _SETCONDITION 0x0 0xC 0x0 CALL label39 ENIF 0x0 ENDA It adds this bit of code to the usual reinforcement stuff. This, too, can be found unchanged in other chapters. This code is a check for Hard Mode; on Normal and Easy, the related reinforcement won't trigger. Actual scenes, like Riev's monsters or Ewan's appearance in Chapter 13B, only need label39 or a simple _LOAD1. I hope these notes will help anybody brave enough to work with FE8 events; in the future I may write on the different ways the game loads reinforcements consisting of player units that do and do not already exist in memory. Edited January 1, 2014 by Vennobennu Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 19, 2013 Share Posted August 19, 2013 good work, i was hoping someone would do this the more i learn about fe8 events the more i like them over fe7 events someone should probably make these into macros so we don't have to continually copy paste what amounts to boilerplate code Quote Link to comment Share on other sites More sharing options...
Blademaster! Posted August 19, 2013 Share Posted August 19, 2013 (edited) What exactly are you trying to show with Reinforcement events in FE8 exactly? That they all follow the same pattern and it can easily be copied? It looks like you're just overcomplicating the entire process. In my FE8 hack, a typical reinforcment event would look like this: TurnBasedEvents: TurnEventPlayer(0x00,BeginningScene,0) TurnEventEnemy(0x0D,ReinforceArm,8) TurnEventEnemy(0x0E,ReinforceArm2,3) TurnEventEnemy(0x0F,ReinforceArm3,5) TurnEventEnemy(0x10,ReinforceArm3,7) TurnEventEnemy(0x11,ReinforceArm2,9) TurnEventEnemy(0x12,ReinforceArm3,11) TurnEventEnemy(0x12,ReinforceArm3,4) TurnEventEnemy(0x12,ReinforceArm3,6) TURN REIN4: UNIT 0x75 0x09 0x45 Level(15,NPC,True) [8,19] 0b 0x00 0x01 28eREDA [0x1a,0x00,0x00,0x00] [0x00,0x2,0x0,0x00] //MK-I UNIT 0x45 0x4e 0x00 Level(15,NPC,True) [9,19] 0b 0x00 0x01 29eREDA [0x10,0x00,0x00,0x00] [0x00,0x2,0x0,0x00] //Sol UNIT Empty ReinforceArm: CAM2 [10,15] LOU1 REIN4 MUS1 0x3c FADI 10 Text(0x09eb) FADU 10 REMA CHAI 0x54 ENDA or this REIN2: UNIT 0x77 0xa2 0x48 Level(6,Enemy,True) [14,0] 0b 0x00 0x01 24eREDA [0xb1,0x00,0x00,0x00] [0x00,0x0,0x0,0x00] //dog UNIT 0x77 0xa2 0x48 Level(6,Enemy,True) [15,0] 0b 0x00 0x01 25eREDA [0xb1,0x00,0x00,0x00] [0x00,0x0,0x0,0x00] UNIT Empty ReinforceArm2: CAM2 [4,13] LOU1 REIN2 ENDA Edited August 19, 2013 by Blademaster! Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 19, 2013 Share Posted August 19, 2013 LOU1 doesn't work in FE8 anymore Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 19, 2013 Author Share Posted August 19, 2013 CHAI doesn't work either, which is another part of FE8 events that sucks. What does 'CHAI 0x54' mean, anyway? I mean, it'd be nice if I was wrong and there's an easy way; but the _LOAD 1/2/3 commands are used only during cutscenes, not during actual chapters. For instance, using the _LOAD commands during a chapter causes a fade to black. On the positive side, I just found out that '_LOAD3 0x0 pointer' pointing at a UNIT list with just one unit in it will load your main lord with the position and allegiance data of the UNIT data at the pointer with their current inventory and stats, even if they're already on the map! I next tried it with a UNIT list with seven units in it, which restarted the game for...some reason. Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 19, 2013 Share Posted August 19, 2013 VBA restarts if an ASM error occurs, so that's probably what happened Quote Link to comment Share on other sites More sharing options...
Matt Snow Posted August 19, 2013 Share Posted August 19, 2013 Umm I have the same question as Vennobennu, what exactly are you trying to do? I mean I normally bring in reinforcements like he said, though I change the LOU1 to _LOAD1.... I mean, it'd be nice if I was wrong and there's an easy way; but the _LOAD 1/2/3 commands are used only during cutscenes, not during actual chapters. For instance, using the _LOAD commands during a chapter causes a fade to black. Woah really O_O- This has never happened to me... I think, what do you mean causes a chapter to fade to black? Because I always use _LOAD1 and the chapter plays fine... Quote Link to comment Share on other sites More sharing options...
Blademaster! Posted August 20, 2013 Share Posted August 20, 2013 LOU1 doesn't work in FE8 anymore Why? That sounds silly to take something that worked before and then make it not work (Please understand that the code I posted is years old). Also, I don't really remember what CHAI 0x54 did. In fact, I don't think it should've done anything basedon the chapter I used that in. Might have been just something I left over on accident when I copied and pasted the code in. Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 20, 2013 Share Posted August 20, 2013 it's because nintenlord discovered that the code we labeled LOU1 doesn't actually do what you think it does Quote Link to comment Share on other sites More sharing options...
Blademaster! Posted August 20, 2013 Share Posted August 20, 2013 Then what did it do? Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 20, 2013 Share Posted August 20, 2013 (edited) clearly not the same thing that it did in fe7! --- nintenlord discovered that it broke things and disabled it Edited August 20, 2013 by CT075 Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 20, 2013 Author Share Posted August 20, 2013 (edited) Woah really O_O- This has never happened to me... I think, what do you mean causes a chapter to fade to black? Because I always use _LOAD1 and the chapter plays fine... Huh, that's strange. Whenever I try to use _LOAD1 or _LOAD2, the screen fades to black for a moment before going back to normal. And it doesn't automatically pan the camera over the reinforcements like the _LOAD_WHATEVER command does. Could you share an event where you use _LOAD1 during a chapter? I'd like to see if I'm just making a mistake with my use of it. Edited August 20, 2013 by Vennobennu Quote Link to comment Share on other sites More sharing options...
Kngt_Of_Titania Posted August 20, 2013 Share Posted August 20, 2013 (edited) I was going to make a post on this a while back when I was working on C6 for FEE3, but I'll just add what I think I know to what you found -- most of this is copied from a text file I made while testing these events. 1) Reinforcement events are almost always set like so (pretty much what you found): labelA:_SETVAL 0x2 0xMYPOINT (insert pointer of interest here)CALL labelBlabelB:_0x1020 0x4CALL labelC_0x0228 0x9_LOAD_WHATEVER 0x1ENUN_0x0220 0x9_0x1020 0x0ENDAlabelC:_0x1020 0x1_0x0220 0x2_0x0320 0x8_SETCONDITION 0x0 0xC 0x0FADU 16ENIF 0x0_0x1020 0x0ENDA 2) _0x0228 0x7 before ENDA (or immediately after _LOAD1, VCWF, etc.) avoids that annoying black fade-in associated with most functions (LOAD, etc.)! 3) Not sure what first line does, but these lines always seem to be paired. Y is the text ID (from Feditor)._SETVAL 0x2 0x2_SETVAL 0x3 0xY In this next code, 0xFFFF is whatever text ID is set up in the previous code -- i.e.Y from _SETVAL 0x3 0xY. TEXTSHOW 0xFFFFTEXTEND Note that a few varieties of this exist. 4) The below is a character present condition; 0xZ is the condition ID and 0xY is the character ID -- 0x13 is Artur, 0x1 is Eirika (this is from Ch. 4 Lute recruitment), for example. Seems to go right to ENIF is marked as true. _SETVAL 0x7 0xY_SETCONDITION 0xZ 0xC 0x7 5) Similar to character present check in #4, but it is used for the AREA events, not villages. In other words, check to see if the character that proc'd the AREA event is the one you're checking for (think Eirika in Ch. 1 FE8 -- she must proc the AREA event for reinforcements to come). Considering what the OP found concerning SETVAL, may be the same thing as #4. _SETVAL 0x2 0xY_SETCONDITION 0x0 0xC 0x2 6) The below looks like the "is character dead?" condition; 0xY is the event ID and 0xZ is the condition ID._0x0322 0xY_SETCONDITION 0xZ 0xC 0x0 7) The below looks like the "is this event ID unused?" condition; 0xY is the event ID and 0xZ is the condition ID. _0x0321 0xY_SETCONDITION 0xZ 0xC 0x0 8) _0x0221 0xY sets the event ID Y as unused! Note that it is _0x0221, while the conditional to check if an event is unused is _0x0321. This can't be a coincidence. 9) _0x0221 0xFFFF is similar to #8, but it's awesome in that it marks the event ID that was associated with the event as unused. I've manipulated this command for my reinforcements in Ch.6 (which should be shown in FEE3 soon), so I know that this works. 10) I don't yet know what marks an event ID as used. Maybe _0x0220 0xY? (Untested at this point) I NEED TO KNOW. GAH. Edited August 20, 2013 by Kngt_Of_Titania Quote Link to comment Share on other sites More sharing options...
Matt Snow Posted August 20, 2013 Share Posted August 20, 2013 Sorry didn't see this XD. Well I inserted these events and I don't really notice a fade to black when it loads units. #include EAstdlib.event #include Definitions_SH.txt EventPointerTable(0x07,ThisChapter) ORG 0x00EF8820 ThisChapter: POIN TurnBasedEvents POIN CharacterBasedEvents POIN LocationBasedEvents POIN MiscBasedEvents POIN Dunno Dunno Dunno POIN Tutorial POIN TrapData TrapData POIN Allied Enemies POIN $0 $0 $0 $0 $0 $0 POIN BeginningScene EndingScene ALIGN 4 TurnBasedEvents: TurnEventPlayer(0x0,BeginningScene,0) TurnEventPlayer(0x0,Noa_Arrives,2) TURN Noa_Arrives: _LOAD1 0x0 Others ENUN FlashCursor(3,0,60) //Flash Cursor on Noa ENUN Text(0x912) //Hey what's going on, why are Tyg and Garlan fighting. REMA ENDA ALIGN 4 Allied: UNIT Tyg Myrmidon 0x00 Level(1,Ally,False) [4,0] 0x00 0x00 0x00 0x00 [ironSword,SlimSword,0x0,0x0] NoAI UNIT Garlan Fighter Tyg Level(1,Ally,False) [3,0] 0x00 0x00 0x00 0x00 [Hatchet,IronAxe,0x0,0x0] Defend UNIT Scene_Units: UNIT Tyg Myrmidon 0x00 Level(1,Ally,False) [5,4] 0x00 0x00 0x00 0x00 [ironSword,SlimSword,0x0,0x0] NoAI UNIT Garlan Fighter Tyg Level(1,Ally,False) [3,4] 0x00 0x00 0x00 0x00 [Hatchet,IronAxe,0x0,0x0] Defend UNIT Noa Archer Tyg Level(1,Ally,False) [4,5] 0x00 0x00 0x00 0x00 [ironBow,ManiKatti,0x0,0x0] Defend UNIT Others: UNIT Noa Archer Tyg Level(1,Ally,False) [3,0] 0x00 0x00 0x00 0x00 [ironBow,ManiKatti,0x0,0x0] Defend UNIT Civ_Unit: UNIT 0x8E 0x6F 0x00 Level(3,NPC,True) [11,8] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] MoveGuard UNIT Enemy_Leader: UNIT ONeill Brigand 0x00 Level(4,Enemy,False) [11,6] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] Defend UNIT ALIGN 4 Enemies: UNIT 0x55 Brigand 0x00 Level(3,Enemy,True) [12,3] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] MoveGuard UNIT 0x58 Brigand 0x00 Level(2,Enemy,True) [12,2] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] Wait2Turns UNIT 0x59 Brigand 0x00 Level(1,Enemy,False) [13,2] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] NoAI UNIT 0x61 Brigand 0x00 Level(1,Enemy,False) [12,1] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] Wait1Turn UNIT 0x62 Brigand 0x00 Level(1,Enemy,False) [11,1] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] Wait2Turns UNIT 0x63 Brigand 0x00 Level(1,Enemy,False) [10,1] 0x00 0x00 0x00 0x00 [ironAxe,HandAxe,0x0,0x0] NoAI UNIT ALIGN 4 CharacterBasedEvents: CHAR LocationBasedEvents: LOCA ALIGN 4 MiscBasedEvents: DefeatAll(EndingScene) AFEV Dunno: //DO NOT TOUCH WORD $00 Tutorial: //DO NOT TOUCH WORD $00 TrapData: ENDTRAP ALIGN 4 ALIGN 4 BeginningScene: FADI 0x20 LOMA 0x40 ENUN _LOAD1 0x0 Scene_Units //loads guys at beginning ENUN Text(0x15,0x90D) //text REMA STAL 0x20 MOVE Tyg [14,3] MOVE Garlan [13,3] MOVE Noa [12,3] ENUN DISA Tyg ENUN MOVE Garlan [14,3] MOVE Noa [13,3] ENUN DISA Garlan ENUN MOVE Noa [14,3] ENUN DISA Noa ENUN STAL 0x20 FADI 0x20 LOMA 0x00 ENUN _LOAD1 0x0 Civ_Unit //Loads civilian ENUN REMA STAL 0x20 FlashCursor(11,8,60) //Flash Cursor on him ENUN Text(0x18,0x90E) //text REMA MOVE 0x8E [9,9] ENUN DISA 0x8E //make civ leave ENUN STAL 0x30 _LOAD1 0x0 Allied //Load Tyg and Garlan ENUN FlashCursor(4,0,60) //Flash Cursor on Tyg ENUN Text(0x18,0x90F) //Text about how they have to go to the beach and back, Noa will catch up REMA MOVE Tyg [9,6] MOVE Garlan [8,5] //Moves them Closer to the beach ENUN FADI 0x20 _LOAD1 0x0 Enemy_Leader ENUN Text(0x18,0x910) // Text about how they're almost there, then bandits show up REMA _LOAD1 0x0 Enemies MOVE 0x55 [13,5] MOVE 0x58 [13,8] MOVE 0x59 [11,8] MOVE 0x61 [6,0] MOVE 0x62 [4,2] MOVE 0x63 [6,4] ENUN Text(0x911) //We gotta fight them off REMA MOVE ONeill [12,3] ENUN ENDA ALIGN 4 EndingScene: FADI 0x20 Text(0x18,0x913) REMA MNC2(0x01) ENDA MESSAGE Events end at offset currentOffset //The map for this offset is at 00EF86D0 Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 21, 2013 Author Share Posted August 21, 2013 Well, you're using your _LOAD1 command as part of a scene, which I think is part of why it's working for you-LOAD1 is used during cutscenes in the vanilla game and obviously it doesn't cause fade-ins all the time, but when one tries to use it as its own thing as part of a TURN or AREA code, it does fade. Although, given what KoT just said about _0x0228 0x7, it seems that it is possible to use _LOAD1 anyhwere without problems. ...Which makes me wonder why reinforcements in this game use the _SETVAL method; it doesn't seem to offer any advantages over just using _LOAD1 and labels, at least from what I know of the codes. I do have some ideas as to why it is used: 1) _LOAD1 doesn't work consistently with TURN (and AREA?) triggers. -PKL has told me that using _LOAD1 to load up reinforcements as a turn event during a chapter causes the reinforcements to either load with the other units at the beginning of the chapter, not load at all, or cause a game over. 2) _LOAD1 doesn't respect the 50 unit cap. -Perhaps the unknown codes used in the vanilla reinforcement are checks against this and other potential issues. Anyway, nice job KoT for that data on event commands! I think it will be a great help to anybody making an FE8 hack. In other news, I think I've found out how to move a unit from a given set of coordinates, instead of by moving a character of a given character ID. The important bit is this: [spoiler=Chapter 1 Enemies Deploy] _SETVAL 0x2 0x89EFC24 CALL label33 MOVE 0x46 [2,2] _SETVAL 0xB 0x60001 _MOVE 0x18 0xFFFE [1,3] _SETVAL 0xB 0x60003 _MOVE 0x18 0xFFFE [3,3] _SETVAL 0xB 0x80001 _MOVE 0x18 0xFFFE [9,5] _SETVAL 0xB 0x70002 _MOVE 0x18 0xFFFE [8,3] _SETVAL 0xB 0x80003 _MOVE 0x18 0xFFFE [4,7] _SETVAL 0xB 0x90002 _MOVE 0x18 0xFFFE [2,8] ENUN _0x0E22 0x3C label33: _0x1927 _SETCONDITION 0x0 0xC 0x0 _CALL_HELL ENIF 0x0 ENDA label33 is called frequently throughout the chapter, which is why it is seperated from the main stream of the beginning scene. I believe that the 0xFFFE may tell the game to load data from the memory slot last used. In fact, you might be able to use this same method to change the AI of units at a given set of coords too; I'll post here if I can confirm it. Quote Link to comment Share on other sites More sharing options...
Matt Snow Posted August 21, 2013 Share Posted August 21, 2013 I did use it as part of a TURN event, here when I load a character on turn 2: ALIGN 4 TurnBasedEvents: TurnEventPlayer(0x0,BeginningScene,0) TurnEventPlayer(0x0,Noa_Arrives,2) TURN Noa_Arrives: _LOAD1 0x0 Others ENUN FlashCursor(3,0,60) //Flash Cursor on Noa ENUN Text(0x912) //Hey what's going on, why are Tyg and Garlan fighting. REMA ENDA Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 21, 2013 Author Share Posted August 21, 2013 Huh. Well then I don't know what happened. Maybe having a text event afterwards makes it not fade in? That's the only difference I can find between this: TurnBasedEvents: TURN 0x0 label24 [5,0] 0x8 END_MAIN label24: _LOAD1 0x0 Extras ENUN ENDA And your event. Quote Link to comment Share on other sites More sharing options...
Kngt_Of_Titania Posted August 21, 2013 Share Posted August 21, 2013 (edited) Huh. Well then I don't know what happened. Maybe having a text event afterwards makes it not fade in? That's the only difference I can find between this: TurnBasedEvents: TURN 0x0 label24 [5,0] 0x8 END_MAIN label24: _LOAD1 0x0 Extras ENUN ENDA And your event. I was thinking that it's possible that ENUN could be used in place of _0x0228 0x7 (I haven't tested this, it's just conjecture atm), based mainly on the fact that he uses it in locations similar to those I find _0x0228 0x7 needs to be placed as well as the distinct lack of ENUN in vanilla FE8 events that I noticed in certain routines; this may even suggest that _0x0228 0x7 and ENUN serve similar functions. I don't have time right now (midterm tomorrow), but the theory would be easily tested. Edited August 21, 2013 by Kngt_Of_Titania Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 21, 2013 Author Share Posted August 21, 2013 (edited) I can confirm that the command _0x0229 will mark an Event ID as used. Chapter 10A uses this command to force Marisa's aggro convo to only trigger on the enemy phase following a player unit triggering an AREA event, and for the Falcoknight and Ranger reinforcements to not occur until Marisa's recruitment event occurs. Thanks to KoT's notes on _SETCONDITION, I've puzzled out an outline of how the game handles AI changes and conditionals: //From Chapter 10A: AREA 0x7 label36 [0,19] [19,30] //Aggro Marisa's group TURN 0xE label25 [1,255] 0x8 //Convo when aggroing Marisa's group label36: _SETVAL 0x2 0x0 // Loads value 0x0 into memory slot 2 CALL label60 _0x0221 0xE //Mark Convo event as unused _SETVAL 0xD 0x0 // Loads New AI? Into Memory Slot 0xD (Could write as _SETVAL 0xD 0x00000000) _SETVAL 0x1 0x1D000D // Loads coordinates of unit to change (in y,x order) into memory slot 1 _SAVEFORBATTLE // Not sure what this does - it appears in many circumstances. Might change AI? _SETVAL 0x1 0x1C000E _SAVEFORBATTLE //Seems to require a value loaded to Memory Slot 1, though. _SETVAL 0x1 0x1D000F _SAVEFORBATTLE _SETVAL 0x1 0x1C0010 _SAVEFORBATTLE _SETVAL 0x1 0x1D0011 _SAVEFORBATTLE _SETVAL 0x1 0x1E000E _SAVEFORBATTLE _SETVAL 0x1 0x1E0010 _SAVEFORBATTLE _SETVAL 0x1 0x1E0012 _SAVEFORBATTLE _SETVAL 0x2 0x1000000 CALL label61 _0x0228 0x7 // Prevents random fadein effects? ENDA // Go back to parent event - since this event has no parents, this is the end. label60: _0x3325 0xFFFF _SETCONDITION 0x0 0xC 0x2 // If the character ID of the triggering character does not match value loaded in Slot 2... CALL label38 // Go to label38 - Never happens, as ID 0x0 is nonspecific? ENIF 0x0 // If it does match, go back to label36 ENDA label38: _0x1929 _0x0620 0xC2 _0x0221 0xFFFF //Mark Event ID of event currently activated as unused - Which is our AREA event. _0x0228 0x7 ENDB // Stop reading this event and its parents and go back to the normal game label61: ENIF 0x0 _0x0C44 0x1 0xD 0x0 //Some sort of conditional - not about character ID's? _0x0620 0x21 _0x0722 0xB _0x3921 0xFFFF //Perhaps this stuff is used to trigger every unit's AI change? ELSE 0x0 ENIF 0x1 ENDA I've figured out how to change the AI of units during chapters. It's actually pretty simple once you break it down into its essential components. Changing the AI of characters is straightforward. You just do this: CauseAggro: _SETVAL 0x1 0x1000000 //Loads new AI - Length of one word _0x3920 0xE //Change AI of character 0xE to value loaded in Memory Slot 0x1 _SETVAL 0x1 0x10000 _0x3920 0x83 // The generic wyvern riders in this chapter use character ID 0x83 _0x0228 0x7 //Stop random fade-in ENDA The interesting thing is that _0x3920 will affect all units on the map with the given character ID. This code causes Cormag and his two subordinates to start chasing you even though _0x3920 is only executed twice. For changing AI of units at given coordinates, it's a little bit complicated, but still easy to implement: GuardsCharge: _SETVAL 0x1 0xC0010 //Load value (coordinates YY00XX for us) 0x0C0010 into Memory Slot 1 _SAVEFORBATTLE //Store this value. _SETVAL 0x1 0xE0010 _SAVEFORBATTLE _SETVAL 0x1 0xD000F _SAVEFORBATTLE _SETVAL 0x2 0x1000000 // Loads new AI, word length - If AI Byte 1 is less than 10, drop the first 'digit'. CALL AIChangeLoop _0x0228 0x7 ENDA AIChangeLoop: //This appears to be a simple loop: it will run until every unit listed has their AI changed. ENIF 0x0 _0x0C44 0x1 0xD 0x0 //Sets condition _0x0620 0x21 //Loads unit at coords? _0x0722 0xB _0x3921 0xFFFF //Changes AI of unit currently loaded to value loaded at Memory Slot 0x2. You can use a single loop for multiple AI change events. ELSE 0x0 ENIF 0x1 ENDA So in summary: Changing the AI of a character uses _0x3920. Changing AI of a unit at a coordinate uses _0x3921. Character AI changes are done individually; _0x3920 can work with a single input. Coordinate AI changes are done all at once, and need a loop to function - _0x3921 doesn't work by itself. So that's how you change AI. Pretty interesting, eh? Edited August 23, 2013 by Vennobennu Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 23, 2013 Author Share Posted August 23, 2013 I've been looking into the units in skirmishes to see if it's possible to use the same randomization code for humans; the results are interesting and a little discouraging. First, all random enemies in skirmishes have '101' in binary as their Flag. '1' will automatically give the unit an inventory based on their class; and what items that they get seem to be based on some pre-defined table (see this list of monster items). But '100' (or 4) will slightly randomize their coordinates and class. It will keep them in the vicinity of their defined coordinates, though, and what classes they can randomly appear as is limited by their defined class - so, Bonewalkers and become Revenants or Bow Bonewalkers, but not Baels; Gargoyles can become Mogalls but not Deathgoyles or Tarvoses. You could say that there are categories of monsters, and a random monster can only become a class that's in it's own category. Anyway, the classes of monsters in skirmishes are defined strangely. Instead of using their actual class ID's, random monsters use valueslike 0x1 to 0x14: [spoiler=An example] UNIT 0xAC 0x2 0x0 0x55 [19,4] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xBB 0x14 0x0 0x55 [21,18] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x0,0xC,0x0] UNIT 0xB0 0x6 0x0 0x55 [4,13] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xAC 0x2 0x0 0x55 [18,3] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xBB 0x14 0x0 0x55 [20,19] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x12,0xC,0x0] UNIT 0xBB 0x14 0x0 0x55 [22,4] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xBB 0x14 0x0 0x55 [22,6] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x0,0xC,0x0] UNIT 0xBB 0x14 0x0 0x55 [21,5] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xB3 0x9 0x0 0x55 [3,4] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x12,0xC,0x0] UNIT 0xAD 0x4 0x0 0x55 [16,14] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] UNIT 0xAB 0x1 0x0 0x55 [18,14] 101b 0x0 0x0 0x0 [0x0,0x0,0x0,0x0] [0x0,0x3,0xC,0x0] This makes me think that the class ID is being used as an index in a table, or a constant in a calculation that finds their class, or something to that effect. What I've done to experiment with this is give monsters a flag of 1b, to stop their class from fluctuating, and tested various values for their class ID to see what happened. [spoiler=Long] 1 - Revenant2 - Bonewalker Melee3 - Wight Bow4 - Bonewalker Bow5 - Wight Melee6 - Bael7 - Elder Bael8 - Cyclops9 - Mauthe DoogA - GwyllgiB - BaelC - MaelduinD - MogallE - MogallF - Mogall10 - Arch Mogall11 - Arch Mogall12 - Arch Mogall13 - Gargoyle14 - Gargoyle15 - Deathgoyle16 - Deathgoyle17 - Gorgon18 - Dracozombie19 - Revenant1A - Bael1B - Cyclops 21C - Elder Bael 21D - Queen (No items)1E - Bonewalker Bow (No items from here on in)1F - Ranger20 - Hero21 - Boss Mercenary (Empty, Hangs game)22 - Bonewalker (No items still)23 - Mage Knight24 - Wyvern Lord (Weird Map animation - incomplete?)25 - Bonewalker Sword26 - Summoner27 - Bonewalker Bow28 - Garbage Eph. Lord, Crashes game, wipes saves29 - Garbage Eph. Lord (Doesn't crash)2A - Garbage Eph. Lord2B - Garbage, may mess up FoW2C - Garbage, Invisible in FoW2D - Tarvos (Has weapons again!)2E - Arch Mogall2F - Bonewalker Sword (No items)30 - Mauthe Doog31 - Archer in Ballista (No items again past here)32 - Gorgon Egg (Can't select)33 - Bonewalker Bow34 - Knight (F)35 - Mymridon (F)36 - Archer37 - Ephraim Lord38 - Pupil (1)39 - Bonewalker Bow3A - Knight (F)3B - Archer3C - Bael3D - Ephraim Lord3E - Knight (F)3F - Ranger (F)40 - Knight (F)41 - Ranger (F)42 - Myrmidon (F)43 - Sage (F)44 - Bonewalker Sword45 - Myrmidon (F)46 - Fleet47 - Bonewalker Sword48 - Myrmidon (F)49 - Bard4A - Bonewalker Sword4B - Archer From this, I can say that while it's possible to have 'random humans', the human classes don't have any item lists corresponding to them, causing the 1b flag to do nothing. To make it possible, you'd have to find the item table - and that class lookup table - to give them such a list. Quote Link to comment Share on other sites More sharing options...
Blademaster! Posted August 24, 2013 Share Posted August 24, 2013 Did you look at FurryYeongsun's(Can't remember the spelling. Guy who made GhebFE) notes on Skirmishes to see if that helps you? Also, why does everything look like it's only become harder to hack into FE8 with? Quote Link to comment Share on other sites More sharing options...
CT075 Posted August 24, 2013 Share Posted August 24, 2013 probably because the old stuff was wrong Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 24, 2013 Author Share Posted August 24, 2013 (edited) FurryYeongsun's notes don't have any useful details in them, unfortunately. But honestly, I think FE8 hacking is much easier than it was before, because now we have decent Event Assembler support, and progress has been made recently in uncovering the functionality of the unknown commands. Since I have a compulsive need to put new information in every post I make, I will say that for basic reinforcement events, it seems like you can just get away with this: [spoiler=Unit Loading] Reinforce: _SETVAL 0x2 (Reinforcements|0x8000000)//Creates a pointer to a unit label; must be done like this _LOAD_WHATEVER 0x1 ENUN _0x0228 0x7 ENDA Reinforcements: UNIT 0x80 WyvernRider 0x0 0x15 [5,0] 0b 0x0 0x2 Fly2 [0x17,0x0,0x0,0x0] [0x0,0x0,0x0,0x0] UNIT 0x80 WyvernRider 0x0 0x15 [5,0] 0b 0x0 0x2 Fly3 [0x17,0x0,0x0,0x0] [0x0,0x0,0x0,0x0] UNIT 0x80 WyvernLord 0x0 0x15 [5,0] 0b 0x0 0x2 Fly4 [0x18,0x0,0x0,0x0] [0x0,0x0,0x0,0x0] UNIT 0x80 WyvernLord 0x0 0x15 [5,0] 0b 0x0 0x2 Fly5 [0x18,0x0,0x0,0x0] [0x0,0x0,0x0,0x0] UNIT 0x80 WyvernRider 0x0 0x15 [5,0] 0b 0x0 0x1 Fly [0x17,0x0,0x0,0x0] [0x0,0x0,0x0,0x0]//Can't have >4 REDA's moving at the same time UNIT But, this was tested in a chapter with almost no other events, so who knows why the vanilla game loads reinforcements in the circuitous way it does. Perhaps it is set up so that one format can be used for all possible types of reinforcements, which seems a little space-ineffecient. Edited October 5, 2013 by Vennobennu Quote Link to comment Share on other sites More sharing options...
Vennobennu Posted August 28, 2013 Author Share Posted August 28, 2013 (edited) People have in the past encountered the problem where if a non-aggressive unit has its AI changed during a chapter to an aggressive one, it will not attack enemies that would not be in range under its old AI; hence the case of pursuing enemies that won't attack after moving. Well, there is a simple fix to this. Setting a unit's initial AI Byte 4 to 0x20 (Stand Still) is what causes this behaviour. If you instead set AI Byte 1 to 0x03 (Stand Still, do not attack in Nightmare), the unit will properly respect any AI changes during the chapter. So, you would set the unit's initial AI in Event Assembler like so: [0x3,0x3,0x9,0x0] And then change it to an aggressive configuration with your event. I tested this in FE8, but I have no reason to believe that this method wouldn't work in FE7. Edit: Oh yeah! If you want to make an AREA code only triggerable by player units (and you probably will), then make sure the area event goes like this: [spoiler=Allegiance-Based Triggering] GuardsCharge: _SETVAL 0x2 0x0 //Loads 0x0, the ID of the player allegiance, into memory slot 2 CALL Surety //This sequence is the check for the unit's allegiance _SETVAL 0x1 0x10000 _0x3920 0x80 //Change AI of all units with character ID 0x80 _0x0228 0x7 ENDA Surety: _0x3325 0xFFFF _SETCONDITION 0x0 0xC 0x2 //Checks value loaded into memory slot 2; skip to ENIF 0x0 if they match CALL Surety2 ENIF 0x0 ENDA Surety2: _0x1929 _0x0620 0xC2 _0x0221 0xFFFF //Sets the Event ID related to this event as unused? _0x0228 0x7 ENDB //End all event execution, go back to main stream Edited September 30, 2013 by Vennobennu Quote Link to comment Share on other sites More sharing options...
Alfred Kamon Posted September 1, 2013 Share Posted September 1, 2013 (edited) Oh wow, this is quite the topic. That AI change discovery is great, I had to reload all my units till now and it was a pain to come up with that kind of events, even if they actually worked. Just a few notes. 6) The below looks like the "is character dead?" condition; 0xY is the event ID and 0xZ is the condition ID._0x0322 0xY_SETCONDITION 0xZ 0xC 0x07) The below looks like the "is this event ID unused?" condition; 0xY is the event ID and 0xZ is the condition ID. _0x0321 0xY_SETCONDITION 0xZ 0xC 0x0 Actually it's the opposite. Invert the conditions order. If it's ALIVE it does this If it's DEAD it does that // If event ID is USED do this if it's UNUSED do that. example: _0x0322 0xY _SETCONDITION 0xZ 0xC 0x0 // Events that occur if Unit 0xY is alive ELSE 0xW ENIF 0xZ // Events that occur if Unit 0xY is dead ENIF 0xW same thing for the other one. Also: _0x0221 0xFFFF considers the event ID associated to the event as unused Actually that alone won't work. It has to be: _0x1929_0x0620 0xC2_0x0221 0xFFFF And: I was thinking that it's possible that ENUN could be used in place of _0x0228 0x7 (I haven't tested this, it's just conjecture atm), based mainly on the fact that he uses it in locations similar to those I find _0x0228 0x7 I'm 100% sure that ENUN can't be used in place of _0x0228 0x7. The latter is to end events, the first is to wait for any movement-type action to finish. They're quite different, and I'm sure that ENUN doesn't work like that since I've had it at the end of most of my codes before discovering _0x0228 0x7 (which I'm not always using anyway since I like that fade-in/out effect, it's kind of scenic). Great topic anyway. Edited September 1, 2013 by Alfred Kamon Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.