Has it really been over a week since I updated? I guess so. I've been taking Akari's suggestion and running with it. Trying to create something that most people could read. I've run into a problem, however.
Ignoring the fact that this is very hard work, let's also talk about erroneous scripts.
Cloud's Physical Counter and Sephiroth's Main scripts have several instances of two consecutive 72h commands. Only one of these will be called (the first one in each instance) and the second one is completely avoided. Why, then, is it there? Some weird deal with their compiler? Who knows.
Sephiroth's Init script is contradicting TFergusson's data. The script starts out:
Code: [Select]
and it does that three more times with other values in the 10h command. Fergusson states in his nots on command 80h:
Absolutely *NOTHING* happens (not even popping variables off) if 'y' is a '1x'-type Var.
y is either the first or second pop, he wasn't clear on that, but it's probably the first. However, if you notice the first two commands are to pop 1X-type variables to the stack so according to him this script shouldn't do anything . . . but it does.
This particular script, to me, translates as (in very simple terms):
Code: [Select]
Code:
Self.MainScriptOverride = TrueSelf.Flag(200) = True [&4029]Self.Flag(100) = True [&4028]Self.Flag(400) = True [&402A]
I'm not sure what these flags so...I guess I'm slightly stuck. I may just have to leave these in assembler (Which is easiest for me, but I know it's not good for everyone).
UPDATE: So who wants to see the decompiled Character AI Scripts? Yeah, I thought you did.
Cloud.PhysicalCounter:
Code: [Select]
Code:
LocalVar:0000 <- 255If (&BattleVar(Self).CharVar(Ally Covered) == 19){ LocalVar:0000 <- 80}ElseIf (&BattleVar(Self).CharVar(Ally Covered) == 18){ LocalVar:0000 <- 81}ElseIf (&BattleVar(Self).CharVar(Ally Covered) == 21){ LocalVar:0000 <- 82}ElseIf (&BattleVar(Self).CharVar(Ally Covered) == 17){ LocalVar:0000 <- 83}POP()If ( (&LocalVar:0000 != 255) ){ BattleVar(TempGlobal) <- &GlobalVar(0000) BattleVar(2018) <- &BattleVar(TempGlobal) BattleVar(TempGlobal) <- &BattleVar(TempGlobal) + 3 If ( (&BattleVar(TempGlobal) > 200) ) { BattleVar(TempGlobal) <- 200 } GlobalVar(0000) <- &BattleVar(TempGlobal)) Debug.Print: "LOVEPARA CHR:%d, %d->%d" ; &BattleVar(Self).CharVar(Ally Covered) - 16; &BattleVar(2018); &BattleVar(TempGlobal)}
Cloud.AllyDeath
Code: [Select]
Code:
LocalVar:0020 <- 0If ( (&LocalVar:0020 < 3) ){ BattleVar(Target) <- FlagBit(&LocalVar:0020) If (&BattleVar(Target).CharVar(Status)) { LocalVar:0000 <- 255 If (&BattleVar(Target).CharVar(Formation) == 19) { LocalVar:0000 <- 80 } ElseIf (&BattleVar(Target).CharVar(Formation) == 18) { LocalVar:0000 <- 81 } ElseIf (&BattleVar(Target).CharVar(Formation) == 21) { LocalVar:0000 <- 82 } ElseIf (&BattleVar(Target).CharVar(Formation) == 17) { LocalVar:0000 <- 83 } POP() If ( (&LocalVar:0000 != 255) ) { BattleVar(TempGlobal) <- &GlobalVar(0000) BattleVar(2018) <- &BattleVar(TempGlobal) BattleVar(TempGlobal) <- &BattleVar(TempGlobal) - 5 If ( (&BattleVar(TempGlobal) < 50) ) { BattleVar(TempGlobal) <- 50 } GlobalVar(0000) <- &BattleVar(TempGlobal)) Debug.Print: "LOVEPARA CHR:%d, %d->%d" ; &BattleVar(Target).CharVar(Formation) - 16; &BattleVar(2018); &BattleVar(TempGlobal)}LocalVar:0020 <- &LocalVar:0020 + 1GOTO: 0x0006}
Barret.Init
Code: [Select]
Code:
Link with scripts on character: 3
Tifa.Init
Code: [Select]
Code:
Link with scripts on character: 3
Aeris.GeneralCounter
Code: [Select]
Code:
If (&BattleVar(Self).CharVar(Formation) == 19){ LocalVar:0080 <- 80}ElseIf (&BattleVar(Self).CharVar(Formation) == 18){ LocalVar:0080 <- 81}ElseIf (&BattleVar(Self).CharVar(Formation) == 21){ LocalVar:0080 <- 82}ElseIf (&BattleVar(Self).CharVar(Formation) == 17){ LocalVar:0080 <- 83}POP()BattleVar(Target) <- &BattleVar(Self).CharVar(40D0)BattleVar(Target) <- (&BattleVar(Target).CharVar(Formation) == 16) If (&BattleVar(Target)){ LocalVar:0020 <- &BattleVar(Self).CharVar(4160) LocalVar:0060 <- 0 If ( (&LocalVar:0020 < &LocalVar:0000) ) { LocalVar:00A0 <- 0 LocalVar:0060 <- 2 } ElseIf (&LocalVar:00C0) { If (&LocalVar:0020) { LocalVar:00A0 <- 1 LocalVar:0060 <- 4 } } ElseIf ( (&LocalVar:0020 > &LocalVar:0000) ) { LocalVar:00A0 <- 1 LocalVar:0060 <- 2 } If (&LocalVar:0060) { BattleVar(TempGlobal) <- &GlobalVar(0080) BattleVar(2018) <- &BattleVar(TempGlobal) If ( (&LocalVar:00A0 == 1) ) { BattleVar(TempGlobal) <- &BattleVar(TempGlobal) + &LocalVar:0060 If ( (&BattleVar(TempGlobal) > 200) ) { BattleVar(TempGlobal) <- 200 } } Else { BattleVar(TempGlobal) <- &BattleVar(TempGlobal) - &LocalVar:0060 If ( (&BattleVar(TempGlobal) < 50) ) { BattleVar(TempGlobal) <- 50 } GlobalVar(0080) <- &BattleVar(TempGlobal)) Debug.Print: "LOVEPARA CHR:%d, %d->%d" ; &BattleVar(Self).CharVar(Formation) - 16; &BattleVar(2018); &BattleVar(TempGlobal)}
Aeris.DeathCounter
Code: [Select]
Code:
If (&BattleVar(Self).CharVar(Formation) == 19){ LocalVar:0080 <- 80}ElseIf (&BattleVar(Self).CharVar(Formation) == 18){ LocalVar:0080 <- 81}ElseIf (&BattleVar(Self).CharVar(Formation) == 21){ LocalVar:0080 <- 82}ElseIf (&BattleVar(Self).CharVar(Formation) == 17){ LocalVar:0080 <- 83}POP()BattleVar(Target) <- &BattleVar(Self).CharVar(40D0)BattleVar(Target) <- (&BattleVar(Target).CharVar(Formation) == 16) If (&BattleVar(Target)){ BattleVar(TempGlobal) <- &GlobalVar(0080) BattleVar(2018) <- &BattleVar(TempGlobal) BattleVar(TempGlobal) <- &BattleVar(TempGlobal) - 4 If ( (&BattleVar(TempGlobal) < 50) ) { BattleVar(TempGlobal) <- 50 } GlobalVar(0080) <- &BattleVar(TempGlobal)) Debug.Print: "LOVEPARA CHR:%d, %d->%d" ; &BattleVar(Self).CharVar(Formation) - 16; &BattleVar(2018); &BattleVar(TempGlobal)}
Aeris.PreTurn
Code: [Select]
Code:
LocalVar:0000 <- &BattleVar(Self).CharVar(4160)LocalVar:00C0 <- &BattleVar(Self).CharVar(Status)
Yuffie.Init
Code: [Select]
Code:
Link with scripts on character: 3
Vincent.Main
Code: [Select]
Code:
LocalVar:0000 <- 98 + &BattleVar(2038) * 2If ( (Random MOD 10 < 3) ){ LocalVar:0000 <- &LocalVar:0000 + 1}BattleVar(Target) <- &BattleVar(2040)Perform attack(&LocalVar:0000)
Sephiroth.Init
Code: [Select]
Code:
BattleVar(Self).CharVar(Flag(0:4)) <- 1BattleVar(Self).CharVar(Flag(1:1)) <- 1BattleVar(Self).CharVar(Flag(1:0)) <- 1BattleVar(Self).CharVar(Flag(1:2)) <- 1
Sephiroth.Main
Code: [Select]
Code:
LocalVar:0000 <- 2BattleVar(Target) <- (&BattleVar(Target).CharVar(ElemWeakness) >= 5) If (&BattleVar(Target)){ Debug.Print: "RESIST EARTH MONSTER" ; 0 LocalVar:0040 <- 1}BattleVar(Target) <- (&BattleVar(2050).CharVar(Formation) == 25) If ( ( (&BattleVar(Target) And (&BattleVar(Target).CharVar(Status) == 1) ) And (Random MOD 3 == 0) ) ){ LocalVar:0020 <- 8}ElseIf ( (BitCount(&BattleVar(Enemies)) == 1) ){ BattleVar(Target) <- RandomBit(&BattleVar(Enemies)) If ( (&BattleVar(Target).CharVar(4270) >= 16) ) { LocalVar:0020 <- 29 } Else { LocalVar:0000 <- 1 }}Else{ BattleVar(Target) <- &BattleVar(Enemies) If (Random MOD 3 + &LocalVar:0040 == 0) { LocalVar:0020 <- 38 LocalVar:0040 <- 1 } ElseIf (Random MOD 3 + &LocalVar:0040 == 1) { LocalVar:0020 <- 32 } Else { LocalVar:0020 <- 35 } Else { POP()}Perform attack(&LocalVar:0020)
This was JUST made from the WM 1.2.0 "Proving Grounds". This still isn't editable yet, but this is getting closer.
I realize this is a lot to go through just to read it all and it's probably pretty confusing. Let me point out a few details.
1. This is incomplete. There are still a lot of memory addresses that need to be accounted for. I haven't done them all, just most of the ones that show up in these scripts.
2. Look at Aeris's GeneralCounter. There's an ElseIF statement there near the middle that contains a nested IF statement. Normally this condition would just be ANDed to the ElseIf statement. This is not a mistake with my decompiler, this is the way it's written. Weird. It also needs two more close curly brackets. I'm not sure what to do about that...
3. Sephiroth's Main Script has two Elses at the end of it. This is a very strange (and unnecessary) code that makes disassembling weird. The code at script address 0xDD is "72 E000". For those keeping score, you can see why this is a completely unnecessary line. If 72h does mean go to address xxxx, then this line basically says "go to the next line". The way I keep track of Elses is by where these jump commands are. That POP() statement will just execute in that larger Else statement.
That's about all I have to report. It's taken me about 2 days (about 11 hours work) to get these results from what I had shown previously. I have no clue how to write an assembler for this so this maybe just a translator more than anything else. I will not likely write an assembler, but I might...given the proper incentive of course.
Non-WM-related update: Wondering why I haven't been doing anything WM related lately? I've been
fixing the PC MDef bug.
WM-related update: I hope people are still looking at this even though it's currently on the second page. I believe I have isolated the damage calculation function and where the 0002h flag is handled. Apparently it does something with the Affect MP.
Here's what it does if that 0002h flag is active (using modified addresses):
Code: [Select]
Code:
if (not (&(99E308+6Ch) and 200h) and _ ' Is flag active? not (&C3F37C and (1 << arg_4)) and _ ' Not sure what argument_4 is. Often passes not (&(99E308+228h) and 40000h) then ' Some flag it set? Never seen it pass. var_34 = 1else var_34 = 0end ifvar_14 = var_34
var_14 then goes on to be checked with the Affect MP flag.
Code: [Select]
Code:
if (var_14 = 0 and _ not (&(99E308+6Ch) and 100h) and _ 'Affect MP? not (&(99E308+228h) and 1) and _ 'This flag is not on not (&(99E308+230h) and C1h) then &(99E308+218h) = &(99E308+218h) or 1 'Turn this flag onend if
If var_14 is 1 it skips several steps afterwards as well.
I don't know what any of these addresses are or what data starts at 0x99E308. Looks like data specific to the current attack since +6Ch is the special flags and something close to +60h and +64 are Camera movements. Apparently that address gets written to address 0x99CE0C almost as soon as the game starts and gets referenced in 1210 places after that! If anyone can identify these addresses let me know. They're probably off from the original 1.02 by a bit.