Page 3 of 3

Re: Code Snippets

Posted: 05 Apr 2013, 21:15
by Sektor
[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]

Re: Code Snippets

Posted: 13 Dec 2013, 14:48
by roarke
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 ?
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

Posted: 13 Dec 2013, 15:00
by Sektor
roarke wrote:I don't understand how to use the snippets.
1. It will work in single player, or only in multiplayer ?
Both but they might need to be modified. It depends on the code.
roarke wrote: 2. For one mission/map or for many ?
Code needs to added to every SCR file that you want to use it in.
roarke wrote: 3. Both players or more, must have the same snippet ?
Everyone needs the same files. MIS files are ignored by GTA2, it needs the compiled version with SCR extension.
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 ?
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.

Re: Code Snippets

Posted: 09 Jan 2014, 15:06
by roarke
Thank you for the value of the reply.

Flashing Lights

Posted: 18 Dec 2014, 10:52
by Rick
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.
:idea: 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

Posted: 07 Apr 2015, 17:14
by Jones
Zombieees :) Makes every pedestrian on map running after your brain
Image
[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

Posted: 08 Apr 2015, 12:38
by T.M.
I love these hacks with pointers :D

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

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.

Re: Code Snippets

Posted: 08 Apr 2015, 19:36
by Jones
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.
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.
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.
See GTA2 memory addresses for some hints about the struct and that thread for some history :)

Re: Code Snippets

Posted: 09 Apr 2015, 09:44
by Sektor
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

Posted: 05 May 2015, 17:57
by Jones
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]

Re: Code Snippets

Posted: 06 May 2015, 03:36
by Sektor
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

Posted: 06 May 2024, 00:34
by valps
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:

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

Re: Code Snippets

Posted: 02 Nov 2024, 01:15
by valps
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)

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
EDIT: use ADD_SCORE_NO_MULT if you are working with multipliers system. However this command only accepts a constant in its parameter, so you cannot use the counter "save_cost" in it.

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.