robin_be Geplaatst: 27 juni 2015 Rapport Geplaatst: 27 juni 2015 (bewerkt) 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. 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 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 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 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 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 Finito En dat is het 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 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? Edits: 28/06/2015 quote van @Big Boss mbt hotring racer bijgezet 14/04/2017 fix niet-werkende incar subroutine.. oeps (+ fix attachments) Bewerkt: 14 april 2017 door robin_be Reageren
Big Boss Geplaatst: 27 juni 2015 Rapport Geplaatst: 27 juni 2015 Duidelijk. Gigantisch veel werk. 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. Reageren
robin_be Geplaatst: 27 juni 2015 Auteur Rapport Geplaatst: 27 juni 2015 (bewerkt) Duidelijk. Gigantisch veel werk. 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 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. Bewerkt: 27 juni 2015 door robin_be Reageren
Crypteq Geplaatst: 27 juni 2015 Rapport Geplaatst: 27 juni 2015 (bewerkt) Een zeer overzichtelijke en duidelijke tutorial. Geweldig om te zien dat je nog zoveel met het modden van GTA SA bezig bent. 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. Heb de tutorial in de Master Tutorial List gezet. 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... 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. Bewerkt: 27 juni 2015 door Crypteq Reageren
robin_be Geplaatst: 27 juni 2015 Auteur Rapport Geplaatst: 27 juni 2015 Een zeer overzichtelijke en duidelijke tutorial. Geweldig om te zien dat je nog zoveel met het modden van GTA SA bezig bent. 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. Heb de tutorial in de Master Tutorial List gezet. Thanks 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... Bedank voor de tip 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 Reageren
Dutchy3010 Geplaatst: 28 juni 2015 Rapport Geplaatst: 28 juni 2015 Ziet er goed uit, toffe tutorial Reageren
Recommended Posts
Een reactie plaatsen
Je kan nu een reactie plaatsen en pas achteraf registreren. Als je al lid bent, log eerst in om met je eigen account een reactie te plaatsen.