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

Pages: [1] 2 3 4 5 6 ... 10
Team Avalanche / Re: Project Edge (Jusete's field scenes)
« on: 2023-06-06 21:34:11 »
It's been quite a while that I've visited qhimm, so I just wanted to say that I'm glad that this project still seems to be alive. Props Jusete, your work is inspirational!

OK then, here's a rough finalised version of the complete Enemy AI Script. I plan to work on it some more in the near future:

OK, I lied, one last question before I can wrap this thing up :)

What's 402A used by Sephiroth only (Kalm Flashback version)? Status immunity?

edit - Nope, not Status immunity....

edit - The 402A flag prevents attacks from consuming MP.

Thanks, thought as much.

Think I'm done with my AI Script questions now, thanks for all the help!

Any idea what 2018 does?

Cloud's AI Script:

Code: [Select]

0x000LocalVar:BattleLovePointsOffset <- 255
0x006 If (BattleAddr(&Self).BattleAddr(&ChrCovered) == 19)
0x006 {
0x012 LocalVar:BattleLovePointsOffset <- 80
0x018 }
0x018 Else
0x018 {
0x01B }
0x01B Else
0x01B {
0x01E If (BattleAddr(&Self).BattleAddr(&ChrCovered) == 18)
0x01E {
0x023 LocalVar:BattleLovePointsOffset <- 81
0x029 }
0x029 Else
0x029 {
0x02C }
0x02C Else
0x02C {
0x02F If (BattleAddr(&Self).BattleAddr(&ChrCovered) == 21)
0x02F {
0x034 LocalVar:BattleLovePointsOffset <- 82
0x03A }
0x03A Else
0x03A {
0x03D }
0x03D Else
0x03D {
0x040 If (BattleAddr(&Self).BattleAddr(&ChrCovered) == 17)
0x040 {
0x045 LocalVar:BattleLovePointsOffset <- 83
0x04C If ( (LocalVar:BattleLovePointsOffset != 255) )
0x04C {
0x055 TempGlobal <- &GlobalVar(0000)
0x05B BattleAddr(&2018) <- BattleAddr(&MemBank1/2)
0x062 BattleAddr(&MemBank1/2) <- BattleAddr(&MemBank1/2) + 3
0x06C If ( (BattleAddr(&MemBank1/2) > 200) )
0x06C {
0x075 BattleAddr(&MemBank1/2) <- 200
0x07B GlobalVar(0000) <- &TempGlobal)
0x081 Debug.Print: "LOVEPARA CHR:%d, %d->%ds" ; BattleAddr(&Self).BattleAddr(&ChrCovered) - 16; BattleAddr(&2018); BattleAddr(&MemBank1/2)
0x081 }


0x000LocalVar:ChrID <- 0
0x006 If ( (LocalVar:ChrID < 3) )
0x006 {
0x00F BattleAddr(&TarSelected) <- FlagBit(LocalVar:ChrID)
0x017 If (BattleAddr(&TarSelected).BattleAddr(&DeathStatus))
0x017 {
0x021 LocalVar:BattleLovePointsOffset <- 255
0x027 If (BattleAddr(&TarSelected).BattleAddr(&GrpFormID) == 19)
0x027 {
0x033 LocalVar:BattleLovePointsOffset <- 80
0x039 }
0x039 Else
0x039 {
0x03C }
0x03C Else
0x03C {
0x03F If (BattleAddr(&TarSelected).BattleAddr(&GrpFormID) == 18)
0x03F {
0x044 LocalVar:BattleLovePointsOffset <- 81
0x04A }
0x04A Else
0x04A {
0x04D }
0x04D Else
0x04D {
0x050 If (BattleAddr(&TarSelected).BattleAddr(&GrpFormID) == 21)
0x050 {
0x055 LocalVar:BattleLovePointsOffset <- 82
0x05B }
0x05B Else
0x05B {
0x05E }
0x05E Else
0x05E {
0x061 If (BattleAddr(&TarSelected).BattleAddr(&GrpFormID) == 17)
0x061 {
0x066 LocalVar:BattleLovePointsOffset <- 83
0x06C POP(BattleAddr(&TarSelected).BattleAddr(&GrpFormID))
0x06D If ( (LocalVar:BattleLovePointsOffset != 255) )
0x06D {
0x076 TempGlobal <- &GlobalVar(0000)
0x07C BattleAddr(&2018) <- BattleAddr(&MemBank1/2)
0x083 BattleAddr(&MemBank1/2) <- BattleAddr(&MemBank1/2) - 5
0x08D If ( (BattleAddr(&MemBank1/2) < 50) )
0x08D {
0x096 BattleAddr(&MemBank1/2) <- 50
0x09C GlobalVar(0000) <- &TempGlobal)
0x0A2 Debug.Print: "LOVEPARA CHR:%d, %d->%d" ; BattleAddr(&TarSelected).BattleAddr(&GrpFormID) - 16; BattleAddr(&2018); BattleAddr(&MemBank1/2)
0x0CC LocalVar:ChrID <- LocalVar:ChrID + 1
0x0D6 LOOP 0x006

The only logical thing it can be doing is setting the offset value to the Mem Bank access value. It's obvious that the script is not adjusting $GameMoment (GlobalVar 0000). 2018 must be using the value of LocalVar:0000 (BattleLovePointsOffset) to set the membank value to record to.


According to the Fandom Wikia:

"The PC version has no restrictions on the use of Whirlsand and it will use it often at the start until only one character is alive or remaining. Ruby Weapon is invulnerable to everything, even defense-ignoring attacks or status effects until its tentacles are exposed.

I've had a look at the '97 PC version scene.bin and the Steam version, I can't see any difference in the AI script compared the PSX Pal version, or any other version for that matter (excluding the JORG and JINT versions).

Am I mistaken? Is there a difference in Ruby's use of Whirlsand in the PC version(s)?

Lol, just when I thought I had no more questions...

It seems Ruby makes use of a special "Pincer Attack" (Formation Type 4). All characters will be front-facing for this battle, but they will all still take double damage from the first use of Big Swing.

Also, if you command a character to feed another character a healing item such as an X-Potion, they will then face the opposite direction to then take double damage from Big Swing (Ruby's only Physical attack).

Also, the default "Attack from both sides"! prompt will not be displayed. Any idea what's controlling all of this?

Looking at the WM script:

Called by:
Addr   Code
2f65   SetControlsEnabled(#0000)
2f69   Op31c(#0001)
2f6d   CALL Model(GetSpecial(0008)).Function(0017)
2f6e   Op334()
2f6f   WaitForWindowReady()
2f79   SetWindowDimensions(#0080, #00a0, #0040, #0019)
2f7f   SetWindowParams(#0000, #0000)
2f80   WaitForWindowReady()
2f84   SetWindowMessage(#0022)
2f85   WaitForMessageAcknowledge()
2f89   SetCameraShakingEnabled(#0001)
2f8f   Op333(GetSpecial(0008), #0000)
2f93   PlaySoundEffect(#017f)
2f97   Op31f(#001e)
2f9e   IF ((GetSpecial(0008) == #0003)) {
2fa3     SetNumWaitFrames(#0019)
2fa4     Wait()
2fa5     GOTO 2fb4
2fad   IF ((GetSpecial(0008) == #0013)) {
2fb2     SetNumWaitFrames(#000f)
2fb3     Wait()
2fb7   Op31f(#0000)
2fbb   SetNumWaitFrames(#0019)
2fbc   Wait()
2fc4   Op3fd(#0001, #0006, #000a)
2fca   ActiveEntity.PlayAnimation(#0002, #0000)
2fce   PlaySoundEffect(#01b1)
2fd2   SetNumWaitFrames(#003c)
2fd3   Wait()
2fd7   Op3fe(#0001)
2fdb   Op34a(#0006)
2fdf   SetCameraShakingEnabled(#0000)
2fe5   ActiveEntity.PlayAnimation(#0000, #0001)
2fe9   SetNumWaitFrames(#0028)
2fea   Wait()
2ff0   WRITE Bank0[0387].Bit(5) = #0001
2ff4   TriggerBattle(SceneId=#03d6)
2ff8   Op31c(#0000)
2ff9   RETURN
Function 2ffa

I know the Save Map has this down as "0x20: World map Ruby Weapon form. bit=0: Small Form (before first encounter). bit=1: Big Form (after first encounter).", but, is there any chance that this could also be triggering some special battle flag?

Also, I can't work out exactly how to get the characters to face the tentacles when they are not buried; some weirdness is definitely going on here...

Ah, that could be it. I've tried changing 2140 as the battle begins, but that's not the address I need to edit. I'll have a play around with Cheat Engine at some point. I tried activating the final battle flag for the Pagoda enemies with Yuffie, as they also make use of Battle Type 8; obviously, the final battle flag is for Cloud only, so I couldn't really test there. I guess I could just edit the scene.bin, but it would be quicker to find the appropriate addr in CE.

Yup! Pre-Battle formation script for Sephrioth:
Code: [Select]
0x000BattleAddr(&2160) <- BattleAddr(&2160) OR 8
0x00ABattleAddr(&2160) <- BattleAddr(&2160) OR 32
0x014BattleAddr(&2180) <- 222

0x20 is toggling the custom "No Rewards Screen" (which is also toggled via 2110 OR 8 as part of the "Custom Event 8").

0x08 is toggling the "Final Battle Paramaters" which sets up the unique conditions for the final battle (Limits always filled, lose command window after one action by the enemy, ATB starts filled etc; it also works in conjunction with 2180 to allow the Limit to fill at a specific rate of 222).

Here is the Pre-Battle Formation AI Script for Safer:

Code: [Select]
0x000BattleAddr(&2160) <- BattleAddr(&2160) OR 48

0x20 again toggles the no rewards screen

0x10 allows Cloud to learn all limit breaks following the battle; however, Omnislash is *not* automatically set as the available ability to use (after testing against random encounters). The "Limit Level" will say Lv 4 when bringing up the in-battle Limit menu, but the abilities available will be the ones set previously (after doing one battle with 0x10 toggled then a second with 0x08 toggled):

It doesn't matter what condition I set up, Cloud never has Omnislash ready by default. The *only* time that Omnislash is available when recreating the steps used for the final two battles is during the final two battles; somewhere after defeating Safer and battling Sephiroth Cloud's Limit ability is set to Omni. I've scoured the field scripts thoroughly; it's not there (95% sure). I can only assume that there is some special script running somewhere for this battle....

That entire battleBG must have scripts running in the back of it though;

Yeah, I agree, there's definitely stuff going on in the background. I was testing with 0x08 Flag ON for 2160 on some random encounters, and a few things were constant every battle, such as the Limit command being available even without the Limit gauge being filled. I would also lose control of the characters after the first action performed by the enemy.

The thing that changed every battle is the use of the other command; sometimes I would only have the Limit Command available with no other option, and sometimes the normal command window would open. Also, sometimes the player's ATB would start filled, and sometimes they would start at random positions. There's definitely stuff going on in the background somewhere that makes sure this battle plays out properly.

Most of it I'm not too bothered about - the main query is exactly how Omnislash is becoming available as the Limit ability. I can't see anywhere that toggles this.

Does anyone know how Cloud's Limit is being set to lv 4 for the final Sephiroth encounter?

I can see that Safer uses 2160, and toggles 0x10. After testing, I can see that this will allow Cloud to learn all Limits following the battle; however, it does not automatically set the available Limit ability to Omnislash.

Sephiroth toggles 0x08 of 2160, which does a number of things, one of which *isn't* setting Cloud's Limit to Lv 4. After testing against Rnd Encounters, Cloud's Limit Level will say Lv 4 in the command window, but the previous abilities will be available from the level that was selected prior (Meteorain and Finishing Touch). This is after having done a battle with 0x10 ON, then doing another battle with 0x08 ON.

Also, I can see that there are a few additional animations used for the final battle. Firstly, the intro to the battle does a little "face flash" to Cloud then Seph a few times; Cloud's battle model uses a different model; Omnislash uses a slightly different animation (does a quick "face flash" on the final blow). Would it be safe to assume these are being handled via the AB files in the battle.lgp? Would it be possible that Cloud's Limit ability being set to Omnislash is also being handled by the same script?

I've sussed it !! :)

4278 is controlling which body part of the enemy is being selected.

It's not a bit-flag at all. The value is indicating which section of the actor's body to select The penny dropped while battling the Zemzelett. Toggling 4278 mid-battle had no effect, however, setting it to 1 pre-battle meant that it would instead target the tail.
I went through fifteen battles incrementing the value by one each time, and each time the finger icon would target one of various parts; its back, its beak, its right shoulder, its right wing, the base of its tail, the tip of its tail......

So that's it! 4278 = Body part of the actor selected! I've spent about 8 hours on that today. I gave up and watched three hours of TV then came back to it with a fresh perspective, and solved it within an hour :) Now I can go to bed :) Soooo glad to put that one behind me

Lol. If you set Jenova Synthesis 'B' 4278 to 10 instead of 16 (decimal), then it will instead target the actual tentacle, and not the part of the body where the tentacle stems out of. The finger icon even sways with the tentacle, it looks cooler than the default setting

4278 definitely has nothing to do with the Target icon

What if it's a bitmask for something?

Jen Synth A = 3 = 0x01 and 0x02 ON
Jen Synth B = 10 = 0x10 ON
Jen Synth C = 14 = 0x10 and 0x40 ON

What could it be toggling? It's not Elemental resistances, I've tested for that....

All other battles have these values set to FF, so maybe it's not that it's toggling the bits ON, but rather, it's toggling all of the other bits OFF. Or maybe it's just a dummied function that does nothing at all. I'd very much like to know.

-edit- Wow, there's quite a lot going on with the final bosses. I'm gonna leave 4278 until I've looked as Biz Seph, Safer and Emerald, as they all have something going on with 4278

2180 is another mystery only seen thus far with Carry Armor.

2165 is definitely 'disable rewards screen', as I tested it on a random encounter. I didn't clock the Formation Pre-Battle Script with Jen Synth; I'm glad I found it, I was banging my head against the wall trying to find the field script that disabled the Rewards flag (I was convinced it was set via the same BTLMD opcdode used in the Flashback lol).

Any idea what 4278 does?

Jen Synty A's 4278 = 3
Jen Synty B's 4278 = 10h
Jen Synty C's 4278 = 14h

Could this be something to do with the positioning of the "Target" icons that appears when you press R1 (or L1)? I can't really move on from Jen Synth until I've solved the 4278 mystery. It's possible that it could be a dummied out function; an educated assumption suggests that the N Crater was designed independently from the rest of the game, as opposed to sequentially; the $GM jump supports this.

It's also curious that the Jen Synth battle overwrites the same addresses in the save map used for Ultimate's HP (and Pandora's Box, seeing as P Box uses the fourth unused byte for U Weapon's HP). I'll look more into 005B - 005E when I get to Biz Seph, as I think that's what they are controlling. Obv the developers didn't account for the Yuffie warping glitch, so overwriting the UWeapon and PBox vars makes sense, as they won't be needed again for anything else.

I wonder what would happen if you Yuffie warped from the Jen fight to any point after the first UWeapon encounter, but before defeating it properly? My guess is that that the vars would be set to 0, so when UW spawns in at Junon it'll have 0 HP; one hit would trigger the death counter to set its HP to 20,000 and fly to Cosmo.

Also, what's the difference between 2008 and 2150? They both seem to have the same function (index of the last action performed)

It's peculiar that Helletic Hojo opts to uses 402D to lift the Death Status of the Right Arm..

I see; it's because it has to use "Right Arm Revive" on itself as an animation; it does not target the Right Arm.

If the script is setting the 4000 (death status) of the Right Arm to 0, why is it necessary to also toggle the 402D flag? Is it necessary? The Nibel Wolf do not need to use this flag.

I'm going to assume that any ability that removes the Death Status also toggles the 402D flag in the background. I know that 4000 is used for the 'Death' checks, but what does 402D actually do? When Carry Armor imprisons you, it also flags you as dead for the subsequent checks, but, the character's HP does not drop to 0, and, it will not show in red. Is this due to the fact that 402D isn't being toggled? If you try to use a battle item such as a Megalixir, the imprisoned character's HP *will* show in red.

4000 = death flag for AI Script checks?
402D = red hp, non-targetable, battle ends if all three 402D flags toggled?

Just guessing here; I'm curious to know what's going on with 402D. So far, only the Pyramid and Waterpolo have made use of 402D, so I haven't looked too deeply into it till now.

In fact, while on the subject of Hojo, I'd like to raise the question of the test formations soft locking for instances where the "Next Battle" flags are used. Instead of spawning in the subsequent test formation, the game will freeze, I've always been curious as to why this is.

Looking at Lifeform Hojo, I can see that three will spawn in, two being invisible and non targetable. The AI script for Lifeform even goes out of its way to ensure that these enemies have 0 HP, and are flagged as dead. TF has documented that the reason for this is to fill the two slots left over from the Right Arm and Left Arm, to stop the game from trying to access values from the left over templates, which makes sense.

Would this be the reason the test enemy formations crash when trying to make use of the Next Battles; because the enemy slots that contained enemy details are not being set to 0, so the game tries to load enemies that are not part of the new formation being loaded? Obv Heli/Hundred uses one enemy in each battle, so the problem will not occur there.

Even more things to consider if/when I ever start working on a mod...

Oooh, just spotted a flaw in the Right Arm's script that needs raising. It tries to use an attack that is not assigned to it's Attack list; it tries to use the 11F no-named attack instead of the 120 no-named attack that is assigned to it. Doesn't this create a bug of sorts? I recall another instance where an enemy tries  to use an attack it doesn't have, was it the Admanataimai? I think it is...... why doesn't the Right Arm fall victim to a similar bug? Is it due to the fact that the action 11F is loaded into the scene?

Nuts, I've just spent the last hour scratching my head as to why Helletic will never set its anim ID to 14 - it's because I'd copied the same script for the Right Arm onto the file I'm working on for the Left Arm LOL, no wonder things weren't making sense.

21A0 "During Emerald Weapon battle, keeps track of how many eyes are active. (Possible use in other battles, too)"

It's also used by the Manhole to identify which Manhole is currently active. I can't think of a global name for 21A0, so I've just called it "ManholePosition" for the MH and "EyesAlive" for EW.

-edit- it's also used by the final Turks Battle to indicate that the Battle has ended once one of the Turks has been killed

Any notion as to why Diamond Weapon is trying to "RunScript(15)", when there is no script for Custom Event 8? I wonder what the intention was there...

OK, after staring at Ultimate Weapon for hours, I now know precisely what's going on. The A0 opcode was throwing me off for a bit, but I figured it all out in the end (without having to ask for help lol). It's interesting to note that a small bug occurs once its HP has dropped to less than 65,536; it won't store the lower byte's value and will undercut the stored HP by up to 255.

Anyway, I've observed that the 0x004 flag in 0x0C1F of the save map is not a flag indicating that Ultimate has been killed; it's a flag that signifies that its HP has reached 'critical' and is ready to move onto the Cosmo Canyon phase. 0x001 is used to indicate that it has been killed, which is also used by the Battle Square, but technically 0x001 should be "Ultimate killed", and 0x004 should be "Ultimate HP Critical" or something to that effect.

edit I didn't realise how easy it was to make an account and edit the wiki (at I'm gonna start updating the save map as and when.

double edit - there is no glitch with Ultimate Weapon; I had the value stored as 2 bytes, not 3 (dur). Cheat Engine doesn't allow for three bytes, just 2 or 4, which means if I set it to 4 bytes, the value overspills into the next byte. I've had to separate out its HP into three separate bytes, which isn't too hard to manage: (Byte3 * 65,536) + (Byte2 * 256) + (Byte1).

^^ Awesomness dude, that one was bugging me for a while. It did inspire me to work with Cheat Engine a bit more closely. I've mapped out all of the six enemy slots LocalVar addresses, which helps to see what is going on in real-time. I've also found the address that deals with the next Formation ID, so I can do tests on any formation I want without having to load save files or mess around with MR lol.

OK, after testing it seems that 4300 is used when a playable character is imprisoned within Carry Armor's Arms, and is used to damage the imprisoned actor, amongst other things. I'll look into it more thoroughly when I actually get to Carr Armor.

For now though, I've spent quite a lot of time with Cheat Engine, and 2040 never seems to be any value other than 0. I think I was correct in my original assumption that this will reset the var to 0, as that's exactly what it seems to be doing.

-edit- The more I look at it, the more I'm sure that 2040 is used to clear the last attacker that is set as the SOLDIER:2nd's target. The same thing is used for the Elfadunk.

As for 2040. The only enemies that use it are Bottomswell, Carry Armor/Left Arm/Right Arm, Elfadunk, Roulette Cannon, SOLDIER:2nd, Turks:Rude. Roulette Cannon and SOLDIER:2nd can appear in the same formation so they might be able to shed some light as to what the intended function is.

The script with the Roulette Cannon is basically a copy and paste of part of Bottomswell's script. It makes sure that it will only use the attack if two or more players are alive; if only one player is alive, it will not use the attack, and target selected will be 2040.

It looks like it's just a coincidence that the Soldier:2nd and roulette cannon appear together and both use 2040. Until now I've been able to dismiss the var, as it doesn't seem to be doing much. With the Soldier:2nd, however, there's quite a lot going on with 2040. I kind of need to know what's going on with it before I can move on....

Just decided to have a quick look at Carry Armor. Any idea what 4300 is doing?

2090. There's another new one that I don't know what it's doing

@Sithlord if you've had a chance to explore my Enemy Database & Calculator, you'll find screenshots in the "Pics" version of each world map jump point, which could help as a visual aid

As DLPB said, really cool  8)

I'm a little bit confused what this script is doing with the Jumping:

Code: [Select]
0x008: PSHA (20A0) Type (02)
0x00B: PSHA (4000) Type (00)
0x00E: MASK
0x00F: PUSH (01) Type (01)
0x011: EQU
0x012: CNTB
0x013: PUSH (01) Type (01)

0x008 If (BitCount( (BattleAddr(&20A0).BattleAddr(&4000) == 1) ) == 1)

It seems to be checking to see if exactly one player has Death, but after testing this check didn't seem to do anything; the Jumping appeared to have a 1/2 chance of using Club Sword regardless of how many players were dead (it's supposed to have a 1/4 chance of using the attack if the check passes).

TF seemed to think this check will always fail, aswell

Thanks for clearing that up :) I suspected as much, I just needed to be sure

Pages: [1] 2 3 4 5 6 ... 10