|
 |
|
|
|
|
|
GTA Modification Forums
DARKPACT level III San Andreas SAMB weaknesses conquered
 |
|
 |
| |
Demarest  |
|
what could be

Group: BUSTED!
Joined: Jul 12, 2003

|
The original Darkpact SA thread was overrun with SAMB support questions. Bottom line: Do not use this technique unless both your Mission Builder and the code you're using it for WORK No download required, only original SA main.scm and Barton Waterduck's Mission Builder 0.33 for SA Craig version. For those familiar with Darkpact level 2 or 3 for VC, this process is even easier! For those not, this will allow your mod to be injected into an existing SCM without having to restart. The resultant SCM will be fully operational even during the starting of a new game. Can be used on original code or code already Darkpacted.
SA's thread execution is a bit more messy than in previous games. Furthermore there are NO threads that loop in bounds of Y_Less's VMA's FFFF limitation. So we're going to have to modify the MAIN thread. Since this thread is already running before during and after Mission 2 (which is Darkpact level III's home in SA as opposed to Mission 1 in VC), we'll need to include a check that will prevent it from trying to start the mission in the event that the user is starting a new game. We do this by putting a flag check in front of the start_mission command. Anyways, in original code, search for :MAIN_392. We're going to add 4 lines after the if there and comment out the next 4 lines (coincidence only) like so| QUOTE | 0038: $24 == 1 ;; integer values 004D: jump_if_false ��MAIN_392 0417: start_mission 2 ; Originally: 0002: jump ��MAIN_392 |
| before | after |
|---|
 |  |
Next, we have to add some code to Mission 2. Mission 2's pass flag is $24. So we check to see if that's NOT 0. If false, it jumps ahead and runs the game's original Mission 2. However, if it's not 0, then our Darkpact code will run. The beginning of the code incorporates Y_Less's VMA (variable memory access) and self-modifying code techniques so that the changes we made to the MAIN thread are restored to their original value. This is important both for game functionality as well as stopping it from launching Mission 2 repeatedly. Then the code will detect which mods (if any) are injected and inject the rest of them. After name thread, add your code like so. In the event of multiple (or additional) mods, make sure ALL create_threads are here and that the $120 equals line indicates the number of create_threads present.| QUOTE | 00D6: if 0 8038: NOT $24 == 0 004D: jump_if_false �NEWGAMECONTINUE 008B: @0 = $59 0004: $59 = 8650752 0004: $60 = 48929538 0004: $61 = 5329828 0006: @1 = 236 0004: $5353 = 134349398 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 16796928 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 61784 0050: gosub @1 0008: $60 += 1024 0004: $5353 = -1409153154 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 84300288 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 1677852853 0050: gosub @1 008A: $59 = @0 008B: @0 = $120 0012: @0 *= -8 000A: @0 += �DARKPACTOR 0050: gosub @0 004E: end_thread
:DARKPACTOR 004F: create_thread ��DARKPACTLEVEL3MOD1 0004: $120 = 1 0051: return
:NEWGAMECONTINUE |
| Darkpacting original code | Darkpacting Darkpacted code OR multiple mods |
|---|
 |  |
The last necessary step is actually adding our mods. They go right before Mission 0 an MUST be in the same order as your create_threads like so.
| Darkpacting original code | Darkpacting Darkpacted code OR multiple mods |
|---|
 |  |
This last part is optional, but recommended as it overcomes Mission 2's way of not ending right away (and therefore your mods will not necessarily auto-start right away). Search for :INTRO_924 and move the jump at the end of that block to the start of that block like so.| before | after |
|---|
 |  |
Minor testing has been done. If you find any bugs, let me know. Bit tired now, so forgive me if I've left anything out. Feel free to ask
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
Demarest  |
Posted: Saturday, Oct 1 2005, 11:38
|
what could be

Group: BUSTED!
Joined: Jul 12, 2003

|
| QUOTE (Whacko @ Oct 1 2005, 04:56) | | Would it be possible for you to host a prepared main.scm for download, please? | I'm assuming you mean TXT file as the SCM is going to be different for everybody based on the mods you're trying to inject. Hosting a TXT would be redundant because it would be the same as it is here. However, I suppose it's possible that while writing this, I skipped a step on accident At any rate, I'm assuming that you've been able to add it to SCM before and it works, is that correct? Otherwise, it could be an error with the mod. And I'm assuming that the SCM that you made these saves with was original code, correct??
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
Whacko  |
Posted: Saturday, Oct 1 2005, 11:54
|
Crackhead

Group: Members
Joined: Sep 20, 2004

|
Yes, I just took a original SCM and compiled it to a text file which I was darkpacting with. No mods. I just retried with Level 3 what already was working with Level 2, that`s causing my confusion. The only difference is that is was creating the "template" for my work myself instead of taking an existing one like I did on Level 2 with the Storemod-Darkpact file. So it`s realtivly clear someting must be wrong with mine, but I can´t find the mistake. I was following the readme above step by step, found anything that has to be edited right away and had no problems... well, untill I tried to load a savegame, hehe. Ah, forgot about this: I compiled my template without having own code added. Meaning only with the modifications for darkpact and it won`t load, too. Erm, and yes. I meant a txt, not a scm file.  YetAnotherEdit: Oki, ich did it once more step by step and comparing to the Level 2 Code the DARKPACTER part is missing in Level 3. I still didn`t get how DP exactely works, but I guess here`s the problem. I tried to put in that part from Level 2 but the game`s still crashing on loading a savegame. Please don`t feel badgered by my edits, just notes. This post has been edited by Whacko on Saturday, Oct 1 2005, 15:34
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
Whacko  |
|
Crackhead

Group: Members
Joined: Sep 20, 2004

|
Oh, right. I`m sorry - it was Level 1, my bad (had the latest release in mind and as it`s acutally 3 I always think of 2). I`ve been trying a lot yestersday and didn`t note all of it here, so it might be confusing (even more when I do mistakes like Level 2 and 1 and so  ). First I took a original SCM, decompiled it with the Builder version above to main_wh.txt and followed the steps as postet. To have no blank thread I just created a marker sphere next to my save point. With Level 3 no game would load up - I didn`t try a new game, `cause this isn`t what I want to mod. And I placed the marker inside the Madd Dogg Mansion so I won`t have access to check it anway. I tried this a few times with minor changes I didn`t write down completely - no progress. Second I saw that the save code from DARKPACTER was missing and I tried to "convert" Level 1 code into Level 3. I pasted what`s on Mission 1 and 0 in Level 1 into Mission 2 (Storemod.txt) and 0 in Level 3 (original main.txt) and added the steps above. A couple of tries - no success. Third, to make sure I don`t have anything in my additional little script crashing the game, I put it in Level 1 and anything worked fine. Only the thread handling in Level 1 is still kind of mystery to me. So it wasn´t possibe for me to a) create the sphere and b) give out a text-box when the player is inside it, but that has nothing to do with DP in any matter - my personal lack of coding knowledge... can be fixed.
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
Whacko  |
|
Crackhead

Group: Members
Joined: Sep 20, 2004

|
Gnaa... don´t ask me why, but now it works.  First thing totally confusing me was the missing save-code. I didn`t realize that it`s not longer needed, well, it seems so, `cause the sphere appeared instantly after loading a "original" save game. This is what I want to add, but doesn`t work right in DP: | CODE | :DARKPACTLEVEL3MOD1 ; --- MODSTART 03BC: @902 = create_sphere 1253.2223 -779.2285 91.0302 1.5
0001: wait 2500 ms 00D6: if 0 0102: actor $PLAYER_ACTOR stopped_near_point_on_foot 1253.2223 -779.2285 91.0302 radius 2.0 2.0 3.0 sphere 1 004D: jump_if_false ££MAIN_414
:WTRASH 03E5: text_box 'WTRASH' 0470: @10 = actor $PLAYER_ACTOR armed_weapon unknown 0001: wait 2500 ms 00D6: if 0 00E1: key pressed 0 15 004D: jump_if_false ££MAIN_414 0555: remove_weapon @10 from_actor $PLAYER_ACTOR 0002: jump ££MAIN_414 ; --- MODEND |
I wrote that code in a stripped main.txt at the bottom of the Main part and it worked fine. In DP nothing happens standing in the sphere. I choose "MAIN_414" to loop it all what might not be ok, but I didn`t find another mark fitting better as kind of return target. Any hint`s how I can improve that - or even get it running?  I know it`s perhaps a bit too general for this thread, but it works without DP, so I guess there are spezifications I didin`t figure out yet. This post has been edited by Whacko on Sunday, Oct 2 2005, 14:09
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
pdescobar  |
|
Conformist Scum Panda

Group: Members
Joined: Jul 19, 2005


|
Yeah, I know this is a pretty large bump, but Darkpact is still an incredibly useful way to use script mods and I am continually amazed by the fact that it works at all; the ease of implementation of level 3 darkpacting is just the icing on the cake. So I don't mind bringing it back up.  Anyhow, if anyone would like to use this method on the SA version 2 scripts so that their mods can be injected into version 2 savegames, there are just a few small changes which need to be made. For consistency with Dem's v1 instructions in the first post, I'll assume SA Mission Builder 0.33 for these instructions, although the process can be done in Sanny Builder too without much difficulty. First of all, you obviously start out with the original v2 scripts rather than the original v1 scripts. Since the MAIN portion of v2 is slightly smaller, some of the labels you are working with are different. Thus the first change occurs a little after the label MAIN_388 rather than MAIN_392. You will want to adjust the two jumps to reflect this label as well so the 4 added lines of code become: | QUOTE | 0038: $24 == 1 ;; integer values 004D: jump_if_false ££MAIN_388 0417: start_mission 2 ; Originally: 0002: jump ££MAIN_388 |
The other change which must be made is in the VMA/self-modifying-code section at the start of mission 2. In this case, two of the VMA variables need to be adjusted to reflect the fact that the code change occurs 21 bytes sooner than in v1. So the initial assignment of $60 changes from 48929538 to 48924162 and the third assignment of $5353 changes from 61784 to 61763. The added code thus becomes the following: | QUOTE | 00D6: if 0 8038: NOT $24 == 0 004D: jump_if_false £NEWGAMECONTINUE 008B: @0 = $59 0004: $59 = 8650752 0004: $60 = 48924162 0004: $61 = 5329828 0006: @1 = 236 0004: $5353 = 134349398 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 16796928 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 61763 0050: gosub @1 0008: $60 += 1024 0004: $5353 = -1409153154 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 84300288 0050: gosub @1 0008: $60 += 1024 0004: $5353 = 1677852853 0050: gosub @1 008A: $59 = @0 008B: @0 = $120 0012: @0 *= -8 000A: @0 += £DARKPACTOR 0050: gosub @0 004E: end_thread
:DARKPACTOR 004F: create_thread ££DARKPACTLEVEL3MOD1 0004: $120 = 1 0051: return
:NEWGAMECONTINUE |
And that's it. Following Dem's first post instructions, with the above few changes, will allow you to create a Darkpacted version of your mod which can be injected into version 2 saves. By keeping a Darkpact template for each SA version, you can simply copy & paste your script mods into each template and get both SA-v1-save-compatible and SA-v2-save-compatible versions of your mod.
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
pdescobar  |
Posted: Saturday, Sep 23 2006, 05:15
|
Conformist Scum Panda

Group: Members
Joined: Jul 19, 2005


|
So here I am following up a technical post that makes it sounds like I know what I'm talking about with newbie questions.  What is the best procedure for making darkpacted one-time adjustments? For example, say you wanted to add some vehicle spawns and inject them into a save. The last time I did this, I took what I'm pretty sure is a poor approach and created a thread which did everything I needed and then ended itself. While it did inject my changes and preserve save compatibility with the unmodified scripts, there's not a whole lot of room in MAIN and there was an oddity. In order to inject another mod later on in any of the saves following that, I had to go back to my original darkpact script and add the new mod as another thread after the first one. I see that mentioned in the instructions but didn't realize it applied if the first darkpacted thread was no longer actually running... So, should one-time changes simply be added inside Mission 2? If so, should they go between the last gosub and the end thread, or between the $120 assignment and the return of the DARKPACTOR subroutine, or somewhere else?
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
Demarest  |
|
what could be

Group: BUSTED!
Joined: Jul 12, 2003

|
If anybody thought that was a newbie question, they'd be revealing that they themselves are a newbie and inexperienced enough to not realize how advanced a question that really is.
AS DOCUMENTED, there is no answer. See, Darkpact, Y_Less's VMA, CyQ's arrays... these things are advanced techniques. Worse than that, they're advanced techniques being applied to the most fragile of procedures. Scary stuff to somebody who doesn't grasp it. It is unfortunate, but this procedure was a major breakthrough that I feel deserves to be in the hands of anybody who wishes for it. So the documentation was meant to be as idiotproof as possible. Which implies that somebody that doesn't get it is an idiot, which couldn't be further from the truth for the reasons stated above. Just a testament to how simplistic we tried to make the documentation. At the time, it was done that way under the assumption that the breakthrough would provoke rabid implimentation. Users wanting to combine this and that, etc. So we tried to keep it simple AND scalable. However, scalable doesn't much provide for create_threads that pass parameters, one time injections outside MAIN, etc If you look at the source for Pillager, it's in fact a piggy back mission; no permanent or one-time effects at all.
The answer is one that might fly over the heads of others, but I'm sure YOU will grasp just fine It requires you to first get rid of the 2nd setting of @0 and subsequent subroutine and of course would require anybody taking your code and adding to it to be given special instructions as to how to scale it. Perhaps this is a good reason for the approach of Level III to change to a less easier to understand, but more versatile approach. It would look something like this:
| CODE | :label if NOT $120 > 0 jf label2 ;first injection here. could be a create_thread, could be one time, etc
:label if NOT $120 > 1 jf label3 ;2nd injection
;repeat above as needed
:labelY $120 = X;X = number of injected sections (last value of NOT $120 > plus one) |
That's what I would do. Though I must confess that Mr. Cole is the main brains. That is to say the guy that usually takes our own mental prisons and somehow thinks beyond them. He might have a more efficient, easier to document, whatever solution.
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
pdescobar  |
|
Conformist Scum Panda

Group: Members
Joined: Jul 19, 2005


|
I finally got around to playing with this again.  There's an error in Y-Less' Sanny-specific v2 code, corrected below in yellow highlighting. One of the internal labels in the hex section wasn't adjusted. | QUOTE (Y-Less) | hex 04 00 02 86 EA 01 56 02 02 08 04 00 02 8A EA 01 00 4D 00 01 04 00 02 8E EA 01 43 F1 00 00 04 00 02 92 EA 01 7E 07 02 AC 04 00 02 96 EA 01 00 52 06 05 04 00 02 9A EA 01 B5 00 02 64 end |
To make YLess' suggestion for adding a second mod work, you just need to comment out (or rename) the previous definition of the label. Here's a simple (Sanny) example I used for testing. First modification: | QUOTE | //Initial Darkpact code above... 00D6: if 0 0038: $120 == 0 004D: jf $120
// code you only want to execute once goes here // this includes create_threads
004F: create_thread @DARKPACTLEVEL3MOD1
:DARKPACTOR_EVERY_TIME // Code you want to execute every time goes here 00BB: text_lowpriority 'CRED609' 5000 ms 1 // Test Team
:DARKPACTOR_END //Final Darkpact code below... |
Second modification with code commented out in orange and code added in yellow| QUOTE | //Initial Darkpact code above... 00D6: if 0 0038: $120 == 0 004D: jf $120
// code you only want to execute once goes here // this includes create_threads
004F: create_thread @DARKPACTLEVEL3MOD1
//:DARKPACTOR_EVERY_TIME 004F: create_thread @DARKPACTLEVEL3MOD2
:DARKPACTOR_EVERY_TIME // Code you want to execute every time goes here 00BB: text_lowpriority 'CRED609' 5000 ms 1 // Test Team
:DARKPACTOR_END //Final Darkpact code below... |
Initially, $120 points to the original DARKPACTOR_EVERY_TIME label. When this code is compiled, that label essentially moves but that doesn't change the value of $120 in the save. So when you load up the save, it jumps to the remembered position, executes the new create_thread command then continues on and updates $120 to the newly redifined location. The above code worked fine in brief testing. Going back to my previous question on making a completely-transparent one-time change, I understand Dem's answer as basically saying the thing to do is to avoid all the mucking about with $120 and just do what I need and get out. As an example, let's say I wanted to create an almost trivially simple darkpactor to cure the gym glitch (4 variable assignments) on a save from the unmodified game with the intent to have it continue to be useable on the unmodified game. In that case, using Y_Less' method, I would do the following. | CODE | //Initial Darkpact code above... //00D6: if 0 //0038: $120 == 0 //004D: jf $120
// Simple gym glitch fix $5345 = -1 $5346 = -1 $5347 = -1 $5348 = -1
:DARKPACTOR_END //0004: $120 = @DARKPACTOR_EVERY_TIME 004E: end_thread
:NEWGAMECONTINUE |
So there I just make my change and exit, leaving $120 alone. Is that correct? It seems to work in testing, but I want to make sure I'm not overlooking anything.
|
|
|
|
|
 |
|
 |
 |
|
 |
| |
0 User(s) are reading this topic (0 Guests and 0 Anonymous Users)
0 Members:
Pages:
(2) [1] 2
Track this topic
Receive email notification when a reply has been made to this topic and you are not active on the board.
Subscribe to this forum
Receive email notification when a new topic is posted in this forum and you are not active on the board.
Download / Print this Topic
Download this topic in different formats or view a printer friendly version.
| |
 |
|
 |
|
|
|
|