Code Snippets
Re: Code Snippets
[mis]//Electro Punch
PLAYER_PED p1 = ( 149.0 , 195.0 , 255.0 ) 22 0
COUNTER loop = 1
COUNTER punched
CHAR_DATA special
LEVELSTART
DECLARE_POLICELEVEL ( 6 )
WHILE_EXEC ( loop = 1 )
IF ( HAS_CHAR_PUNCHED_SOMEONE ( p1 ) )
STORE_LAST_CHAR_PUNCHED ( p1 , punched )
SET special = ( punched + 8 )
// this electrocutes the punched player instead of making them invincible because it is 8 bytes higher than the command expected
SET_CHAR_INVINCIBLE ( special , ON )
ENDIF
ENDWHILE
LEVELEND
[/mis]
PLAYER_PED p1 = ( 149.0 , 195.0 , 255.0 ) 22 0
COUNTER loop = 1
COUNTER punched
CHAR_DATA special
LEVELSTART
DECLARE_POLICELEVEL ( 6 )
WHILE_EXEC ( loop = 1 )
IF ( HAS_CHAR_PUNCHED_SOMEONE ( p1 ) )
STORE_LAST_CHAR_PUNCHED ( p1 , punched )
SET special = ( punched + 8 )
// this electrocutes the punched player instead of making them invincible because it is 8 bytes higher than the command expected
SET_CHAR_INVINCIBLE ( special , ON )
ENDIF
ENDWHILE
LEVELEND
[/mis]
Re: Code Snippets
I don't understand how to use the snippets.
1. It will work in single player, or only in multiplayer ?
2. For one mission/map or for many ?
3. Booth players or more, must have the same snippet ?
4. The script (snippet) what name must have for .mis file ? Because how the game know how the file name lol.mis (an random name) will make the connection with the map game ?
1. It will work in single player, or only in multiplayer ?
2. For one mission/map or for many ?
3. Booth players or more, must have the same snippet ?
4. The script (snippet) what name must have for .mis file ? Because how the game know how the file name lol.mis (an random name) will make the connection with the map game ?
Create your basic script as a textfile using any text editor.
Give it a name such as "text.mis" - all raw scripts must have a .mis extension
Compile the mis file using the Miss2.exe compiler program.
This will generate a .tmp file, a .txt file & a .scr file of your raw script.
Once successfully compiled, copy the resulting .scr file into the …/gta2/data/ folder on your harddrive.
Code: Select all
http://projectcerbera.com/gta/2/tutorials/scripting
Re: Code Snippets
Both but they might need to be modified. It depends on the code.roarke wrote:I don't understand how to use the snippets.
1. It will work in single player, or only in multiplayer ?
Code needs to added to every SCR file that you want to use it in.roarke wrote: 2. For one mission/map or for many ?
Everyone needs the same files. MIS files are ignored by GTA2, it needs the compiled version with SCR extension.roarke wrote: 3. Both players or more, must have the same snippet ?
You can either edit gta2\data\test1.seq in notepad to point to the SCR file of your choice or the better way is to make an MMP file (this can support 1 to 6 players) and has to be launched from the GTA2 network create game screen.roarke wrote: 4. The script (snippet) what name must have for .mis file ? Because how the game know how the file name lol.mis (an random name) will make the connection with the map game ?
Re: Code Snippets
Thank you for the value of the reply.
Flashing Lights
For those detail lovers like me:
It´s a known bug that using flashing lights in your map causes desync.
So mappers could not use them in multiplayer maps.
Here´s how it works without getting out of sync:
We are using the script to create a light (must not be placed in the map file!) and simply change the intensity in a while loop.
This is a simple one using a straight / linear flashing:
[syntax=mis]COUNTER loop = 1 //number that runs the WhileLoop
COUNTER cyclecounter //every cycle +1, then set to zero when some favoured value is reached
LIGHT flashing_light = (100.5, 100.5, 2.02) 1.1 0 (255, 255, 111) 0 0 0
LEVELSTART
WHILE_EXEC ( loop = 1 )
IF (cyclecounter > 128)
SET cyclecounter = 1
ENDIF
//changing the intensity of the light
IF (cyclecounter > 0)
CHANGE_INTENSITY (flashing_light, 45) //intensity = 45 (glows a bit)
ENDIF
IF (cyclecounter > 64)
CHANGE_INTENSITY (flashing_light, 255) //intensity = 255 (full shining)
ENDIF
++cyclecounter
ENDWHILE //end of whileloop with value = 1
LEVELEND[/syntax]
This one is a little more complex, using different intensities and a "pseudo-random" flashing. Actually it´s a sequence.
[syntax=mis]COUNTER loop = 1 //number that runs the WhileLoop
COUNTER cyclecounter //every cycle +1, then set to zero when some favoured value is reached
LIGHT broken_light = (100.5, 100.5, 2.02) 1.1 0 (255, 255, 111) 0 0 0
LEVELSTART
WHILE_EXEC ( loop = 1 )
IF (cyclecounter > 2500)
SET cyclecounter = (cyclecounter - 2500)
ENDIF
//changing the intensity of the light
IF (cyclecounter > 480)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 481)
SET cyclecounter = (cyclecounter - 50)
ENDIF
IF (cyclecounter > 540)
CHANGE_INTENSITY (broken_light, 80)
ENDIF
IF (cyclecounter > 720)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 721)
SET cyclecounter = (cyclecounter - 200)
ENDIF
ENDIF
IF (cyclecounter > 1080)
CHANGE_INTENSITY (broken_light, 200)
ENDIF
IF (cyclecounter > 1500)
CHANGE_INTENSITY (broken_light, 0)
ENDIF
IF (cyclecounter > 1920)
CHANGE_INTENSITY (broken_light, 255)
ENDIF
IF (cyclecounter = 1923)
SET cyclecounter = (cyclecounter - 200)
ENDIF
IF (cyclecounter > 2200)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 2202)
SET cyclecounter = (cyclecounter + 200)
ENDIF
IF (cyclecounter = 2203)
SET cyclecounter = (cyclecounter + 200)
ENDIF
ENDIF
IF (cyclecounter > 2250)
CHANGE_INTENSITY (broken_light, 170)
ENDIF
IF (cyclecounter > 2280)
CHANGE_INTENSITY (broken_light, 0)
ENDIF
SET cyclecounter = (cyclecounter + 3)
ENDWHILE //end of whileloop with value = 1
LEVELEND[/syntax]
It´s probably better to use a randomization script you can find in this topic.
I am still wondering how to generate coincidences just by mathmatic operations.
Please tell me if something doesn´t work here. I modified it for the topic and did not test exactly THIS script.
It´s a known bug that using flashing lights in your map causes desync.
So mappers could not use them in multiplayer maps.
Here´s how it works without getting out of sync:
We are using the script to create a light (must not be placed in the map file!) and simply change the intensity in a while loop.
This is a simple one using a straight / linear flashing:
[syntax=mis]COUNTER loop = 1 //number that runs the WhileLoop
COUNTER cyclecounter //every cycle +1, then set to zero when some favoured value is reached
LIGHT flashing_light = (100.5, 100.5, 2.02) 1.1 0 (255, 255, 111) 0 0 0
LEVELSTART
WHILE_EXEC ( loop = 1 )
IF (cyclecounter > 128)
SET cyclecounter = 1
ENDIF
//changing the intensity of the light
IF (cyclecounter > 0)
CHANGE_INTENSITY (flashing_light, 45) //intensity = 45 (glows a bit)
ENDIF
IF (cyclecounter > 64)
CHANGE_INTENSITY (flashing_light, 255) //intensity = 255 (full shining)
ENDIF
++cyclecounter
ENDWHILE //end of whileloop with value = 1
LEVELEND[/syntax]
This one is a little more complex, using different intensities and a "pseudo-random" flashing. Actually it´s a sequence.
[syntax=mis]COUNTER loop = 1 //number that runs the WhileLoop
COUNTER cyclecounter //every cycle +1, then set to zero when some favoured value is reached
LIGHT broken_light = (100.5, 100.5, 2.02) 1.1 0 (255, 255, 111) 0 0 0
LEVELSTART
WHILE_EXEC ( loop = 1 )
IF (cyclecounter > 2500)
SET cyclecounter = (cyclecounter - 2500)
ENDIF
//changing the intensity of the light
IF (cyclecounter > 480)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 481)
SET cyclecounter = (cyclecounter - 50)
ENDIF
IF (cyclecounter > 540)
CHANGE_INTENSITY (broken_light, 80)
ENDIF
IF (cyclecounter > 720)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 721)
SET cyclecounter = (cyclecounter - 200)
ENDIF
ENDIF
IF (cyclecounter > 1080)
CHANGE_INTENSITY (broken_light, 200)
ENDIF
IF (cyclecounter > 1500)
CHANGE_INTENSITY (broken_light, 0)
ENDIF
IF (cyclecounter > 1920)
CHANGE_INTENSITY (broken_light, 255)
ENDIF
IF (cyclecounter = 1923)
SET cyclecounter = (cyclecounter - 200)
ENDIF
IF (cyclecounter > 2200)
CHANGE_INTENSITY (broken_light, 0)
IF (cyclecounter = 2202)
SET cyclecounter = (cyclecounter + 200)
ENDIF
IF (cyclecounter = 2203)
SET cyclecounter = (cyclecounter + 200)
ENDIF
ENDIF
IF (cyclecounter > 2250)
CHANGE_INTENSITY (broken_light, 170)
ENDIF
IF (cyclecounter > 2280)
CHANGE_INTENSITY (broken_light, 0)
ENDIF
SET cyclecounter = (cyclecounter + 3)
ENDWHILE //end of whileloop with value = 1
LEVELEND[/syntax]
It´s probably better to use a randomization script you can find in this topic.
I am still wondering how to generate coincidences just by mathmatic operations.
Please tell me if something doesn´t work here. I modified it for the topic and did not test exactly THIS script.
Re: Code Snippets
Zombieees Makes every pedestrian on map running after your brain
[mis]//Find new ped
IF(ped=0)
SET in = ( p1 + charpointer ) //all characters are stored after player 1
SET in = (in+360) // read sprite address of character
CHANGE_GANG_CHAR_RESPECT (in,out,104)
IF(NOT(out=0)) // check if sprite is existent, therefore character is walking around
SET ped= (p1 + charpointer) // store character in ped
ENDIF
SET charpointer = ( charpointer + 660 ) //adavance to next character address
IF ( charpointer > 32340 ) // 49 x 660 (each character has a struct of 660 bytes)
SET charpointer = 3960 // If you don't want to kill player 2-6, set to 3960 ( 6 x 660 )
ENDIF //charpointer > 32340
ENDIF
//set ped to null if character has died
IF((NOT(CHECK_CHARACTER_HEALTH(ped,0))) OR (HAS_CHARACTER_DIED(ped)))
SET ped=0
ENDIF
//if ped is alive
IF(NOT(ped = 0))
SET_CHAR_GRAPHIC_TYPE ( ped , DUMMY_GRAPHIC , 24 )
SET_CHAR_OBJECTIVE ( ped ,KILL_CHAR_ANY_MEANS , p1 )
SET ped=0
ENDIF[/mis]
See this thread for a similar complete script.
[mis]//Find new ped
IF(ped=0)
SET in = ( p1 + charpointer ) //all characters are stored after player 1
SET in = (in+360) // read sprite address of character
CHANGE_GANG_CHAR_RESPECT (in,out,104)
IF(NOT(out=0)) // check if sprite is existent, therefore character is walking around
SET ped= (p1 + charpointer) // store character in ped
ENDIF
SET charpointer = ( charpointer + 660 ) //adavance to next character address
IF ( charpointer > 32340 ) // 49 x 660 (each character has a struct of 660 bytes)
SET charpointer = 3960 // If you don't want to kill player 2-6, set to 3960 ( 6 x 660 )
ENDIF //charpointer > 32340
ENDIF
//set ped to null if character has died
IF((NOT(CHECK_CHARACTER_HEALTH(ped,0))) OR (HAS_CHARACTER_DIED(ped)))
SET ped=0
ENDIF
//if ped is alive
IF(NOT(ped = 0))
SET_CHAR_GRAPHIC_TYPE ( ped , DUMMY_GRAPHIC , 24 )
SET_CHAR_OBJECTIVE ( ped ,KILL_CHAR_ANY_MEANS , p1 )
SET ped=0
ENDIF[/mis]
See this thread for a similar complete script.
Re: Code Snippets
I love these hacks with pointers
Is there full "manual" for those pointer tricks yet? Would be nice to create some tool to generate the necessary pointer tricks for different things.
Also, have you guys figured out the struct structure that is 660 bytes in size? 660 bytes sounds very large for a character struct. Would be interesting to know what it contains.
Is there full "manual" for those pointer tricks yet? Would be nice to create some tool to generate the necessary pointer tricks for different things.
That is interesting. What is the magic number 32340 ? How did you calculate it? To my knowledge, 10*660 = 6600.IF ( charpointer > 32340 ) // 10 x 660 (each character has a struct of 660 bytes)
Also, have you guys figured out the struct structure that is 660 bytes in size? 660 bytes sounds very large for a character struct. Would be interesting to know what it contains.
My GTA2 related projects:
Re: Code Snippets
I took those numbers from Sektor, I think 32340 is the highest multiple of 660 you represent with a COUNTER. In an older script he used 6600 like the comment says.IF ( charpointer > 32340 ) // 10 x 660 (each character has a struct of 660 bytes)
That is interesting. What is the magic number 32340 ? How did you calculate it? To my knowledge, 10*660 = 6600.
See GTA2 memory addresses for some hints about the struct and that thread for some historyAlso, have you guys figured out the struct structure that is 660 bytes in size? 660 bytes sounds very large for a character struct. Would be interesting to know what it contains.
Re: Code Snippets
Yeah 10 x 660 was just an outdated comment in some old code but that code has spread around a bit with no one fixing it, so I went and changed it to 49 x 660. I don't think 49 was any magic number, I just figured 50 (1 player + 49 dummies) should be enough to control most of the peds. I'd prefer to set it to the exact number of peds that currently exist.
Re: Code Snippets
This shows a brief message only visible to a specific player:
[mis]
COUNTER static = 6206716
COUNTER myPlayer=0
COUNTER mainloop=1
LEVELSTART
SET in = (static+0)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+36)
CHANGE_GANG_CHAR_RESPECT (in,myPlayer,101)
WHILE_EXEC ( mainloop = 1 )
IF(myPlayer=1) //if me is player 2 (player 1 is 0)
DISPLAY_BRIEF ( 8001 )
ENDIF
IF(myPlayer=3) //if me is player 4 show another message
DISPLAY_BRIEF ( 8002)
ENDIF
ENDWHILE
LEVELEND
[/mis]
[mis]
COUNTER static = 6206716
COUNTER myPlayer=0
COUNTER mainloop=1
LEVELSTART
SET in = (static+0)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+36)
CHANGE_GANG_CHAR_RESPECT (in,myPlayer,101)
WHILE_EXEC ( mainloop = 1 )
IF(myPlayer=1) //if me is player 2 (player 1 is 0)
DISPLAY_BRIEF ( 8001 )
ENDIF
IF(myPlayer=3) //if me is player 4 show another message
DISPLAY_BRIEF ( 8002)
ENDIF
ENDWHILE
LEVELEND
[/mis]
Re: Code Snippets
Nice. That should be useful. You could also use it for arrows. If you did something stupid like KILL_CHAR then it would go out of sync but that's to be expected.
Re: Code Snippets
Wanted Level Cooldown:
Hiding from police for a while drops the wanted level ( greater than 1 ) to 1, and then you can finally clear your wanted level.
It not always work, since I do not fully understand the behaviour of some variables, like the "observed_address".
Code:
Cheat Engine:
observed_address = ( "GTA2.EXE"+0027B7A0 ) + offset: 7B4
heads_address = ( "GTA2.EXE" + 0027B7A0 ) + offset: 46C
wanted_address = ( "GTA2.EXE"+0027B7A0 ) + offset: 654h
observed = 1 -> there is police officers seeing you (it don't work with guards policemans or road-block police)
heads = 5 -> you're hidden (sometimes it don't work, so I combined it with the "observed" to obtain the desired result)
heads = 3,2,1 -> you are not hidden
Hiding from police for a while drops the wanted level ( greater than 1 ) to 1, and then you can finally clear your wanted level.
It not always work, since I do not fully understand the behaviour of some variables, like the "observed_address".
Code:
Code: Select all
PLAYER_PED p1 = (135.4, 128.3, 255.0) 8 45
COUNTER neverends = 1
// Cooldown Counters
COUNTER magic_address
COUNTER magic_number = 1906784
COUNTER timer = 0
COUNTER cycles_hide = 500 // cycles until cooldown
COUNTER observed_pointer = 1972 // = 7B4
COUNTER observed_address
COUNTER observed
COUNTER wanted_pointer = 1620 // = 654h
COUNTER wanted_address
COUNTER wanted_level
COUNTER heads_pointer = 1132 // = 46C
COUNTER heads_address
COUNTER heads_var
LEVELSTART
SET magic_address = ( p1 + magic_number )
SET wanted_address = ( magic_address + wanted_pointer )
SET observed_address = ( magic_address + observed_pointer )
SET heads_address = ( magic_address + heads_pointer )
WHILE_EXEC ( neverends = 1 )
CHANGE_GANG_CHAR_RESPECT(wanted_address, wanted_level,101) // Wanted level (0 to 6)
IF ( wanted_level > 1 )
CHANGE_GANG_CHAR_RESPECT(observed_address, observed,101) // observed variable (0 or 1)
CHANGE_GANG_CHAR_RESPECT(heads_address, heads_var,101) // Oscillating heads (3 or 5) 3 = oscillating, 5 = no oscillating
IF ( (observed = 0) AND (heads_var = 5) )
++timer
IF( timer = cycles_hide )
ALTER_WANTED_LEVEL (p1, 1)
SET timer = 0
ENDIF
ELSE
CHANGE_GANG_CHAR_RESPECT(observed_address, observed,101) // double check
IF ( observed = 1 )
SET timer = 0
ENDIF
ENDIF
ELSE
IF ( NOT ( timer = 0 ) )
SET timer = 0
ENDIF
ENDIF
ENDWHILE
LEVELEND
observed_address = ( "GTA2.EXE"+0027B7A0 ) + offset: 7B4
heads_address = ( "GTA2.EXE" + 0027B7A0 ) + offset: 46C
wanted_address = ( "GTA2.EXE"+0027B7A0 ) + offset: 654h
observed = 1 -> there is police officers seeing you (it don't work with guards policemans or road-block police)
heads = 5 -> you're hidden (sometimes it don't work, so I combined it with the "observed" to obtain the desired result)
heads = 3,2,1 -> you are not hidden
Re: Code Snippets
Custom Save
In the example below, you can customize the amount the player pays to save the game: (only works on v11.44 if you want to keep the classic sounds "DAMNATION" etc)
Furthermore, you can customize all the save mechanics. For example you can let the player to save without having money enough but spawn hitmen to kill you if that happens.
In the example below, you can customize the amount the player pays to save the game: (only works on v11.44 if you want to keep the classic sounds "DAMNATION" etc)
Code: Select all
SAVED_COUNTER flag_on_mission = 0 // Put this counter only if you haven't one of mission flag in your script
COUNTER player_score
COUNTER save_score = 100 // The amount the player needs to save the game
COUNTER save_cost = -100 // The save game cost
COUNTER vocal_value // 61 = save successful; 62 = not enough money
COUNTER voice_add = 6168620 // 0x5E202C
COUNTER save_delay = 120 // Delay before enabling the trigger again
COUNTER delay_count = 0 // Delay counter
// Adjust the trigger area to the building you are saving the game. In this example, you are saving on a 1x1 entrance.
// Remember that the player will spawn at coordinates (x, y+1, z) when loading the save
THREAD_TRIGGER thr_savepoint_1 = THREAD_WAIT_FOR_CHAR_IN_AREA (p1, 128.5, 136.0, 2.0, 1.00, 1.00, savepoint_1:)
savepoint_1:
// If the player isn't playing a mission
IF ( flag_on_mission = 0 )
STORE_SCORE (p1, player_score)
++player_score
// Check if the player has score enough to save the game
IF ( player_score > save_score )
EXEC
ADD_SCORE ( p1, save_cost ) // Pay the save
DISPLAY_BRIEF (1812) // "Your status is saved!"
SET vocal_value = 61 // "HALLELUJAH, ANOTHER SOUL SAVED!"
CHANGE_GANG_CHAR_RESPECT (voice_add,vocal_value,114) // Play sound
ENDEXEC
SAVE_GAME ()
ELSE
// The player does not have enough money
EXEC
DISPLAY_BRIEF (1995) // "Get lost, ya bum! It costs $[insert the save cost in brief 1995 in .gxt] to save the state of play here!"
SET vocal_value = 62 // "DAMNATION, NO DONATION, NO SALVATION!"
CHANGE_GANG_CHAR_RESPECT (voice_add,vocal_value,114) // Play sound
ENDEXEC
ENDIF
ELSE
// The player is playing a mission
IF ( flag_on_mission = 1 )
DISPLAY_BRIEF (1811) // "No no no! You cannot save your state of play while you are on a job. Get back to work!"
ENDIF
ENDIF
// Now wait some time before enabling the save trigger again
SET delay_count = (save_delay + 0)
WHILE_EXEC ( NOT ( delay_count = 0 ) )
--delay_count
ENDWHILE
ENABLE_THREAD_TRIGGER (thr_savepoint_1) // enable it again
RETURN
LEVELSTART
// The rest of the code
LEVELEND