Jump to content

[SA|CLEO] Een simpele ELS mod


robin_be

Recommended Posts

Simpele ELS mod




 

In deze tutorial ga ik uitleggen hoe je een emergency light system/emergency light mod kan maken voor GTA:SA. Dit houdt in dat we een knipperend effect geven aan de lichten van voertuigen.

post-140414-0-04558800-1435406867.gif

Benodigdheden

CLEO3 of hoger

Sannybuilder

GTA:SA v1 of v1.01

We maken gebruik van geheugenadressen, waardoor dit hoogstwaarschijnlijk niet zal kloppen voor andere versies

SCM-kennis

Basiskennis is een vereiste (Basis SCM-scripten: tutorial door @Dutchy3010 & @PatrickW)

We zullen ook werken met het geheugen (Werken met geheugen (adressen) in CLEO: tutorial door @Crypteq)

Inhoud

Belangrijkste code + uitleg

Variabelen toekennen

Incar subroutine

Toggle subroutine

Pattern control subroutines

Hoofdcode

Patroon aansturen

Finito

 

Belangrijkste code + uitleg

Het belangrijkste deeltje van de code is natuurlijk de lichten van de auto aan of uit laten gaan. Dit is echter niet zo vanzelfsprekend, er is namelijk geen enkele opcode die ons toelaat om dit te doen. Maar gelukkig is het wel mogelijk door een beetje in het geheugen van het spel te werken.

De basiscode ziet er zo uit:

0A97: 9@ = car 8@ pointer
000A: 9@ += 0x5A0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 2
 

■ De eerste lijn zorgt ervoor dat in 9@ het geheugenadres komt waar de structuur van auto 8@ opgeslagen zit.

Op de lijst van geheugenadressen kan je zien wat je daar allemaal kunt vinden.

■ De tweede lijn zorgt ervoor dat 9@ nu wijst naar het adres dat 1440 (=0x5A0 hex) bytes verder geplaatst is. Deze wijst naar de damage handler van de auto. (veronderstelling)

■ Op de derde lijn wordt de method die op geheugenadres 0x6C2100 zit aangeroepen vanuit de damage handler die 9@ aanwijst. Deze mehtod is SetLightStatus en zal dus de staat van een licht aansturen.

Opcode 0AA6 heeft een aantal parameters:

1) Memory address van method die we willen gebruiken

2) Memory address van de structuur van de damage handler van de auto

3) Aantal parameters er meegegeven worden

4) Aantal parameters dat verwijderd moeten worden uit de stack nadat de method uitgevoerd is.

5) De parameters die doorgegeven moeten worden naar de method die aangeroepen wordt, in dit geval een parameter die aangeeft of het licht aan of uit moet zijn, en het nummer van het licht.

Lichtnummers: 0 voorzijde links | 1 voorzijde rechts | 3 achterzijde beide

Standaard kun je de achterlichten niet apart aan- of uitzetten. Maar dit kan opgelost worden door:

0A8C: write_memory 0x6E1D4F size 1 value 2 vp 0
 

Dit heb ik gevonden in de source van mtasa. Er staat bij dat dit een bug is in het spel, maar ik denk dat het ook zou kunnen dat het gewoon iets onafgewerkts is (in de video kun je namenlijk zien dat de achterlichten van hotring racer A nog steeds niet apart werken).

Edit:

Op 27-6-2015 om 14:54, Big Boss zei:

Dat komt omdat het model beide lichten definiëert als zijnde "links achter". Als je deze toewijzing in het model verandert dan zullen ze wel apart werken. Zie het model van Hotring A en ter vergelijking het model van de gewone Hotring.

Nu hebben we volgende lichtnummers: 0 voorzijde links | 1 voorzijde rechts | 2 achterzijde links | 3 achterzijde rechts

Om hiermee gemakkelijk te kunnen werken had ik het idee om verschillende stukjes code te maken waar we naartoe kunnen gosub'en om de voorlichten of achterlichten te kunnen sturen.

:FL // front left
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 1
return

:FR // front right
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 1
return

:FB // front both
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 1
return

:FN // front none
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 1
return

:BL // back left
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 3
return

:BR // back right
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 3 
return

:BB // back both
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 3 
return

:BN // back none
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 3
return
 

Dus om bijvoorbeeld het linkervoorlicht te laten werken en het rechtervoorlicht te laten doven kunnen we dit met 1 lijntje doen:

0050: gosub @FL
 

Nu kun je even uitblazen want hier is het moeilijkste gedeelte al achter de rug :dans:

Variabelen toekennen

Hier ga ik plaatsen welk variabelen we voor wat gaan gebruiken, dit kan handig zijn om op terug te vallen als je even niet meer weet wat je aan het doen bent of als je de code na een lange tijd terugziet.

// vars:
//  1@  ELS enabled?
//  4@  zit speler in auto?
//  5@  patroon index
//  8@  player car
//  9@  damage handler pointer voor player car
//  33@ pattern delay timer
 

Alle andere nummers die je eventueel tegenkomt, zijn tijdelijke variablen.

32@ en 33@ zijn speciale timer-variabelen, deze worden elke milliseconde verhoogd met 1. Dit kan handig zijn als je een missie hebt met tijdsbeperking of als je een vertraging nodig hebt zoals hier: anders zou het misschien zo snel gaan dat je het niet deftig kan zien. Soms is dit ook te verkiezen boven een wait, want bij een wait kun je namelijk niets anders doen, maar als je een timer variabele gebruikt kun je bijvoorbeeld ondertussen nog kijken of de speler op een bepaalde toets drukt voor een menu te tonen.

Incar subroutine

Dit is een subroutine die gaat checken of de speler in een auto zit. Als dit zo is, zetten we 4@ op 1 en 9@ naar de damage handler pointer. Dit kunnen we dan aanroepen door een simpele gosub te gebruiken.

4@ geeft aan of de speler in een auto zit

9@ wijst naar de damage handler van de auto (zie eerste puntje: belangrijkste code + uitleg)

:INCAR
0006: 4@ = 0 //incar
00D6: if and
00DF:   actor $PLAYER_ACTOR driving 
84C8:   not actor $PLAYER_ACTOR driving_flying_vehicle 
84A9:   not actor $PLAYER_ACTOR driving_heli 
84A7:   not actor $PLAYER_ACTOR driving_boat
847A:   not actor $PLAYER_ACTOR driving_bike
004D: jf @INCAR_1 
0006: 4@ = 1 //incar
03C0: 8@ = actor $PLAYER_ACTOR car
0A97: 9@ = car 8@ pointer
000A: 9@ += 0x5A0
:INCAR_1   
return
 

code map

Spoiler

post-140414-0-38708800-1435406846.png

Toggle subroutine

Deze subroutine zal de staat verwisselen. Als het effect niet actief is, dan deze aanzetten, tekst tonen, variables resetten en een geluidje afspelen. Anders uitzetten, tekst tonen en een geluidje afspelen.

1@ geeft aan of het effect actief is.

:TOGGLE
00D6: if
0039:   1@ == 1 //enabled
004D: jf @ENABLE
0AD0: show_formatted_text_lowpriority "ELS ~r~disabled" time 2000
0006: 1@ = 0                                    
067F: force_car 8@ lights_to 1 // 1 = FORCE_CAR_LIGHTS_OFF
018C: play_sound 1053 at 0.0 0.0 0.0
return

:ENABLE
0AD0: show_formatted_text_lowpriority "ELS ~g~enabled" time 2000
0006: 1@ = 1
0006: 33@ = 0 // reset timer
018C: play_sound 1052 at 0.0 0.0 0.0
return
 

code map

Spoiler

post-140414-0-36874100-1435406837.png

Pattern control subroutines

Hier gaan we de patronen aansturen. Dit is het masterplan:

in 5@ zit de zgn 'pattern index', deze geeft aan in hoeverre het patroon zit. Dit zal van 0 tot 23 lopen (dus 24 verschillende staten). Afhankelijk van deze pattern index zullen we de staat van lichten veranderen. Zowel de voorlichten als achterlichten zullen een eigen patroon hebben.

De patronen die ik ga gebruiken staan in commentaar. L = links en R = rechts, - wil zeggen alles uit. Dan moeten we naar de juiste labels springen om de lichten veranderen enkel als het nodig is. Dus bv als er een - na een - komt hoeft er niets te gebeuren want de lichten zitten al in die staat.

Dit kan gemakkelijk geïmplementeerd worden door jump tables. Voor de mensen die al wat van programmeren kennen: dit lijkt goed op een switch statement.

// -------------- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// front pattern: L - L - - - R - R - - - L - L - - - R - R - - - 
:PATTERN_FRONT
0871: switch 5@ total_cases 16 default_case -1 @R case 0 @FL case 1 @FN case 2 @FL case 3 @FN case 6 @FR case 7 @FN case 8 @FR
0872: switch_continued case 9 @FN case 12 @FL case 13 @FN case 14 @FL case 15 @FN case 18 @FR case 19 @FN case 20 @FR case 21 @FN
 

Deze code wil zeggen dat we de waarde van 5@ zullen bekijken & er zijn 16 verschillende waardes waarvoor we kunnen jumpen naar een label. Als de waarde niet overeenkomt met een van die ingestelde waardes, gebruik de default jump (-1) en die gaat naar :R (dit is gewoon een label met een return statement erna). De rest van de waardes staan na elkaar. Bv als 5@ 0 is, jump naar :FL, bij 1 jump naar :FN etc etc.

In 0871 kunnen we 7 waardes zetten, hiermee hebben we echter niet genoeg maar gelukkig is er nog 0872 waarmee we de jump table kunnen uitbreiden. Hiermee hebben we net genoeg voor dit patroon, maar je kunt de jump table meerdere keren uitbreiden.

De labels zijn van de stukjes die ik in het begin heb gezet (belangrijkste code + uitleg).

// ------------- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// back pattern: L L L R R R L L L R R R L L L R R R L L L R R R
:PATTERN_BACK
0871: switch 5@ total_cases 8 default_case -1 @R case 0 @BL case 3 @BR case 6 @BL case 9 @BR case 12 @BL case 15 @BR case 18 @BL
0872: switch_continued case 21 @BR case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R
 

Merk op dat er hier op het einde allemaal -1 @R staat. Dit is omdat die opcode zoveel parameters verwacht, en we kunnen die niet leeglaten dus zetten we er meestal hetzelfde als bij de default case.

Deze zullen we ook oproepen met gosub.

Hoofdcode

Nu hebben we alle subroutines en kunnen we beginnen aan de main code.

:ELS_START duidt het begin aan van de loop. Hier staat er ook een wait 0 omdat dit een oneindige loop is en het spel kan anders niets anders doen.

pseudocode

variablen initialiseren
:ELS_START
wait 0
voor subroutine bij @INCAR uit
als 4@ niet 1 is (dus als speler niet in auto zit), jump terug naar @ELS_START
anders
als de speler niet f12 indrukt, ga naar @ELS_START_PATTERN en voer het patroon uit
anders
voor subroutine bij @TOGGLE uit om de staat de veranderen
wacht een beetje zodat de speler de toets kan loslaten
jump terug naar @ELS_START
 

code

{$CLEO .cs}
03A4: name_thread 'ELS'
0006: 1@ = 0
0006: 5@ = 0
0A8C: write_memory 0x6E1D4F size 1 value 2 vp 0 // default value: 3

:ELS_START
0001: wait 0
0050: gosub @INCAR
00D6: if
0039:   4@ == 1 //incar
004D: jf @ELS_START 
00D6: if
0AB0:   key_pressed 0x7B // f12
004D: jf @ELS_START_PATTERN
0050: gosub @TOGGLE
0001: wait $DEFAULT_WAIT_TIME // prevent double key
0002: jump @ELS_START
 

code map

Spoiler

post-140414-0-37736700-1435406823.png

Patroon aansturen

Bij :ELS_START_PATTERN gaan we het patroon aansturen. Hier zullen we een vertraging insteken zodat het patroon niet te snel zal gaan. Zoals eerder vermeld gaan we hiervoor timer 33@ gebruiken. 5@ geeft de index aan van het patroon.

pseudocode

als het niet aan staat of 33@ is minder dan 75, jump naar het begin (@ELS_START)
anders
forceer de lichten op aan (zodat de lichten ook overdag aan zijn).
voor subroutine bij @PATTERN_FRONT uit om de voorlichten aan te sturen
voor subroutine bij @PATTERN_BACK uit om de achterlichten aan te sturen
timer 33@ resetten op 0
pattern index 5@ verhogen, als dit meer is dan 23: terug op 0 zetten
jump naar het begin (@ELS_START)
 

code

:ELS_START_PATTERN
00D6: if and
0039:   1@ == 1 //enabled
0019:   33@ > 75 // pattern delay
004D: jf @ELS_START
067F: force_car 8@ lights_to 2 // 0 = NO_CAR_LIGHT_OVERRIDE | 1 = FORCE_CAR_LIGHTS_OFF | 2 = FORCE_CAR_LIGHTS_ON
0050: gosub @PATTERN_FRONT
0050: gosub @PATTERN_BACK
0006: 33@ = 0
000A: 5@ += 1 // pattern index
00D6: if
0019:   5@ > 23
004D: jf @ELS_START
0006: 5@ = 0
0002: jump @ELS_START
 

code map

Spoiler

post-140414-0-37736700-1435406823.png

Finito

En dat is het :D

Volledige code:

 

{$CLEO .cs}

03A4: name_thread 'ELS'

// vars:
//  1@  ELS enabled?
//  4@  zit speler in auto?
//  5@  patroon index
//  8@  player car
//  9@  damage handler pointer voor player car
//  33@ pattern delay timer

0006: 1@ = 0
0006: 5@ = 0

// Fix vehicle back lights both using light state 3 (SA bug)
// https://github.com/multitheftauto/mtasa-blue/blob/c0a35ccd2b7704c92907fd48f66eeea869e533a4/MTA10/multiplayer_sa/CMultiplayerSA.cpp#L1247
0A8C: write_memory 0x6E1D4F size 1 value 2 vp 0 // default value: 3

// ----------------------------------------------------------------------------
// main start point


:ELS_START
0001: wait 0
0050: gosub @INCAR
00D6: if
0039:   4@ == 1 //incar
004D: jf @ELS_START 
00D6: if
0AB0:   key_pressed 0x7B // f12
004D: jf @ELS_START_PATTERN
0050: gosub @TOGGLE
0001: wait $DEFAULT_WAIT_TIME // prevent double key
0002: jump @ELS_START

:ELS_START_PATTERN
00D6: if and
0039:   1@ == 1 //enabled
0019:   33@ > 75 // pattern delay
004D: jf @ELS_START
067F: force_car 8@ lights_to 2 // 0 = NO_CAR_LIGHT_OVERRIDE | 1 = FORCE_CAR_LIGHTS_OFF | 2 = FORCE_CAR_LIGHTS_ON
0050: gosub @PATTERN_FRONT
0050: gosub @PATTERN_BACK
0006: 33@ = 0
000A: 5@ += 1 // pattern index
00D6: if
0019:   5@ > 23
004D: jf @ELS_START
0006: 5@ = 0
0002: jump @ELS_START


// ----------------------------------------------------------------------------
// pattern control

// -------------- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// front pattern: L - L - - - R - R - - - L - L - - - R - R - - - 
:PATTERN_FRONT
0871: switch 5@ total_cases 16 default_case -1 @R case 0 @FL case 1 @FN case 2 @FL case 3 @FN case 6 @FR case 7 @FN case 8 @FR
0872: switch_continued case 9 @FN case 12 @FL case 13 @FN case 14 @FL case 15 @FN case 18 @FR case 19 @FN case 20 @FR case 21 @FN

// ------------- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// back pattern: L L L R R R L L L R R R L L L R R R L L L R R R
:PATTERN_BACK
0871: switch 5@ total_cases 8 default_case -1 @R case 0 @BL case 3 @BR case 6 @BL case 9 @BR case 12 @BL case 15 @BR case 18 @BL
0872: switch_continued case 21 @BR case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R case -1 @R

:R
return

// ----------------------------------------------------------------------------
// light control

:FL // front left
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 1
return

:FR // front right
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 1
return

:FB // front both
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 1
return

:FN // front none
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 0
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 1
return

:BL // back left
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 3
return

:BR // back right
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 3 
return

:BB // back both
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 0 param_light_nr 3 
return

:BN // back none
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 2
0AA6: call_method 0x6C2100 struct 9@ num_params 2 pop 0 param_destroyed 1 param_light_nr 3
return

// ----------------------------------------------------------------------------
// incar subroutine

:INCAR
0006: 4@ = 0 //incar
00D6: if and
00DF:   actor $PLAYER_ACTOR driving 
84C8:   not actor $PLAYER_ACTOR driving_flying_vehicle 
84A9:   not actor $PLAYER_ACTOR driving_heli 
84A7:   not actor $PLAYER_ACTOR driving_boat
847A:   not actor $PLAYER_ACTOR driving_bike
004D: jf @INCAR_1 
0006: 4@ = 1 //incar
03C0: 8@ = actor $PLAYER_ACTOR car
0A97: 9@ = car 8@ pointer
000A: 9@ += 0x5A0
:INCAR_1   
return

// ----------------------------------------------------------------------------
// toggle subroutine

:TOGGLE
00D6: if
0039:   1@ == 1 //enabled
004D: jf @ENABLE
0AD0: show_formatted_text_lowpriority "ELS ~r~disabled" time 2000
0006: 1@ = 0                                    
067F: force_car 8@ lights_to 1 // 1 = FORCE_CAR_LIGHTS_OFF
018C: play_sound 1053 at 0.0 0.0 0.0
return

:ENABLE
0AD0: show_formatted_text_lowpriority "ELS ~g~enabled" time 2000
0006: 1@ = 1
0006: 33@ = 0 // reset timer
018C: play_sound 1052 at 0.0 0.0 0.0
return

0A93: end_custom_thread
 

Volledige code map:

 

Spoiler

post-140414-0-16582500-1435406783_thumb.png

 

 

In SA-MP zullen de andere spelers het enkel kunnen zien als het nacht is, aangezien de lichten zogezegd niet aanstaan tijdens de dag. Ook zullen de achterlichten voor de andere spelers ofwel beide aan of uit zijn, tenzij ze ook deze mod hebben of een andere die de waarde aanpast die dit fixt.

Nu kun je het natuurlijk uitbreiden, misschien meerdere patronen, een mooi menu'tje?

post-140414-0-80952800-1435406735.jpg

Edits:

28/06/2015 quote van @Big Boss mbt hotring racer bijgezet

14/04/2017 fix niet-werkende incar subroutine.. oeps (+ fix attachments)

 

patternstart.png

Edited by robin_be
Link to comment
Share on other sites

Duidelijk. Gigantisch veel werk. Applaus.gif

Maar ik blijf mij er toch over verbazen hoe primitief het nog steeds allemaal is. Je zou toch denken dat men nu toch wel iets zou uitgevonden hebben om een simpele loop te schrijven en variabelen een naam te geven in plaats van het nietszeggende "8@". Al die jumps en goto's leiden tot spaghetti code waar je nauwelijks wijs uit wordt.

in de video kun je namenlijk zien dat de achterlichten van hotring racer A nog steeds niet apart werken

Dat komt omdat het model beide lichten definiëert als zijnde "links achter". Als je deze toewijzing in het model verandert dan zullen ze wel apart werken. Zie het model van Hotring A en ter vergelijking het model van de gewone Hotring.

Link to comment
Share on other sites

Duidelijk. Gigantisch veel werk. :klap:

Maar ik blijf mij er toch over verbazen hoe primitief het nog steeds allemaal is. Je zou toch denken dat men nu toch wel iets zou uitgevonden hebben om een simpele loop te schrijven en variabelen een naam te geven in plaats van het nietszeggende "8@". Al die jumps en goto's leiden tot spaghetti code waar je nauwelijks wijs uit wordt.

Dankje ^_^

De naamgeving is idd een moeilijk punt. Globale variabelen kun je wel een naam geven maar het wordt afgeraden die te gebruiken in een cleo script of als het niet nodig is om die tussen threads nodig te hebben. Daarnaast zijn er ook wel wat high level structuren zoals if-then-else-end en repeat-until.

bv

repeat
   wait 0 ms
   if 00E1:   player 0 pressed_key 15 
   then
       08DA: remove_panel $KLEDINGMENU
       03E6: remove text box
       actor.PutAt($PLAYER_ACTOR, 256.9322, -41.5877, 1002.0234)
       actor.Angle($PLAYER_ACTOR) = 90.0
       0373: set_camera_directly_behind_player
       01B4: set_player $PLAYER_CHAR can_move 1 
       jump @KLEDING_1
   end
until 00E1:   player 0 pressed_key 16

Het ziet er misschien wel duidelijker uit maar ik werk persoonlijk meestal liever met de jumps. Uiteindelijk krijg je ook een soort mix van low en high level structuren en dat zie ik niet zo graag. Maar voor een tutorial was het misschien wel beter om deze wel te gebruiken om de code duidelijker te maken.

Edit: bedank voor de uitleg van de hotring racer, het is dan een beetje hetzelfde zoals de voorlichten van de infernus :puh: Ik dacht dat het iets onafgewerkts was omdat je kan zien dat het rechterlicht nog een klein beetje licht geeft als ze beide uit zijn.

Edited by robin_be
Link to comment
Share on other sites

Een zeer overzichtelijke en duidelijke tutorial.

Geweldig om te zien dat je nog zoveel met het modden van GTA SA bezig bent. thumbsup2.gif

Heb eigenlijk nooit echt nagedacht om in tutorials code-maps te gebruiken maar zeker op de manier zoals jij ze hier weergeeft draagt het zeer goed bij aan de structuur en duidelijkheid.

Ik ga ook eens kijken naar de mogelijkheid om dat te gebruiken in een toekomstige tutorial. smile3.gif

Heb de tutorial in de Master Tutorial List gezet. blij.gif

Edit:


"Naamgeving" is wel mogelijk zonder dat je global vars gaat gebruiken, tenminste om het leesbaar te houden.

Als je vele variabelen hebt dan kan je ook gewoon gewoon const gebruiken om ze voor de leesbaarheid een naam te geven.

Is tijdje geleden dus of dit de correcte syntax is... clown.gif

Als ik die "voorbeeldcode" van je neem:

//const vars
const KLEDINGMENU 0@
const POSITION_X 1@
const POSITION_Y 2@
const POSITION_Z 3@
const ANGLE 4@

0007: POSITION_X = 256.9322
0007: POSITION_Y = -41.5877
0007: POSITION_Z = 1002.0234
0007: ANGLE = 90.0

repeat
 wait 0 ms
 if 00E1: player 0 pressed_key 15
 then
		 08DA: remove_panel KLEDINGMENU
		 03E6: remove text box
		 actor.PutAt($PLAYER_ACTOR, POSITION_X, POSITION_Y, POSITION_Z)
		 actor.Angle($PLAYER_ACTOR) = ANGLE
		 0373: set_camera_directly_behind_player
		 01B4: set_player $PLAYER_CHAR can_move 1
		 jump @KLEDING_1
 end
until 00E1: player 0 pressed_key 16

Intern is het dan allemaal nog gewoon 0@, 1@ etc. Maar voor de leesbaarheid is het wel een stuk beter. smile3.gif

Edited by Crypteq
Link to comment
Share on other sites

Een zeer overzichtelijke en duidelijke tutorial.

Geweldig om te zien dat je nog zoveel met het modden van GTA SA bezig bent. thumbsup2.gif

Heb eigenlijk nooit echt nagedacht om in tutorials code-maps te gebruiken maar zeker op de manier zoals jij ze hier weergeeft draagt het zeer goed bij aan de structuur en duidelijkheid.

Ik ga ook eens kijken naar de mogelijkheid om dat te gebruiken in een toekomstige tutorial. smile3.gif

Heb de tutorial in de Master Tutorial List gezet. blij.gif

Thanks :D Ik kwam op het idee toen ik bezig was met IDA, vooral met al die jumps is het dan handig om te zien waar je allemaal heengaat.

"Naamgeving" is wel mogelijk zonder dat je global vars gaat gebruiken, tenminste om het leesbaar te houden.

Als je vele variabelen hebt dan kan je ook gewoon gewoon const gebruiken om ze voor de leesbaarheid een naam te geven.

Is tijdje geleden dus of dit de correcte syntax is... clown.gif

Bedank voor de tip :tu: had ik nog niet tegengekomen.

De syntax is wel een klein beetje anders, met CONST..END:

//const vars
const
   KLEDINGMENU 0@
   POSITION_X 1@
   POSITION_Y 2@
   POSITION_Z 3@
   ANGLE 4@
end

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...