< Back to home page

The fix

Download the modified main.scm file and copy it to game folder -> data -> script, replacing the original.

Technical description of modifications below.

Burning Desire

Too complicated, see below for a better solution. This section is kept only for historical reasons.

This is the code fragment that handles the last part of the mission, as decompiled by Sanny Builder:

:Label0AAD98 00D6: if 0039: 35@ == 6 004D: jump_if_false @Label0AADD4 00D6: if 00DF: actor 95@ driving 004D: jump_if_false @Label0AADCD 0633: AS_actor 95@ exit_car 000A: 35@ += 1 0002: jump @Label0AADD4 :Label0AADCD 0006: 35@ = 8 :Label0AADD4 00D6: if 0039: 35@ == 7 004D: jump_if_false @Label0AAE0A 062E: get_actor 95@ task 1587 status_store_to 40@ // ret 7 if not found 00D6: if 04A4: 40@ == 7 // == constant 004D: jump_if_false @Label0AAE0A 000A: 35@ += 1 :Label0AAE0A 00D6: if 0039: 35@ == 8 004D: jump_if_false @Label0AAE53 05D3: AS_actor 95@ goto_point 2402.052 -1719.716 12.6181 mode 6 time -2 ms // versionA 00D6: if 80DF: not actor $PLAYER_ACTOR driving 004D: jump_if_false @Label0AAE4C 0639: AS_actor $PLAYER_ACTOR rotate_to_actor 95@ :Label0AAE4C 000A: 35@ += 1 :Label0AAE53 00D6: if 0039: 35@ == 9 004D: jump_if_false @Label0AAF48 062E: get_actor 95@ task 1491 status_store_to 40@ // ret 7 if not found 00D6: if 04A4: 40@ == 7 // == constant 004D: jump_if_false @Label0AAF48 00A0: store_actor $PLAYER_ACTOR position_to 282@ 283@ 284@ 0087: 290@ = 282@ // (float) 0087: 292@ = 283@ // (float) 00A0: store_actor 95@ position_to 282@ 283@ 284@ 0087: 289@ = 282@ // (float) 0087: 291@ = 283@ // (float) 0087: 282@ = 289@ // (float) 0063: 282@ -= 290@ // (float) 0087: 283@ = 291@ // (float) 0063: 283@ -= 292@ // (float) 0604: get_Z_angle_for_point 282@ 283@ store_to 285@ 0804: AS_actor 95@ walk_to 2402.052 -1719.716 12.6181 angle 285@ radius 0.2 animation "BD_GF_WAVE" IFP_file "BD_FIRE" 4.0 LA 0 LX 0 LY 0 LF 0 LT -1 00D6: if 80DF: not actor $PLAYER_ACTOR driving 004D: jump_if_false @Label0AAF41 0639: AS_actor $PLAYER_ACTOR rotate_to_actor 95@ :Label0AAF41 000A: 35@ += 1 :Label0AAF48 00D6: if 0039: 35@ == 10 004D: jump_if_false @Label0AAF88 0006: 50@ = 18 0050: gosub @Label0AF7DD 00D6: if 0039: 49@ == 18 004D: jump_if_false @Label0AAF88 0050: gosub @Label0AF87F 000A: 35@ += 1 :Label0AAF88 00D6: if 0039: 35@ == 11 004D: jump_if_false @Label0AAFFE 00D6: if 0611: actor 95@ performing_animation "BD_GF_WAVE" 004D: jump_if_false @Label0AAFFE 0613: 295@ = actor 95@ animation "BD_GF_WAVE" time 00D6: if 0043: 295@ == 1.0 004D: jump_if_false @Label0AAFFE 05D3: AS_actor 95@ goto_point 2401.857 -1717.01 12.6334 mode 6 time -2 ms // versionA 000A: 35@ += 1 :Label0AAFFE 00D6: if 0039: 35@ == 12 004D: jump_if_false @Label0AB048 062E: get_actor 95@ task 1491 status_store_to 40@ // ret 7 if not found 00D6: if 04A4: 40@ == 7 // == constant 004D: jump_if_false @Label0AB048 009B: destroy_actor 95@ 02A3: enable_widescreen 0 0373: set_camera_directly_behind_player 02EB: restore_camera_with_jumpcut 0A09: set_actor $PLAYER_ACTOR muted 0 // versionB 000A: 35@ += 1

Variable 35@ keeps track of the progress. Actor 95@ is Denise.

Step 6 makes her get out of the car if she's inside. Step 7 waits until she gets out. I think we can leave it as is, getting out of the car should not be a problem.

Step 8 tells her to go towards her house. We can change it to teleport her instead.

Unfortunately, I couldn't change the code in Sanny Builder and compile it back, because it fails to compile the code it decompiled. I could fix the code to make it compile, but then I wouldn't get the original code back. It could introduce bugs and save file incompatibilities in unrelated missions. Thus, for safety, I decided to patch main.scm file manually.

The line 05D3: AS_actor 95@ goto_point 2402.052 -1719.716 12.6181 mode 6 time -2 ms is at offset 0xAAE1C in main.scm. The original code looks like this:

AAE1C: D3 05 03 5F 00 06 D6 20 16 45 06 E6 F6 D6 C4 06 BD E3 49 41 04 06 04 FE

We can change the opcode to 0xA1 (set_char_coordinates), but its argument list is shorter, so we have to fill the last 4 bytes with 2 NOPs (00 00):

AAE1C: A1 00 03 5F 00 06 D6 20 16 45 06 E6 F6 D6 C4 06 BD E3 49 41 00 00 00 00

Step 9 checks if the task is running. Since we replaced the task with the teleport, we have to patch this check. The line that gets the task status is at offset 0xAAE65 and looks like this:

AAE65: 2E 06 03 5F 00 05 D3 05 03 28 00

Instead of getting the task status and storing to variable 40@ (0x28), we can set the variable to the expected value directly:

AAE65: 39 00 03 28 00 04 07 00 00 00 00

Next few lines after the test calculate vector from her to CJ, then tell her to go to the same spot we teleported her earlier, turn to CJ and play a wave animation.

Step 10 calls a completely different part of the code far away, which I think handles her dialogue. The code is very convoluted and seems to be required for the mission to progress. It also seems to need the task from previous step running, probably to monitor its progress to know when she should start talking.

Step 11 waits for her to stop waving. We can patch it out to skip this part. I just replaced the jump with NOPs. Since we have 7 bytes to replace and a NOP is 2 bytes, we can use "wait 0" as a 5-byte NOP equivalent:

AAFD8: 4D 00 01 0A C7 FF FF change to: 00 00 01 00 05 00 00

Step 11 also starts a new task telling Denise to go to the door. We can replace it with a teleport the same way as in step 8:

AAFDF: D3 05 03 5F 00 06 B8 1D 16 45 06 55 A0 D6 C4 06 68 22 4A 41 04 06 04 FE change to: A1 00 03 5F 00 06 B8 1D 16 45 06 55 A0 D6 C4 06 68 22 4A 41 00 00 00 00

The last thing to do is to patch the completion test for previous task, the same way as in step 9:

AB010: 2E 06 03 5F 00 05 D3 05 03 28 00 change to: 39 00 03 28 00 04 07 00 00 00 00

555 We Tip

The problem with "555 We Tip" is that actors start shooting each other at the last cutscene, and if any of them dies and can no longer perform its role, the cutscene doesn't finish and the game soft locks.

How can we make them stop fighting? What's the difference to other missions in which actors do not shoot each other?

When we look at other missions, we can see that actors are spawned as "MissionX" or "Special" ped types. On 555 however, they are spawned as a standard male civilian, and with riot cheats on civilians hate each other.

Lets fix it. This is the relevant code fragment:

0129: 121@ = create_actor_pedtype 4 model #SFPD1 in_car 115@ driverseat 0129: 122@ = create_actor_pedtype 4 model #SFPD1 in_car 116@ driverseat 01B2: give_actor 121@ weapon 22 ammo 99999 // Load the weapon model before using this 01B2: give_actor 122@ weapon 22 ammo 99999 // Load the weapon model before using this 009A: 37@ = create_actor_pedtype 4 model #SWMYRI at -1763.276 946.1676 23.8905

The first line is at offset 0x159953. Lets change ped type 4 to something else. 31 (0x1F) seems like a good bet:

159953: 29 01 03 73 00 04 04 05 19 01 03 79 00 change to: 29 01 03 73 00 04 1F 05 19 01 03 79 00

Next line:

159960: 29 01 03 74 00 04 04 05 19 01 03 7A 00 change to: 29 01 03 74 00 04 1F 05 19 01 03 7A 00

And the DA (the last line):

159985: 9A 00 04 04 05 F0 00 06 D3 68 DC C4 06 BA 8A 6C 44 06 BE 1F BF 41 03 25 00 change to: 9A 00 04 1F 05 F0 00 06 D3 68 DC C4 06 BA 8A 6C 44 06 BE 1F BF 41 03 25 00

Save file for testing

Burning Desire revised

We can use the same method as in 555 to fix Burning Desire. The fix is much simpler and less intrusive.

This is the relevant code fragment:

0007: 282@ = 2345.907 0007: 283@ = -1171.659 0007: 284@ = 30.9688 0007: 285@ = 359.0737 009A: 95@ = create_actor_pedtype 5 model #GANGRL3 at 282@ 283@ 284@

ADE84: 9A 00 04 05 05 C3 00 03 1A 01 03 1B 01 03 1C 01 03 5F 00 change to: 9A 00 04 1F 05 C3 00 03 1A 01 03 1B 01 03 1C 01 03 5F 00

Save file for testing

Madd Dogg

Madd Dogg is also easy to fix:

0395: clear_area 1 at 2161.34 1442.504 9.8203 radius 20.0 0395: clear_area 1 at 2107.19 1409.153 9.8203 radius 10.0 009A: 95@ = create_actor_pedtype 4 model #SPECIAL01 at 2162.62 1451.475 23.1719 0245: set_actor 95@ walk_style_to "DRUNKMAN"

229063: 9A 00 04 04 05 22 01 06 EC 29 07 45 06 31 6F B5 44 06 0D 60 B9 41 03 5F 00 change to: 9A 00 04 1F 05 22 01 06 EC 29 07 45 06 31 6F B5 44 06 0D 60 B9 41 03 5F 00

Save file for testing

Summary of changes

OffsetValueChange to
712328 (0x000ade88)5 (0x05)31 (0x1f)
1415514 (0x0015995a)4 (0x04)31 (0x1f)
1415527 (0x00159967)4 (0x04)31 (0x1f)
1415561 (0x00159989)4 (0x04)31 (0x1f)
2265191 (0x00229067)4 (0x04)31 (0x1f)

All the offsets are for main.scm from version 1.0 (Steam version downgraded). Checksums of the original:

SHA-256601def3baae766ce6a23e2f0b9b48f6b33c9a64e2fc32eb4f22ddea8b868b0fa
SHA-1abeeba49669359c57b7ef2888c7263117f488cea
MD560ad23e272c3b0aa937053fe3006be93

After patching:

SHA-2560dddd01324036599da1eb301cbe8979718dbb1698b52461733ca10f44753977a
SHA-1b022f8750add95ca7a0820deb41544ef2b7b005f
MD5286a07d0a4aba93d6331826f3edcdfcc

main.scm patch in xdelta format.