Jump to content

[SA|SCM] Mission Coding for Dummies!


Recommended Posts

Geplaatst:

Wij schrijven deze tutorials om zo te proberen om meer animo te krijgen voor SCM scripten. Momenteel zijn er veel te weinig scripters, zeker in verhouding tot het aantal Modellers. Aangezien er weinig tutorials op dit forum zijn, en al helemaal weinig die over SannyBuilder gaan, maken wij (PatrickW en ik) een aantal tutorials om jullie wat op weg te helpen.

Waarom SannyBuilder? Omdat dat een hele handige en overzichtelijke tool is voor het schrijven van de code. Zeker voor beginnende scripters, die we met deze tutorials willen bereiken, is dit natuurlijk erg handig.

Voor deze tutorials heb je nodig:

  • SannyBuilder (Download)
  • Een "stripped" code (die kan je vinden in de SannyBuilder Map > Data >> SA >> Stripped)
  • Grand Theft Auto: San Andreas
  • Ped Editor (Download)
  • San Andreas Place Manager (Download)

In dit topic worden alleen tutorials geplaatst. Reacties en vragen kan je plaatsen in het reactietopic. Ook kan je hier nieuwe tutorials aanvragen als je ergens vastloopt.

Wij hopen dat jullie hier wat aan hebben!

Inhoudsopgave

Tutorial 1: Beginnen met scripten

Tutorial 2: De absolute beginselen

Tutorial 3: Basis SCM-scripten

Tutorial 4: Actors

Tutorial 5: Wapens (en eigenschappen) aan een Actor

Tutorial 6: Cars spawnen

Tutorial 7: Spheres, icons en markers

Tutorial 8: Een eenvoudige missie

Tutorial 9: Een echte missie (Rockstar style)

Tutorial 10: Status Balken

Tutorial 11: Actor Animations en Animation Paths

Tutorial 12: Pickups

Tutorial 13: Teksten

Tutorial 14: Custom Save Point

Tutorial 15: Cutscenes

Tutorial 16: Menu's

Andere handige tutorial:

MPACK's

SCM VS CLEO

Ook deze tutorials zijn zeker het proberen waard, want leren je de handigste manieren om te scripten. :)

Geplaatst:

Beginnen met scripten (San Andreas)

Inhoud

  • Inleiding
  • Wat heb ik nodig?
  • Het programma
  • SCM Scripten
    • Structuren belangrijkst!
    • Het scripten zelf

    [*]CLEO

    • Introductie tot CLEO
    • CLEO Scripten

    [*]Tot slot

Inleiding

Deze "tutorial" (bij gebrek aan een beter woord) is alleen voor mensen die willen leren scripten, dus niet de mensen die al kunnen scripten. Voor jullie is dit gesneden koek, maar voor mensen die net beginnen niet. ;) Stel, je wil leren scripten, maar waar moet je beginnen? Je kunt door de bomen het bos niet meer zien. In deze tutorial, loods ik je door het beginnen heen. Een stap die voor velen als te moeilijk wordt beschouwd en daarom stoppen ze gelijk. Laat ik jullie wat zeggen: iedereen die inzet heeft, kan leren scripten! Maar denk niet: ik wil nu leren scripten, en morgen maak ik mijn eerste missie. Zo werkt het uiteraard niet. Zoiets heeft tijd nodig, net als wanneer je wil leren Photoshoppen of 3d modellen. Deze "tutorial" zal voornamelijk links en tips bevatten, die je het opstarten vergemakkelijkt.

Wat heb ik nodig?

Wat heb je allemaal nodig om te scripten? Sommige mensen vragen zich dit af, ik zal een lijstje maken:

  • Een programma waarmee je kunt editten (SannyBuilder of MissionBuilder)
  • Een GXT editor (sagxtedit)
  • San Andreas Place Manager (niet voor de coords, maar om te kunnen springen)
  • Map Editor
  • Ped Editor
  • Tijd en inzet

Het programma

Allereerst moet je het programma een beetje kennen. Ik raad je aan om SannyBuilder te gebruiken, aangezien die veel gebruikersvriendelijker is dan Missionbuilder. De laatste wordt ook niet meer geupdate. Het allereerste wat je moet weten, is hoe zo'n programma een beetje werkt. Als je niet weet hoe je de code tevoorschijn haalt, loop je natuurlijk gelijk al vast. Voor dat probleem is deze tutorial een goede oplossing.

SCM Scripten

Structuren belangrijkst!

Natuurlijk wil je gelijk scripten. Missies maken, of andere dingen die in je hoofd zitten. Dit raad ik je ten zeerste af, want als je eerst wat tijd in het leren van de structuren steekt, gaat het later vele malen beter. Dit kan je vergelijken met school: je moet nu leren (iets wat minder leuk is), maar later krijg je daardoor wel een veel betere baan dan wanneer je niet naar school zou gaan. Om dit te leren raadt ik je deze tutorial aan.

Het scripten zelf

Nu ken je, als het goed is, de structuren al. Ook nu moet je niet gelijk willen beginnen met het maken van een totale missie. Het eerste wat je moet doen, is bijvoorbeeld pickups spawnen. Helaas is voor pickups spawnen geen Sannybuilder tutorial, maar ik denk dat je (met een beetje aanpassen) deze of deze tutorials wel kunt gebruiken (Let dus op: deze zijn voor Missionbuilder!). Vervolgens kan je beetje proberen om een car te spawnen, m.b.v. deze tutorial. Als je dat een beetje geprobeerd hebt, en het lukt, dan kan je proberen een kleine missie te maken. Ik raad je dan ook aan om dit topic helemaal door te lezen, en alle tutorials te doen die je nog niet gedaan hebt. Wanneer je eigenwijs bent, en toch MissionBuilder wil gebruiken, kan je deze tutorial doorlezen. Maar zoals ik al zei, dat raad ik je af. Ook omdat je dan geen CLEO kunt gebruiken, iets waar ik hierna op terugkom.

CLEO

Introductie tot CLEO

Allereerst raad ik je aan om eerst SCM te leren. Als je kunt SCM-scripten, kan je ook CLEO maken. Andersom is dat echter niet altijd het geval, door bepaalde structuren binnen het SCM die je niet hebt binnen CLEO. Maar wat is CLEO nou? CLEO zorgt ervoor dat je geen nieuwe savegame hoeft te beginnen. Er zijn enkele verschillen met SCM, en als je kunt SCM'en zou ik gewoon een keer in de help-files van SannyBuilder kijken. Daar staan alle verschillen in: Help > Contents > CLEO 3 Code Library. De meeste kleine mods komen tegenwoordig uit in CLEO, zodat die gewoon naast je savegames kan draaien. De bekendste CLEO mod op dit forum is de BC7 mod. Een andere bekende mod, Design Your Own Mission, is juist niet een CLEO-mod, omdat die daar te groot voor is. Daarvoor is een MPACK gebruikt, iets wat erg handig is, en waar je hier een tutorial over kunt vinden. Heel handig om gebruik van te maken. Je moet dus goed bedenken wat je gebruikt: CLEO (voor de mods die naast de savegames moeten lopen) of SCM (voor de mods die los van savegames etc staan).

CLEO scripten

Misschien wil je eerst een CLEO-script downloaden en gebruiken, voordat je zelf gaat scripten. Wanneer je dat doet, kan je daarvoor deze tutorial gebruiken. Je moet natuurlijk eerst CLEO installeren, maar wanneer je SannyBuilder download krijg je daarvoor de optie (rechts onderin in het programma). Wanneer je eenmaal CLEO geïnstalleerd hebt, kun je ook gaan CLEO-scripten. Dit is, zoals ik al zei, vrijwel hetzelfde als het scripten van SCM, met enkele (cruciale) verschillen. Gewoon even in de help-files kijken, dus. Wat je ook kunt doen, om het verschil tussen die twee echt te kunnen zien, is de eerder genoemde tutorial over het spawnen van een auto vergelijken met deze tutorial.

Wanneer je eenmaal een beetje geleerd hebt te scripten, kan je ook nog andere CLEO-tutorials bekijken, zoals deze of deze. Dit raad ik je echter ten zeerste af als je nog maar net bent begonnen, want deze heb je een tijd lang niet nodig en zijn in het begin veel te moeilijk! ;)

Tot slot

Als je vragen hebt, kan je die natuurlijk altijd in het hulp forum van het scripten zetten, en je wordt zo snel en zo goed mogelijk geholpen! Heel veel succes!

Geplaatst:

De Absolute beginselen van SCM scripten



Inhoud:

  • Programma's
    • Welke programma's
    • Vergelijking
    • Hulpprogramma's

    [*] Decompileren

    • Wat is decompileren?
    • Hoe moet je decompileren?

    [*] Compileren

    • Wat is compileren
    • Verschil tussen compile en compile+copy

Programma's

Welke programma's zijn er?

Er zijn verschillende programma's die je als belangrijkste editor voor het SCM scripten kunt gebruiken. Allereerst MissionBuilder, daarnaast SannyBuilder en tot slot kan het ook gedeeltelijk! in kladblok.

Vergelijking

[table=header]Functie

MissionBuilderSannyBuilderKladblokEdittenjajaja (wanneer al gedecompileerd)CompilerenjajaneeDecompilerenjajaneeUpdatesneejaneeExtra'sweinigjaneeMakerBarton WaterduckSeemannMicrosoftDownloadlinkKlikKlikn.v.t.[/table]

Onder extra's in SannyBuilder worden dingen verstaan als: CLEO3, een ingebouwde coordinaten-tool, een opcode-search-tool, veel sneltoetsen, gekleurde teksten, waardoor duidelijk wordt wat wat is, etcetera.

Ik raad dan ook aan dat iedereen, zeker de mensen die net begonnen zijn met SCM-scripten, SannyBuilder te gebruiken.

Hulpprogramma's

Bij het SCM scripten is vaak alleen een editor niet genoeg. Er zijn genoeg hulpprogramma's te vinden, die je kunnen helpen bij het scripten. Een paar voorbeelden:

San Andreas Place Manager: vooral handig om te springen naar de plek waar je moet zijn bij het testen. Kan ook voor Coördinaten worden gebruikt (let wel op het verschil komma-punt!).

PED-editor: hiermee kan je handig de "code"/"naam" van een PED opzoeken, zodat je hem kunt gebruiken.

Decompileren

Wat is decompileren?

Voordat je de file kunt editten, moet je eerst compileren. Dat wilt zeggen dat je hem leesbaar maakt, je veranderd de extensie van .scm naar .txt. Dit kan je dus doen in MissionBuilder en SannyBuilder, maar niet in kladblok. Wanneer het een txt file is, kan je hem ook openen in kladblok en daar editten. Dit is echter niet handig, omdat er geen extra's zitten in kladblok (wat het dus alleen maar moeilijker maakt). Je kunt hem dan dus editten in elke text editor die je je maar kunt bedenken.

Hoe moet je decompileren?

Aangezien dit een tutorial is voor SannyBuilder, zal ik het ook uitleggen voor SannyBuilder. Eigenlijk is het heel simpel: druk op F5 óf het toetsje "decompile" óf bij "run" > "Decompile".

post-33831-1247829775_thumb.jpg

Ga vervolgens naar de map: Program Files > GTA San Andreas > Data > Script, en kies voor "main" (een .scm file). Druk vervolgens op openen.

post-33831-1247829778_thumb.jpg

Als je dit voor de eerste keer doet, krijg je misschien een scherm als hieronder staat. Geef daar de map "GTA san Andreas" aan. Doe vervolgens het bovenstaande opnieuw.

post-33831-1247829783_thumb.jpg

Nu krijg je een tekst voor je, die je kunt editten. Als je hem zo opslaat, krijg je een txt bestandje.

Compileren

Wat is compileren?

Wanneer je wilt testen of het klopt, dan moet je het weer "omschrijven" naar de taal die GTA San Andreas leest. Dan moet je dus weer terug brengen naar de originele staat. Dit tegenovergestelde aan decompileren heet compileren. Dit kan je doen via "Run" > "Compile", door op F6 te drukken of door in de toolbar op het tekentje van compile te klikken.

Wat is het verschil tussen compile en compile + copy?

Het kan zijn dat je iets maakt in een andere map dan de originele Data map, bijvoorbeeld m.b.v. MPACK of gewoon als je het ergens anders op wilt slaan. Compile betekent dat de SCM file in de map terecht komt waar ook de txt file staat. Compile + Copy betekent dat de scm file én in de map van de txt file komt, én in de map Data. De vorige main.scm wordt in dat laatste geval dus overschreven. Er is geen verschil wanneer je de main.txt file aan het editten bent in de map "Data".

Tot zover de absolute beginselen van het scripten. Op aanvraag van Unmountable Tijmen, hopelijk heb ik hierbij een tutorial gemaakt zoals jij het bedoelde. Zo niet, dan moet je maar even via PM uitleggen wat je wel bedoelde, en schrijf ik die tutorial ook. ;)

Geplaatst:

Basis SCM-scripten

Sannybuilder

Allereerst zal ik jullie wat basis leren over het programma wat we gebruiken: SannyBuilder. Er zijn een aantal handige dingen om te weten, waardoor het scripten een stuk leuker en eenvoudiger wordt. Maar we zullen beginnen bij het begin: het decompileren.

Ga naar Run > Decompile. Dit kan ook door op het tekentje in de balk te klikken, of op F5 te drukken.

Klik vervolgens op Program Files > Rockstar Games > GTA San Andreas > data > script.

En je ziet de code, waarin je kan editten.

post-33831-1247830083_thumb.png

Nu kun je gaan editten. Handig aan Sannybuilder is dat de tekst kleurtjes heeft:

  • Zwart: dit is bij bepaalde vaakgebruikte (waar je vaak ook geen code voor hoeft te zetten), zoals jump, wait, create_thread, fade, repeat, jf, etcetera.
  • Groen: dit is de naam van een label, bijvoorbeeld “:label” of “@label” (achter een jump ofzo).
  • Blauw: de variabelen hebben een blauwe kleur
  • Rood: namen van bijvoorbeeld objecten, teksten en threads zijn rood.
  • Geel en blauw: deze zijn achter elkaar te vinden in een file. De gele is het “object” wat bedoeld wordt, de blauwe is wat iets over het eerste zegt. Misschien moeilijk uit te leggen, maar als je even bekijkt snap je het wel. ;)
  • Bruin: namen van models
  • Blauw/grijs (lichter): dit staat achter //, wat als kladblaadje kan functioneren. Dit wordt niet gelezen door het spel, en dient alleen als kladblaadje voor de modder(s).

Er zijn een aantal functies in SannyBuilder die erg handig zijn om te gebruiken:

  • Coords manager, te vinden in: Tools > Ide Tools > Coords Manager (sneltoets: CTRL+ALT+1). Hiermee vind je gelijk de X, Y en Z coordinaat én de hoek waarmee je op dat moment in SA staat. Dit kan je niet aanklikken als je SA niet aanstaat.
  • Opcode search, te vinden in: Tools > Ide Tools > Coords Manager (sneltoets: CTRL+ALT+2). Hiermee kan je makkelijk zoeken naar opcodes.
  • De F1 toets is erg handig. Als je iets typt, bijvoorbeeld de begincode van een opcode, dan krijg je gelijk het volledige te zien. Ook andere dingen kan je intypen Een soort zoekfunctie dus.
  • Contents, te vinden onder “HELP”, met als sneltoets F12. Hierbij vind je een hele grote documentatiebank, als je op SCM Documentation klikt. Heel handig als je bijvoorbeeld een bepaald icon-nummer zoekt, of één van de vele andere dingen.
  • Je kunt vanuit Sanny gelijk SA opstarten, door op het icoontje “Run San Andreas” of F8 te drukken.
  • Er is een code converter van Mission Builder naar SannyBuilder, maar die werkt niet vlekkeloos. Als je het toch wilt doen, wat ik je niet aanraad, ga dan naar Tools > Code Converter > MB -> SB.

Als je klaar bent met editten, moet je het weer compileren. Dit doe je door op Run > Compile te klikken, of op het icoontje, of op F6. Je hebt ook nog een andere functie om te compileren, namelijk Compile + Copy, F7. Dit betekent dat het altijd in de map GTA San Andreas > Data > Script wordt opgeslagen, dus niet op de plaats waar jij het bestand op dat moment hebt staan.

Natuurlijk heeft SannyBuilder nog meer mogelijkheden, maar dit zijn de belangrijkste.



Het scripten

Threads

Je kunt het script zien alsof er een mannetje doorheen loopt. Soms komt dat mannetje bij een punt aan, waar hij zich verdubbeld: “create_thread”. Ze leven dan beide door, maar het originele mannetje gaat door vanaf “create_thread”, terwijl het gekloonde mannetje doorgaat op de plaats waar je een nieuwe thread wilt laten starten. Dus bijvoorbeeld: create_thread @boe, dan gaat het mannetje verder bij :boe. Als een mannetje bij het commando “end_thread” komt, gaat hij dood. Dan loopt die dus niet verder door de code. Er kunnen dus heel veel mannetje tegelijk lopen (er komt immers bij iedere “create_thread” een nieuw mannetje), die ieder hun eigen werkzaamheden op hetzelfde moment aan het doen zijn. De mannetjes werken onafhankelijk van elkaar.

De missies zijn een apart soort thread, en worden dan ook niet aangegeven met “create_thread”, maar met “start_mission”. Het zorgt er bijvoorbeeld voor dat je maar één missie tegelijk kunt beginnen. Het aparte is dat er door heel het script wordt gecontroleerd of je “wasted” of “busted” bent, en niet alleen wanneer dat commando er staat. Als de player wasted of busted is doet het mannetje van de missie thread alsof hij een "return" tegenkomt. Daarom moeten missies ook altijd beginnen met een bepaalde structuur..

Labels/jump/gosub

Labels worden aangegeven met “:” ervoor. Het zijn namen die worden toegekend aan bepaalde plekken/locaties/punten in het script. Dit is handig om ernaar toe te kunnen springen. Dit kan met “gosub” en “jump”.

:MAIN_4059
01B7: release_weather 
jump @MAIN_4075

Hierboven zie je een label, namelijk “MAIN_4059”. Vervolgens zie je een commando, met een code ervoor. Die code heet een opcode. Daaronder zie je een ander commando, namelijk jump. Met die @... geef je aan dat je naar een label springt. Je springt dus naar het label: :MAIN_4075.

Gosub is een ander verhaal. Daarmee springt hij naar een ander label, en gaat hij weer terug nadat het script “return” gelezen heeft. Voorbeeld:

 :MS_GAME_BEEFYBARON
$ONMISSION = 1 // integer values 
00BA: text_styled 'BEEFY' 1000 ms 2  // Beefy Baron
gosub @SUB_FADE_500MS 
start_mission 10  // Beefy Baron
jump @END_CASE_VIDEO_GAME

 :SUB_FADE_500MS
0169: set_fade_color 0 0 0 
fade 0 500 

:LITCAS_282
if 
fading 
else_jump @LITCAS_306 
wait 0 
jump @LITCAS_282 

:LITCAS_306
Return

Hierboven springt hij dus eerst met “gosub” naar :SUB_FADE_500MS. Daar gaat het script erdoorheen en gaat pas terug na het commando “return” (LITCAS_306).

Na “return” gaat hij dus weer terug naar de gosub, in MS_GAME_BEEFYBARON

dus.

De reden waarom “gosub” gebruikt wordt in plaats van 2x jump, is omdat het dan altijd standaard terug gaat naar de plaats waar hij vandaan komt. Meerdere mannetjes kunnen dan afzonderlijk van elkaar springen naar het label waar gosub naar verwijst, en terugkomen naar het stukje waar ze vandaan komen. Bij “jump” gaat hij echter altijd naar hetzelfde label terug. Gosub komt van subroutine.

Conditionele jump

Er is ook nog zoiets als de “conditionele jump”. Dan checkt het mannetje het script, en kijkt of er iets gebeurd is. Is dat niet gebeurd, dan jump je ergens anders naar toe. Is dat wel gebeurd, dan gaat het script gewoon door. Hiervoor kan je drie dingen gebruiken:

“else_jump @boe”

“jf @boe”

“004D: jump_if_false @boe”

In SannyBuilder wordt meestal één van de twee bovenste gebruikt, omdat bij de derde ook de opcode (004D) gebruikt moet worden.

:SWEET4_103
if
  Model.Available(#GREENWOO)
else_jump @SWEET4_152

In dit voorbeeld wordt gekeken of een Model beschikbaar is (het model van de Greenwood, in dit geval). Als dat niet het geval is, dan springt hij naar het label “:SWEET4_152”. Is dit wel het geval, dan gaat hij gewoon door.

Je kunt hier ook een lus van maken, dan wacht het mannetje net zo lang tot aan de voorwaarde gedaan wordt. Let wel op, dat je dan een wait moet plaatsen! In alle lussen, moet een wait. Als je dat vergeet, slaat het spel vast. Vaak kan je hierdoor niets meer, ook niet terug naar je bureaublad, waardoor je genoodzaakt bent om je pc opnieuw op te starten. Een voorbeeld van zo’n lus is:

:SWEET4_103
Wait 0 ms
if
  Model.Available(#GREENWOO)
else_jump @SWEET4_103

Zoals je ziet, blijft hij, zolang het model niet beschikbaar is, terugspringen naar het begin van dit label. Is dat wel het geval, dan gaat hij door.

Conditionele gosub

Naast een conditionele jump, is er ook een conditionele gosub (bestaat alleen bij CLEO3!!!):

0AA0: gosub_if_false @CREATE_NEW_ACTOR

Dit werkt precies hetzelfde als een conditionele jump (alleen dan met een gosub). Dit wordt echter niet zo vaak gebruikt…

If-then-end structuur

Er zijn nog andere structuren, buiten de jump_if_false, waarmee je kunt checken of iets gebeurd. Een voorbeeld hiervan is de if-then-end structuur (deze heb ik zelf geschreven, dus is niet terug te vinden in de main van sa):

if $choice == 0
then
$money = 10
End

Wanneer de variabele $choice gelijk is aan 0, dan wordt de waarde van de variabele “$money” gelijk aan 10. Is $choice niet gelijk aan 0? Dan gebeurt er gewoon niets. De end is nodig om aan te geven vanaf waar de voorwaarde niet meer geld, dus wat het mannetje altijd moet lezen, ook als $choise niet gelijk is aan 0. Je kunt dus bij $money nog veel meer dingen zetten die moeten gebeuren als $choice gelijk is aan 0.

Repeat-wait-until structuur

 repeat
 wait 0 ms
until 03D0: wav 3 loaded

Dit is een voorbeeld van een repeat-wait-until structuur. Aangezien dit weer een lus is, moet er weer een wait bijstaan. Hier staat: blijf alles doen wat tussen repeat en until staat, tot de voorwaarde bereikt is. Tussen repeat en until kunnen ook andere dingen staan, bijvoorbeeld dat je in een auto moet blijven zitten. In plaats van dit kan je het ook in de vorm van een conditionele jump schrijven:

:label
wait 0 ms
if
03D0: wav 3 loaded
else_jump @label

Getallen

Er zijn 2 mogelijke getallen:

Integer Values: hele, natuurlijke getallen (1; 2; 3)

Floating-point values: kommagetallen (1,5345; 3,4)

Floating-point values worden meestal gebruikt bij coördinaten, of andere coördinaten gerelateerde zaken, als bijvoorbeeld snelheid.

Voor de overige dingen worden vaak Integer Values gebruikt. Het voordeel aan Integer Values gebruiken, is dat de computer er makkelijk mee kan rekenen. Deze worden bijvoorbeeld gebruikt om wachttijden in te stellen. Maar ook als identificatie getallen voor bepaalde objecten, en om sprongen binnen het script te berekenen.

De IV en FPV mogen niet door elkaar gebruikt worden, het script werkt dan niet. Bij coördinaten is het dan ook handig om gewoon altijd Floating-point values te gebruiken. Om een voorbeeld te geven, als je bij een coördinaat 100.0 in wilt vullen, en je tikt 100, dan slaat hij de waarde 100 als integer op. Later als het script in het spel draait, wordt dat door een commando als floating-point value gezien, en komt er iets heel anders uit (geen 100.0, wat de bedoeling was).

0004: $3412 = 5000 ;; integer values

0084: $3413 = $3412 ;; integer values and handles

Het verschil is dat de eerste een waarde toekent aan een globale variable, in dit geval de waarde 5000, aan de globale variabele $3412. Dus hier staat in feiten: $3413 = $3412 = 5000, al mag je dit zo nooit in main.scm schrijven, daarin moet je hem opsplitsen.

Variabelen

Er zijn twee soorten variabelen: globale en lokale variabelen. Globale worden aangegeven met een $ ervoor (bijvoorbeeld $boe), lokale met een @ erachter (2@). Let op: een lokale variabele bestaat uit alleen maar cijfers, een globale mag nooit uit alleen maar cijfers staan. Daar wordt de code heel instabiel van, en soms werkt het gewoon niet (ook al doet Rockstar het zelf ook wel eens). Het verschil tussen globale en lokale variabelen is eigenljk vrij simpel: een globale variabele gebruik je in heel het script. Dus als je $boe gelijk stelt aan 5, dan is $boe overal 5 (tenzij je het weer veranderd). Lokale variabele daarentegen, gelden allee binnen één thread. Als je 1@ in een bepaalde thread aanmaakt, en vervolgens hetzelfde getal in een andere thread wilt gebruiken, dan moet je aan 1@ opnieuw een waarde toekennen. De waarde uit de andere thread geldt niet meer.

Rekenen met variabelen

In het SCM scripten moet je ook wel rekenen met variabelen. Hier zijn een aantal opcodes voor. Let op, hier kán je verschillen hebben in integer-values en floating-point-values, of verschil in globale en lokale variabelen. Je kunt optellen, aftrekken, vermenigvuldigen en delen. Daarnaast kan je iets gelijk stellen aan iets anders. Hieronder staan een aantal voorbeelden:

0008: $variabele += 1

Hierbij wordt de globale variabele vermeerderd met 1.

000A: 3@ += 3000

Deze opcode doet in feiten hetzelfde als hierboven, maar dan een lokale variabele. Zoals je ziet is er toch een verschil in opcode, de een is 0008, de andere is 000A.

000B: 6@ += 0.1

Misschien zie je zelf al wel wat het verschil is met hierboven. Dit is een floating-point-value, die hierboven is een integer value.

0009: $variabele += 1.741

Vrijwel dezelfde als de bovenste, maar ook dit keer is het een floating-point-value en geen integer.

Dit zijn alleen de opcodes voor het vermeerderen van een variabele. Zo heb je ze ook met delen, vermenigvuldigen en aftrekken. Ook kan je variabelen bij andere variabelen tellen, bijvoorbeeld:

 0058: $1924 += $1929 // (int)

Stel dat $1924 de waarde 5 heeft, en $1929 de waarde 3. Dan heeft $1924 vanaf deze opcode de waarde 8 (5 + 3).

 0038:   $672 == 1

Dit is een code waarmee je checkt of de variabele gelijk is aan 1. Dit is dus niet de variabele gelijkstellen.

 0004: $var = 0

Dit is wél de variabele gelijkstellen aan 0.

Dit was de basistutorial van SCM-scripten. Mochten jullie nog vragen hebben, dan weten jullie wel waar je die kunt plaatsen!

Geplaatst:

Actors

Inleiding

Er zijn 2 soorten actors: de 'gewone' actors, en de 'special' actors. De gewone actors zijn over het algemeen de standaard voetgangers, maar ook bijvoorbeeld de overheids-actors (zoals de politie) vallen hieronder. De special actors zijn, zoals de naam al zegt, speciaal. Ze lopen niet rond. Voorbeelden van special actors zijn Sweet en Catalina. De gewone actors zijn vrij eenvoudig te maken, ze worden ongeveer hetzelfde geladen als een gewoon model (wapens bijvoorbeeld). Bij de zogenaamde special actors is het wat lastiger, maar hier komen we later op terug. Eerst gaan we de gewone actors_modellen laden (en controleren of hij geladen is), spawnen, en vervolgens natuurlijk ook weer unloaden.

We beginnen in de "stripped" code, dat is een code die helemaal clean is. Je kunt dus niets doen, alleen wat rondlopen en autorijden. Dit is natuurlijk ideaal voor een nieuwe mod. Een actor is niets anders als een karakter in het spel, op welke manier dan ook (dus bijvoorbeeld Sweet, maar ook de pedestrians).

Allereerst moet je het principe kennen. Je moet een model van de actor (actor_model) laden, vervolgens kijken of hij geladen is (zo niet, wachten tot hij wél geladen is), daarna de actor spawnen en tot slot het model weer unloaden.

Normale actors

Een actor laden en kijken of hij geladen is

Eerst gaan we dus de actor loaden:

// Load models
0247: load_model #BFYST
038B: load_requested_models

Achter // schrijf je een notitie, die // zorgt ervoor dat het systeem deze regel overslaat en er niet naar kijkt. Dit is dus alleen maar als verduidelijking voor de modder zelf. De regel "Load_model" daar geef je aan welk model je hebt. In deze tutorial is er gekozen voor het model BFYST, maar daar zijn allemaal andere voor te gebruiken. De derde regel zorgt ervoor dat het model echt geladen wordt.

Vervolgens moet je er, zoals gezegd, voor zorgen dat het model ook echt geladen is:

:MODEL_LOAD
00D6: if 
8248:   not model #BFYST available 
004D: jump_if_false @MODEL_SPAWN 
0001: wait 0 ms 
0002: jump @MODEL_LOAD 

:MODEL_SPAWN

Met deze code kijk je dus of het model geladen is, zo niet, dan begint hij opnieuw. Je begint met het aanmaken van een nieuw label. Het maakt natuurlijk niet uit of hoe je die label noemt, maar een duidelijke naam maakt het later makkelijker om je labels terug te vinden. In deze tutorial heet het label MODEL_LOAD.

Om het vervolg uit te leggen moet je eerst weten wat een if-structuur is. If betekend als/indien. Dus if ... jump @ MODEL_LOAD, betekend indien ... gebeurd, spring dan naar het label :MODEL_LOAD. In deze contekst betekend het dus: indien (regel 2) het model BFYST niet beschikbaar is (regel 3), spring dan naar het label MODEL_LOAD (regel 5).

Er zit nog een regel tussen, namelijk "jump_if_false @MODEL_SPAWN". De “jump_if_false" zorgt ervoor dat op het moment dat de if niet waar is (in dit geval dus dat het model wel geladen is), er naar een ander label (MODEL_SPAWN) gesprongen wordt.

Zo hebben we dus al 2 van de 4 dingen gedaan. Nu gaan we het model laten spawnen: de actor staat.

Actor Spawnen

:MODEL_SPAWN
10@ = Actor.Create(CIVFEMALE, #BFYST, 0.0, 0.0, 0.0)
Actor.Angle(10@) = 318.9705

De "10@" is een lokale variabele, het maakt dus niet uit welk getal je neemt. Het moet echter wel onder de 33 zijn, want dat is het maximum binnen een thread (bij missies kunnen er meer zijn). Dan ga je die variabele definiëren. Actor.Create lijkt me duidelijk... Dan tussen haakjes, zie je 5 dingen die je in moet vullen. Allereerst het type ped, in mijn geval is het CIVFEMALE. Dan de naam van de ped weer, met een # ervoor (dus #BFYST). Vervolgens de 3 coördinaten: x, y en z. De Actor.Angle is de hoek waarin de ped staat. Het westen is 0.0. Wil je hem naar het oosten hebben staan, moet je de Angle dus 180.0 hebben.

Unload model

Tot slot moet je ook in je code nog verwerken dat je het model unload:

0249: release_model #BFYST

Volledige code

Dus de volledige code is:

// Load models
0247: load_model #BFYST
038B: load_requested_models

:MODEL_LOAD
00D6: if 
8248:   not model #BFYST available 
004D: jump_if_false @MODEL_SPAWN 
0001: wait 0 ms 
0002: jump @MODEL_LOAD 

:MODEL_SPAWN
10@ = Actor.Create(CIVFEMALE, #BFYST, 0.0, 0.0, 0.0)

//Hier komt wat je met je actor wilt doen

0249: release_model #BFYST

Met de Ped Editor kan je opzoeken welke ped je wilt hebben. Je ziet zo gelijk een beeld van de ped ingame, je ziet de naam van de ped én je ziet de groep, kortom: alles wat je nodig hebt staat erin. De coördinaten kan je opzoeken via de San Andreas Place Manager. Je kunt ook in Sanny Builder zelf kijken welke coördinaten je op dat moment ingame hebt, door naar "tools" te gaan, dan naar IDE tools en tot slot op "Coords manager".

Special actors

Special actors zijn iets moeilijker. Je hebt namelijk maar 10 slotjes voor special actors. Het is te vergelijken met de 8 slotjes waarin je je savegame zet: je kunt er altijd maar 8 tegelijk bewaren, en op het moment dat je andere savegames wilt hebben moet je er verwijderen om vervolgens die te kunnen plaatsen. Zo werkt het ook met de special actors. Een lijst met alle actors die tot de special actors behoren, kan je vinden bij de SCM Documentatie bank van Sanny Builder. Ga naar Help >> Contents >> SCM Documentation >> GTA SA >> Special Actors.

Als je het principe van de special actors snapt, is het eigenlijk zo moeilijk niet meer en lijkt het wel op een gewone actor (maar met een iets andere code). Opnieuw moet je goed onthouden: model loaden, checken of model geladen is, actor spawnen, model unloaden.

Special Actor laden

We pakken als voorbeeld Catalina. Je ziet in de lijst uit de documentatie bank dat zij de naam 'CAT' in de code heeft. Laten we het model eerst maar gaan laden:

// Load models
023C: load_special_actor 'CAT' as 1 // models 290-299
038B: load_requested_models

De special actor Catalina laden. "as 1" betekend in slotje 1, dus kan je naast deze nog 9 anderen loaden.

Vervolgens moeten we natuurlijk weer checken of hij geladen is:

:MODEL_LOAD
00D6: if or 
823D:   not special_actor 1 loaded 
004D: jump_if_false @MODEL_SPAWN 
0001: wait 0 ms 
0002: jump @MODEL_LOAD 

:MODEL_SPAWN

Dit is dus bijna hetzelfde als die van de "normale" actor, dus veel uitleg is niet nodig. Alleen is het nu "not_special_actor 1 loaded" in plaats van "not model #BFYST available". In principe betekend het hetzelfde, wanneer het model voor de actor of special actor niet geladen is, jump dan naar het label MODEL_LOAD. De 1 staat in dit geval voor het nummer van het slotje.

Spawn Special Actor

:MODEL_SPAWN
009A: 10@ = create_actor_pedtype 4 model #SPECIAL01 at 0.0 0.0 0.0
0173: set_actor 10@ Z_angle_to 0.0

Je gebruikt #SPECIAL01 als naam voor degene die slotje 1 heeft. 4 is het pedtype. De angle is de hoek hoe hij moet staan, 0.0 is het westen.

Unload Special Actor

Tot slot ook nog unloaden natuurlijk:

0296: unload_special_actor 1

Dus weer het unloaden van het model van de special actor die in slotje 1 staat.

Volledige code

// Load models
023C: load_special_actor 'CAT' as 1 // models 290-299
038B: load_requested_models  

:MODEL_LOAD
00D6: if or 
823D:   not special_actor 1 loaded 
004D: jump_if_false @MODEL_SPAWN 
0001: wait 0 ms 
0002: jump @MODEL_LOAD 

:MODEL_SPAWN
009A: 10@ = create_actor_pedtype 4 model #SPECIAL01 at 0.0 0.0 0.0
0173: set_actor 10@ Z_angle_to 0.0

// Hier komt te staan wat je met de actor wilt doen

0296: unload_special_actor 1

Script voor het spawnen van een normale actor in een gestripte scm

Je kunt de actor vele dingen laten doen, zoals bijvoorbeeld in de auto laten stappen of naar jou laten schieten. Maar eerst moeten ze gespawnt zijn, voordat je die dingen kunt gaan toevoegen. Daarom is het essentieel om dit eerst te weten. Ik hoop dat jullie wat geleerd hebben van deze tutorial, en als er vragen zijn schroom dan niet om ze te stellen. ;)

Geplaatst:

Wapens aan Actors geven

Inleiding

Je kunt de actor vele dingen laten doen, zoals bijvoorbeeld in de auto laten stappen of naar jou laten schieten. Maar eerst moeten ze gespawnd zijn, voordat je die dingen kunt gaan toevoegen. Daarom is het essentieel om dit eerst te weten.

In dit tweede deel van de tutorial gaan we de code waarmee me in deel 1 gestopt zijn iets verder uitbreiden. We geven de actor een wapen en stellen wat eigenschappen in. De speler krijgt ook een wapen. Om het enigszins leuk te maken moeten de speler en de actor elkaar vermoorden. Als je de actor vermoordt krijg je een muziekje, een "mission passed"-tekst en 25.000 dollar.

Wapens

Om een wapen aan een actor te geven, moet je eerst het wapen-model laden. Net zoals je in deel 1 het actor-model van een actor moest laden voordat je het kunt spawnen. Gelukkig is het laden van een wapen model identiek aan het laden van een actor-model. voor het laden van het actor model hadden we de volgende code

 // Load models
0247: load_model #BFYST
038B: load_requested_models

:MODEL_LOAD
00D6: if
8248:   not model #BFYST available
004D: jump_if_false @MODEL_SPAWN
0001: wait 0 ms
0002: jump @MODEL_LOAD

:MODEL_SPAWN  

Dit stuk code gaan we uitbreiden voor het laden van de modellen van 3 wapens: De desert_eagle, de rocket-launcher en de m4. In de help-files van sannybuilder zoeken we de juiste namen op: Help->SCM Documentation->GTA SA->Weapon numbers

We zoeken daar de wapennummers en de modelnamen van de wapens die we willen gebruiken:

    desert-eagle 24 #DESERT_EAGLE
   rocket-launcher 35 #ROCKETLA
   M4 31 #M4 

We breiden nu de bovenstaande code uit met de modelnamen van deze wapens, op deze manier:

 // Load models
0247: load_model #BFYST
0247: load_model #rocketla
0247: load_model #desert_eagle 
0247: load_model #m4 
038B: load_requested_models

:MODEL_LOAD
00D6: if or
8248:   not model #BFYST available
8248:   not model #rocketla available 
8248:   not model #desert_eagle available 
8248:   not model #m4 available 
004D: jump_if_false @MODEL_SPAWN
0001: wait 0 ms
0002: jump @MODEL_LOAD

:MODEL_SPAWN

Naast het actor model wordt nu dus ook het laden van de wapen modellen aangevraagd. En we wachten daaronder net zolang, tot alle 4 modellen geladen zijn.

Nu gaan we de wapens uitdelen. Om te beginnen geven we de speler een rocket-launcher en een desert_eagle

 01B2: give_actor $PLAYER_ACTOR weapon 35 ammo 10 // Load the weapon model before using this
01B2: give_actor $PLAYER_ACTOR weapon 24 ammo 30000 // Load the weapon model before using this
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 24

Hier komen de wapennummers om de hoek kijken die we hierboven opgezocht hebben.

We geven de speler een rocket-launcher (35) met 10 raketten en een desert-eagle(24) met 30.000 kogels. De speler heeft nu twee wapens, maar omdat hij er maar 1 tegelijk kan gebruiken moeten we er ook nog 1 in zijn handen stoppen en dat doen we met het onderste commando.

De speler is bewapend, nu de actor nog.

 01B2: give_actor 10@ weapon 31 ammo 30000 // Load the weapon model before using this
01B9: set_actor 10@ armed_weapon_to 31

De actor krijgt dus een m4 (31) met 30.000 kogels, en die geven we hem ook direct in de handen.

Eigenschappen

Nu hebben we dus een bewapende speler en een bewapende actor. Om wat leven in de brouwerij te krijgen geven de actor de opdracht om de speler te doden. Om het iets moeilijker te maken stellen we nog een paar eigenschappen in.

 05E2: AS_actor 10@ kill_actor $PLAYER_ACTOR

Deze code zorgt dat zij de speler probeert te doden.

 actor.WeaponAccuracy(10@)= 90

Deze code zorgt dat zij nauwkeuriger kan richten met z'n wapen dan normaal.

 actor.Health(10@) = 2000

Deze code zorgt zij een extra hoog health nivo heeft, dus niet zo snel dood is.

 0350: toggle_actor 10@ maintain_position_when_attacked 1

Deze code zorgt dat zij niet bang wegloopt als hij wordt aangevallen.

Mini-missie

Alles staat klaar voor een vechtpartij. Nu moeten we dus wachten hoe het afloopt. Mocht de speler geraakt worden, dan spawned ie vanzelf opnieuw bij het ziekenhuis, en kan hij opnieuw gaan vechten (hoewel hij geen wapens meer heeft). Het is dus eigenlijk wachten op het moment dat de actor gedood wordt.

Dat doen we met de volgende code

 repeat
 wait 0 ms 
until actor.Dead(10@)

We wachten dus net zolang tot de actor dood is.

Beloning

Daarna geven we een melding en voor de aardigheid een beloning

 0394: play_music 1 
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1  // MISSION PASSED!~n~~w~$~1~
Player.Money($PLAYER_CHAR) += 25000

De eerste regel speelt een overwinningsmuziekje terwijl de tweede regel op het scherm meld dat de missie gelukt is. Als beloning geeft de derde regel de speler een som van 25000 dollar.

Het enige dat we hierna nog moeten doen is het unloaden van de models die we gebruikt hebben. Dit gaat op dezelfde manier als met de actor model, dus

 0249: release_model #BFYST
0249: release_model #rocketla
0249: release_model #desert_eagle
0249: release_model #m4

Alles samen in een gestripte scm.

  • 2 maanden later...
Geplaatst:

Cars spawnen

Inleiding

Deze tutorial gaat over een wezenlijk deel van het spel: auto’s. Je hebt auto’s op verschillende manieren: een auto die eenmalig spawnt of auto’s die blijven spawnen. Beiden zal ik in deze tutorial gaan behandelen.

Auto’s die blijven spawnen

Je zou het misschien niet zeggen, maar de auto’s die blijven spawnen zijn makkelijker te maken als de auto’s die eenmalig gespawnt worden. Dit komt omdat het een zogenaamde ‘cargenerator’ is. Je hoeft ze dan niet van tevoren te laden en na afloop te unloaden, omdat dat allemaal achter de schermen voorkomt en hardcoded is. Op deze manier worden dus de auto’s gespawnt die een vaste vindplaats hebben.

De regel voor de cargenerator is:

 014B: $PARKED_RHINO = init_parked_car_generator #RHINO -1 -1 1 alarm 0 door_lock 0 0 10000 at 2435.302 -1671.848 12.8007 angle 90.0 
014C: set_parked_car_generator $PARKED_RHINO cars_to_generate_to 0

Eerst de eerste regel.

  • $PARKED_RHINO is een variabele, de naam van de code.
  • Het is een RHINO, wat er staat #RHINO.
  • Hij is geparkeerd op de coördinaten “2435.302 -1671.848 12.8007”.
  • Hij staat onder een hoek (angle) van 90 graden, dat betekend dus het oosten.

Tot zover was het nog makkelijk in de regel af te lezen. Na #RHINO staan nog een aantal parameters die ik stuk voor stuk uit zal leggen.


  • De eerste -1 is de eerste kleur van het voertuig.
  • De tweede -1 is de tweede kleur van het voertuig.
  • De derde, de 1, is of de politie denkt dat het jouw auto is of niet. Is het 1, zoals hier, dan denkt de politie dat het de jouwe is. Is het een 0, dan denkt de politie dat jij hem gejat hebt en krijg je een wanted level als ze je zien.
  • Alarm 0 betekent dat er geen alarm op zit. Het getal dat je invult, is de percentuele kans dat het alarm af gaat. Dus 100 is altijd, 0 is nooit. 50 is 1 op de twee keer, 75 is 1 op de drie keer etc.
  • Door_lock 0 betekent dat de auto open is, als je daar 1 weg zet, is de auto op slot.
  • De twee andere parameters, in dit geval 0 en 10000, zijn onbekend (men heeft (nog) niet uitgevonden wat het doet).

De tweede regel betekend: spawnen, ja of nee? Bij 101 spawnt hij, bij 0 niet. Dit lijkt niet zo belangrijk, maar je moet deze tweede regel er altijd bij hebben. Overigens staat de ‘naam’ in de eerste regel, en die moet je toevoegen in de tweede regel. In het voorbeeld hierboven dus $PARKED_RHINO.

Voorbeeld in een gestripte scm.

Een car generator hoeft niet per se in een aparte thread, het is ook mogelijk om hem bovenaan erbij te plaatsen (net boven de idle loop).

Er is ook nog een variant, waarmee je het nummerbord kunt wijzigen:

09E2: $2765 = parked_car_generator_w_numberplate #GREENWOO 59 34 0 alarm 0 door_lock 0 0 10000 plate "GROVE4L_" at $138 $139 $140 angle $141 
014C: set_parked_car_generator $2765 cars_to_generate_to 101

Je maakt er "parked_car_generator_w_numberplate" van (with numberplate), en je voegt "Plate "..." " toe. Dan heb je dus een auto die spawnt mét nummerbord.

Auto’s die eenmalig spawnen

Dit gaat weer ongeveer op dezelfde manier als het spawnen van actors.

//Load models
0247: load_model #GREENWOO 
038B: load_requested_models 

:MODEL_LOAD
00D6: if  
8248:   not model #GREENWOO available 
004D: jump_if_false @MODEL_SPAWN
0001: wait 0 ms 
0002: jump @MODEL_LOAD

Als je de andere tuts hebt gelezen, lijkt me hier geen bij uitleg nodig. ;)

:MODEL_SPAWN
$greenwood = Car.Create(#GREENWOO, 2458.2483, -1659.0264, 13.3047)
Car.Angle($greenwood)= 270.0

Hier spawn je dus de greenwood.


  • De naam van het model is GREENWOO, daarvoor uiteraard altijd een #.
  • Daarachter komen de coordinaten.
  • De tweede regel is weer voor de Angle (hoek).

 0249: release_model #GREENWOO

En hier weer om te releasen.

Eigenschappen eenmalig spawnende auto

Natuurlijk zijn er allerlei leuke codes voor een eenmalig spawnende auto. Hier volgen een paar voorbeelden:

0674: set_car_model #GREENWOO numberplate "ABCDEFG"

Zo kan je dus een speciaal nummerbord instellen van een auto.

  0119:   car $greenwood wrecked

Hiermee kun je dus vragen of je auto kapot is of niet (vaak met een if-structuur erbij). Bij de $ moet je de naam van de gespawnde auto geven.

 0224: set_car $greenwood health_to 10000

Hoe hoger je het getal maakt (10000), hoe meer schade de auto kan incasseren. Hier kan je natuurlijk leuk mee variëren. De Greenwood met 500 is hij bijvoorbeeld hevig aan het roken (nog wel wit), met 250 is hij ook aan het roken, zelfs zwart, en is 1 botsing genoeg om te ontploffen. Lager als 249 hoef je niets te doen, dan ontploft hij al uit zichzelf. 1000 is een reëel getal voor een auto. De $greenwood is natuurlijk weer de naam van de auto, gedefinieerd bij het spawnen.

 01E8: create_forbidden_for_cars_cube_cornerA 2500.0 -1677.0 20.0 cornerB 2430.0 -1653.0 0.0

 01E7: remove_forbidden_for_cars_cube_cornerA 2272.922 -1649.556 14.3311 cornerB 2266.101 -1633.219 14.3505

Dit zijn de codes voor aanmaken en verwijderen van gebieden die je autoloos wilt hebben. Er rijden daar dus geen auto’s rond. Is handig als je bijvoorbeeld mensen moet vermoorden die een goed wapen hebben. Anders heb je immers een probleem dat de speler gewoon een auto kan pakken en daardoor vrijwel geen last heeft van het wapen van de actor.

Je hebt een corner A en een corner B. De coordinaten invullen is wat lastiger. Je moet dus de x en y coordinaat van de ene hoek nemen en de x en y coordinaat van de andere hoek. Dus:

A  

        B

Vervolgens moet je de Y coordinaat bepalen. De ene moet hoog zijn, de andere laag: zo krijg je een kubus. Maakt dus niet uit welke van de twee hoog is en welke laag. Advies is om gewoon heel hoog en heel laag te doen, zodat het niet uit maakt waar je gaat staan in die kubus. Bijvoorbeeld 0.0 en 20, of misschien zelfs hoger.

Natuurlijk zijn er nog veel en veel meer commando’s die met cars te maken hebben, omdat het natuurlijk een heel wezenlijk onderdeel is in het spel. Mocht je dus nog requests hebben omdat je niet weet hoe je het moet doen, dan kan je het altijd vragen in het reactietopic!

Geplaatst:

Spheres, icons en markers

Allereerst: wat zijn Spheres en markers? Met icons worden de tekentjes bedoeld op de radar linksonder in beeld en markers zijn pijltjes boven hoofden van actors en/of boven auto’s. Met spheres worden de rode rondjes bedoeld, die je bijvoorbeeld krijgt als je een missie voor een persoon moet doen of als je bijna klaar bent met je missie en dingen moet doen.

Hoe creëer je een sphere/icon?

Je kunt met 1 commando zowel een icon als een sphere creëren, je kunt ook alleen een sphere of alleen een icon creëren. Je hebt ook icons die je altijd ziet, en icons die je alleen ziet wanneer je in de buurt bent. Ik zal ze allemaal uitleggen.

Sphere

 03BC: 10@ = create_sphere_at 2488.5601 -1666.84 13.38 radius 5.0

Dit is de code voor alleen een sphere. De 10@ is hier de naam van de sphere (die kan je later gebruiken als je wat met de sphere gaat doen). Vervolgens zijn er de x, y en z-coordinaat en tot slot ook radius. Dat betekend de doorsnede van de sphere. Die kan je dus klein maken (1.0), maar ook vrij groot (5.0) of heel groot (10.0). 1.0 is ongeveer het formaat van een sphere wanneer je in een missie bent.

Icon en Sphere die je altijd ziet

 02A7: $ICON_SPHERE_CJ = create_icon_marker_and_sphere $ICON_CJ at $X_JOHNSON_HOUSE $Y_JOHNSON_HOUSE $Z_JOHNSON_HOUSE

Altijd is niet helemaal waar, wanneer in je in een missie zit, zie je ze niet. Maar voor de rest zie je ze altijd. Markers én spheres.

    [*]De $ICON_CJ is niets minder als gewoon het getal wat bij de icon van CJ hoort. Die kan je opzoeken in de help-files van Sannybuilder.

    [*]$X_JOHNSON_HOUSE, $Y_JOHNSON_HOUSE en $Z_JOHNSON_HOUSE, zijn de variabelen die eerder gedefinieerd zijn (als getallen dus). Is ook wel logisch, aangezien de coördinaten van het Johnson House natuurlijk vaak in het spel voorkomen, en dan hoeven ze niet iedere keer de coördinaten op te schrijven maar gewoon zo’n makkelijk herkenbare variabele.

    [*]$ICON_SPHERE_CJ is de naam, waar je dus op terug kunt vallen (bijvoorbeeld voor het verwijderen van die markers).

    Icon (zonder sphere) die je altijd ziet

 02A8: $marker03 = create_marker 23 at 658.0068 -1866.3127 4.4537

Dit is een code voor een icon marker zonder sphere. Met andere woorden, je ziet die links onderin op de radar, maar je ziet niet een rood rondje als je er bent. Eerst dus weer de naam, in dit geval $MARKER_EMMETS_GUN, daarna het commando (dus dat je een icon marker wilt, maar geen sphere). De 18 betekend het soort tekentje. Welke je wilt kan je vinden in sannybuilder >> help >> contents >> SCM Documentation >> SA >> Radar Icons. 18 is het pistooltje van Emmet (eigenlijk ook logisch, gezien de naam van deze regel). Je kunt daar dus al die nummers invullen die je in die lijst ziet. Vervolgens de coördinaten, en je hebt het op je radar staan.

Icon en Sphere die je alleen ziet als je dichtbij bent

 0570: $icon_en_sphere  = create_asset_radar_marker_with_icon 36 at 1837.3643 -1974.4963 12.5469

Zoals je ziet zijn er maar 2 dingen veranderd. Het getal van de opcode is nu 0570 (eerst 02A7), en het commando is ook net even anders. Maar het idee is hetzelfde, de 36 is het getal van de icon die je kunt opzoeken in de lijst en daarna ook nog de coördinaten.

Icon die je alleen ziet als je dichtbij bent

 04CE: $icon = create_icon_marker_without_sphere 12 at 2447.3643 -1974.4963 12.5469

Ik denk dat het nu al wel voor zich spreekt, maar ik wilde hem er toch bijzetten.

Markers

Markers zijn pijlen die je boven een object, actor of auto plaatst. Je ziet dan tegelijkertijd een vierkantje op je radar (die hoef je er niet zelf bij te voegen dus). Er zijn natuurlijk ook markers in allerlei soorten en maten. Daarvoor gebruik je de volgende codes:

 0187: $m1 = create_marker_above_actor 10@  
0186: $m2 = create_marker_above_car $greenwood
03DC: $m3 = create_marker_above_pickup $wapen
0188: $m4 = create_marker_above_object $object

De eerste is dus om een marker te plaatsen boven een actor, de tweede boven een auto, de derde boven een pick up en de vierde boven een object. Spreekt eigenlijk voor zich, als je de codes bekijkt.

Het zijn echter wel verschillende opcodes en verschillende commando’s. Wat achter de eerste $ staat, is de naam van deze regel. Wat achter de tweede $ staat, is de naam van de auto/actor/object/pickup, die je eerder (tijdens het spawnen) al gedefinieerd hebt.

Met die marker kan je natuurlijk ook allerlei dingen doen, zoals bijvoorbeeld het vierkantje op de radar kleiner (of groter) maken. Die ga ik nu niet allemaal uitleggen, want het is niet zo van belang. Alleen het kleuren maken wil ik nog wel even uitleggen, omdat dat wel leuk is in een mod. Mocht er iemand zijn die graag heeft dat ik wat extra details geeft, moet die dat even zeggen. ;)

Er zijn verschillende kleuren. Je kunt elke marker dus een kleur geven. Dat kan je door een andere regel toe te voegen:

 0165: set_marker $m1 color_to 1

Een lijstje met kleuren: 0= red 1= green 2= light blue 3= white 4= light yellow

Destroy

Uiteindelijk moet je alles ook nog destroyen, zodat de marker/sphere/icon er niet meer is. Dat doe je als volgt:

 0164: disable_marker $m1

of (Sannybuilder manier):

 Marker.Disable($m1)

Voorbeeld

De pijl op de greenwood uit de vorige tutorial, geeft als code:

 //Load models
0247: load_model #GREENWOO 
038B: load_requested_models 

:MODEL_LOAD
00D6: if  
8248:   not model #GREENWOO available 
004D: jump_if_false @MODEL_SPAWN                                              
0001: wait 0 ms 
0002: jump @MODEL_LOAD

:MODEL_SPAWN
00A5: $greenwood = create_car #GREENWOO at 2458.2483 -1659.0264 13.3047 
Car.Angle($greenwood)= 270.0
0186: $m1 = create_marker_above_car $greenwood
wait 5000 ms
Marker.Disable($m1)

0249: release_model #GREENWOO

Hier spawnt dus een Greenwood, met daarop een pijl. Na 5000 ms (5 seconden) verdwijnt de pijl.

Complete code in een stripped file.

Werkende sphere

Nou hebben we een sphere, maar houdt er rekening mee dat dat alleen nog maar de sphere is. Er gebeurt dus niets als je in de sphere gaat staan, ook niet als je daarachter code hebt geschreven. Dan moet je de volgende code toevoegen:

00EC:   actor $PLAYER_ACTOR 0 near_point $c1 $c2 radius 1.0 1.0

Hier zegt hij dus dat de PLAYER_ACTOR (in dit geval de variablee voor de speler zelf) in de buurt is van de coordinaten $c1 (x) en $c2 (y), met een radius van 1.0.

Voor als je in een auto erin moet gaan staan:

00EE:   actor $PLAYER_ACTOR 0 near_point 2067.4 -1831.2 radius 15.0 15.0 in_car

Werkt hetzelfde, let wel op dat het een andere opcode is en dus niet alleen in_car erachter schrijven!

Je kunt ook een specifieke auto erin laten staan, en dat doe je zo:

01AE:   car $greenwood sphere 0 near_point -2614.6282 1398.4735 radius 5.0 5.0 stopped

Het spreekt allemaal voor zich, maar de code is altijd net even anders.

Met deze tutorials zou je al een missie kunnen maken, en dat zullen we dan ook maar gaan doen in de volgende tutorial!

  • 2 maanden later...
Geplaatst:

Een eenvoudige missie

Zoals beloofd gaan we nu beginnen met een echte missie te maken. Allereerst moet je een goed plan hebben voor de missie. In ons voorbeeld gaan we een auto laten spawnen met pijl erboven, als je instapt gaat de pijl weg en komt er een sphere waar je heen moet rijden. Op dit moment heeft de speler een baseball bat. De auto is al ver kapot, en bij de lichtste aanraking (zelfs met een lantaarnpaal) ontploft hij. Als men in de marker is, moet er een actor spawnen met een baseball bat. Deze moet je aanvallen zodra hij je ziet. Als de actor gekilled is, is de missie passed, krijg je een bericht dat de missie gehaald is en krijg je $10000 bij. Ook verdwijnt de marker dan.

Natuurlijk is dit niet een hele moeilijke missie, en zou je hem later nog wat kunnen opleuken. Bijvoorbeeld door een tijd toe te voegen als je rijdt: zo moet je snel rijden en kan je niet gewoon rustig rijden en zo schade voorkomen. Of bijvoorbeeld als je uitstapt, dat je dan weer een marker krijgt op de auto. Of dat mission failed is als je dood bent, want nu moet je gewoon van het Los Santos ziekenhuis gaan naar de plek waar je gebleven bent (met de gevolgen daarvan). Hoe dan ook, je moet klein beginnen, en dat gaan we dus ook doen met deze missie.

Het scripten

Nu we het idee hebben, gaan we scripten. We beginnen zoals gebruikelijk met de stripped file. Deze kan je vinden in de map van Sanny Builder (meestal in Program Files) > Data > SA > Stripped.txt. Open deze in Sanny Builder.

Vervolgens gaan we eerst maar alles laden en kijken of het geladen is. De actor moet nog niet gespawnt worden, de auto wel. De bat moeten we zometeen geven aan de speler, later pas aan de actor. Hier het loaden van de models en het spawnen van de auto (en de instellingen van de auto) .

 :MODEL
thread 'MODEL'
//Load models
0247: load_model #GREENWOO
0247: load_model #bat
0247: load_model #BFYST
038B: load_requested_models 

:MODEL_LOAD
00D6: if or 
8248:   not model #GREENWOO available
8248:   not model #bat available
8248:   not model #BFYST available
004D: jump_if_false @MODEL_SPAWN                                              
wait 0 ms 
jump @MODEL_LOAD

:MODEL_SPAWN
0674: set_car_model #GREENWOO numberplate "ABCDEFG" 
00A5: $greenwood = create_car #GREENWOO at 2458.2483 -1659.0264 13.3047 
Car.Angle($greenwood)= 270.0
0224: set_car $greenwood health_to 250

Vervolgens gaan we kijken, wat missen we nog voordat we gaan rijden? Dat is dat de speler een baseball bat krijgt, en natuurlijk ook de marker boven de auto:

 0186: $m1 = create_marker_above_car $greenwood
01B2: give_actor $PLAYER_ACTOR weapon 5 ammo 10 // Load the weapon model before using this
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 5

Ok, we zijn nu zo ver dat we in de auto kunnen gaan stappen. Stel, we zitten in de auto. Wat moet er dan gebeuren? Je moet naar de volgende plek gaan. Dus nadat we in de auto zitten, moet de marker van de auto weg, de icon geplaatst worden en de sphere gemaakt worden. Dat doe je als volgt:

 repeat
wait 0
until Actor.InCar($PLAYER_ACTOR, $greenwood)
Marker.Disable($m1)

0004: $coordinaat_x = 2100.9604
0004: $coordinaat_y = -1366.8369
0004: $coordinaat_z = 23.9844 

$coordinaat = Marker.CreateIconAndSphere(0, $coordinaat_x, $coordinaat_y, $coordinaat_z)

Wat hebben we nou, we hebben een speler die in de auto zit en naar de marker toe moet rijden. Wat kan er onderweg gebeuren? De auto kan kapot gaan, wat willen we dan dat er gebeurt? Dan moet er een nieuwe auto gespawnd worden aan het begin en moet je teruggaan. Deze check moet maar doorgaan tot de auto de sphere heeft bereikt. Dit is misschien een lastigere code om te maken, maar als je er goed naar kijkt is het eigenlijk wel logisch en kan je het de volgende keer zelf ook!

 :MODEL_WRECKED
wait 0 ms                                        
if     
  0119:   car $greenwood wrecked               
  004D: jump_if_false @MODEL_END                                 
wait 0 ms                                              
jump @MODEL

:MODEL_END
if
 01AE:   car $greenwood sphere 0 near_point $coordinaat_x $coordinaat_y radius 5.0 5.0 stopped 
 004D: jump_if_false @MODEL_WRECKED
wait 0 ms

Hier staat: Wanneer de auto kopot is, spring naar @MODEL. Dan begin je dus weer helemaal opnieuw. Wanneer dit niet het geval is (jump_if_false), spring dan naar MODEL END, de label eronder. Probleem is dat je nu nog niet klaar bent, want je moet die check niet één keer uitvoeren, maar heel vaak. In het begin is hij immers nog niet kapot, maar dat kan gebeuren tot aan de sphere, en dat betekend dus dat deze code herhaalt moet blijven worden.

Dus wanneer de auto (aangegeven met car $greenwood, zodat er per se in die auto gezeten moet worden) in de buurt is van de sphere (radius 5.0), dan mag hij door. Zo niet? Dan springt hij terug naar MODEL_WRECKED en komt er eerst een controle of hij kapot is. Dit gaat zo door, totdat de Greenwood in de buurt van de sphere is.

Nu moet de sphere en marker verdwijnen. Dan wil je de actor spawnen, die je aanvalt.

 10@ = Actor.Create(CIVFEMALE, #BFYST, 2094.3499, -1342.9515, 23.9844)
Marker.Disable($coordinaat)
Actor.Angle(10@) = 88.44
0187: $marker = create_marker_above_actor 10@ 
actor.WeaponAccuracy(10@)= 100
actor.Health(10@) = 250
01B2: give_actor 10@ weapon 5 ammo 1000 // Load the weapon model before using this
01B9: set_actor 10@ armed_weapon_to 5
05E2: AS_actor 10@ kill_actor $PLAYER_ACTOR

Alle codes die in dit stukje code voorkomen, zijn in de vorige tutorials al uitgelegd.

Tot slot wil je dat de actor dood gaat, en dan is de missie gehaald. Liedje afspelen, tekst op het scherm, geld erbij, de marker op de actor destroyen en ook de models destroyen:

 repeat
wait 0 ms
until actor.Dead(10@)

0394: play_music 1
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1 // MISSION PASSED!~n~~w~$~1~
Player.Money($PLAYER_CHAR) += 10000
0249: release_model #GREENWOO
0249: release_model #BAT
0249: release_model #BFYST
Marker.Disable($marker)

Ook hier staat niets nieuws. Misschien het "Repeat until", dat betekend niets anders als wachten tot (in dit geval) de actor dood is.

Tot slot zet je nog een end_thread en dan ben je klaar.

 end_thread

Alles bij elkaar krijg je het volgende. En probeer maar: het is een missie. Misschien niet een al te moeilijke missie, maar who cares? Je moet tenslotte klein beginnen :Y.

Code in een stripped file.

Zo zien jullie, met eenvoudige codes kan je toch al een aardige missie maken. Maar het probleem is bij veel modders ook niet de kunst van het modden, maar de creativiteit…

  • 1 year later...
Geplaatst:

Een complete missie ( Rockstar Style )

In deze nogal lange tutorial gaan we uitleggen hoe je een echte missie maakt, zoals Rockstar ze ook bouwt, dus niet als een simpele thread, zoals in de voorgaande tutorials.

Om te beginnen zullen we de structuur en de bijzonderheden op een rijtje zetten, daarna zullen we templates geven voor de verschillende delen, en deze uitleggen, en tenslotte zullen we een missie laten zien die op basis van deze templates zijn gemaakt.

Structuur

Missies zoals ze door rockstar zijn gemaakt, en zoals we ze nu ook gaan maken, wijken qua gedrag af van normale threads die je normaal gebruikt. Ten eerste wordt de code voor een missie pas vanaf de schijf in het geheugen geladen, wanneer de missie gestart wordt. Dit heeft tot gevolg dat er slechts 1 missie tegelijk actief kan zijn. Een ander heel groot verschil is de manier hoe de code zich gedraagt waneer de speler BUSTED of WASTED is.

In een normale thread moet je hier steeds op checken (is_payer_defined), maar tijdens een missie hoeft dat niet. Als de speler tijdens een missie WASTED of BUSTED wordt, voert de SCM-engine, namelijk op dat moment automatisch een "return"-opcode uit. Je hoeft dus tijdens de missie zelf niet steeds te controleren of de speler nog leeft, maar je moet wel het standaard framework van een Rockstar missie gebruiken, om die automatische "return"-opcode op te vangen. Dit framework zal verderop uitgelegd wordt bij de missie-template.

Om een missie te maken heb je twee delen nodig:

  1. De missie zelf
  2. Een zogenaamde "sniffer"-thread, die de startvoorwaarden van een missie checked en controleert of de speler de start van een missie triggert ( door b.v. op een bepaalde plek in een marker te lopen).

Voor beide delen zullen we een template geven, die je voor je eigen project moet invullen en evt. uitbreiden.

Sniffer-thread template

De sniffer-thread wordt gestart, zodra de missies gedaan kunnen worden. Dit kan direct vanaf de start van het spel zijn, of op het moment dat je een andere missie gehaalt hebt. Deze template bevat de code voor een sniffer-thread voor twee missies, maar dit kun je vrij eenvoudig uitbreiden tot veel meer missies die na elkaar gedaan kunnen worden.

// $TUT_MISSIONS_PASSED wordt vooraf op 0 gezet.
// bij het "PASS"-en van een missie , moet je $TUT_MISSIONS_PASSED ophogen.
:TUT_MISSIONS_SNIFFER
thread "TUT_SNIFF"
$MARKER_SWEET_HOUSE = Marker.CreateIconAndSphere(42, <<xcoord>>, <<ycoord>>, <<zcoord>>)
repeat
 wait $DEFAULT_WAIT_TIME 
 if and
   player.Defined($PLAYER_CHAR)
   $ONMISSION == 0 
 then
   if and
     00FF:   actor $PLAYER_ACTOR sphere 0 in_sphere <<xcoord>>, <<ycoord>>, <<zcoord>> radius 1.0 1.0 2.0 on_foot 
     Player.Controllable($PLAYER_CHAR)
     $TUT_MISSIONS_PASSED == 0
   then
     $ONMISSION = 1
     00BA: show_text_styled GXT 'INTRO_1' time 1000 style 2  
    start_mission 1  
   end

   if and
     00FF:   actor $PLAYER_ACTOR sphere 0 in_sphere <<xcoord>>, <<ycoord>>, <<zcoord>> radius 1.0 1.0 2.0 on_foot 
     Player.Controllable($PLAYER_CHAR)
     $TUT_MISSIONS_PASSED == 1
   then
     $ONMISSION = 1
     00BA: show_text_styled GXT 'INTRO_2' time 1000 style 2  
    start_mission 2  
   end
 end 
until $TUT_MISSIONS_PASSED == 2
marker.Disable($MARKER_SWEET_HOUSE)
end_thread 

Globaal gesproken, zet deze thread een marker op de goede plek waar de missions gestart kunnen worden en wacht dan in een lus tot de speler in de marker loopt, of dat beide missies gepassed zijn.

Zolang $TUT_MISSIONS_PASSED op 0 staat, is er nog geen van de twee tutorial missies gepassed, en zal de eerste missie gestart worden, als de speler in de marker loopt (de eerste tak van de lus).

Nadat de speler de eerste missie gehaald heeft, (waarbij de $TUT_MISSIONS_PASSED is opgehoogd naar 1), zal de snifferthread opnieuw wachten tot de speler in de marker loopt (de tweede tak van de lus).

Na het succesvol afronden van de tweede missie, zal de $TUT_MISSIONS_PASSED op 2 staan, waarna de lus wordt verlaten, de marker wordt opgeruimd, en de thread wordt beëindigd.

Mission template

//-------------Mission 1---------------
// Mission wrapper
:TUT_MISSION_1
thread 'TUT 1' 
gosub @TUT_MISSION_1_MAIN 
if wasted_or_busted 
then 
 gosub @TUT_MISSION_1_FAIL 
end
gosub @TUT_MISSION_1_CLEANUP 
end_thread 

//-------------------------------------
:TUT_MISSION_1_MAIN


//-------------------------------------
:TUT_MISSION_1_PASSED
Player.Money($PLAYER_CHAR) += 10000
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1 // MISSION PASSED!~n~~w~$~1~
// This subroutine is executed when the mission is passed. 
// Give the rewards, and make new missions available if needed.

return

//-------------------------------------
:TUT_MISSION_1_FAIL
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1  // ~r~MISSION FAILED!
// This subroutine is executed when the mission fails. 
return 

//-------------------------------------
:TUT_MISSION_1_CLEANUP
$ONMISSION = 0 
// This subroutine is always executed at the end of the mission, regardless the outcome.
// This is the place to unload models etc. 
mission_cleanup 
return 

Het eerste stukje, van deze code is de missie-wrapper, die de verschillende delen van de missie aanroept met behulp van "gosub", om zo de automatische "return" bij het WASTED of BUSTED van de speler ook opvangt.

Als eerste roept hij het hoofdgedeelte van de missie aan. Als die terug komt, kunnen er twee dingen zijn gebeurt:

  1. Een automatische "return, omdat de speler WASTED of BUSTED is. In dat geval wordt de mission failed nog aangeroepen. en daarna de "cleanup" routine, die alles opruimt.
  2. De missie is PASSED of FAILED om een andere reden. In dat geval in de mission_passed of mission_failed routine al aangeroepen, en hoeft alleen de "cleanup" nog gedaan te worden.

In het complete voorbeeld hieronder zul je zien, hoe je vanuit het hoofddeel, de mission_passed en mission_failed routines aanroept bij bepaalde gebeurtenissen.

Voorbeeld missie

Op basis van bovenstaande templates hebben we hieronder een simpele missie gemaakt. Naast de templates uit deze tutorials, worden ook verschillende dingen uit voorgaande tutorials gebruikt.

De bedoeling van deze missie, die je kunt starten, voor het huis van Sweet, is om een andere actor dood te schieten. Er staan echter twee actors, een mannetje en een vrouwtje. Het is de bedoeling om het vrouwtjes dood te schieten, dan is de missie passed. Als je echter het mannetje doodschiet, dan is de missie failed.

Als de speler WASTED of BUSTED is, voor dat het vrouwtje is doodgeschoten, is de missie ook failed.

DEFINE MISSIONS 2
DEFINE MISSION 0 AT @INITIAL
DEFINE MISSION 1 AT @TUT_MISSION_1
DEFINE EXTERNAL_SCRIPTS 0 // Use -1 in order not to compile AAA script
//DEFINE SCRIPT {NAME}  AT {LABEL} @
DEFINE UNKNOWN_EMPTY_SEGMENT 0
DEFINE UNKNOWN_THREADS_MEMORY 0

{$VERSION 3.0.0000}
var
$PLAYER_CHAR: Player
end // var 
03A4: name_thread 'MAIN' 
01F0: set_max_wanted_level_to 6 
0111: toggle_wasted_busted_check 0 
00C0: set_current_time_hours_to 8 minutes_to 0 
04E4: unknown_refresh_game_renderer_at 2488.56 -1666.84 
03CB: set_rendering_origin_at 2488.56 -1666.84 13.38 
0053: $PLAYER_CHAR = create_player #NULL at 2488.56 -1666.84 13.38 
01F5: $PLAYER_ACTOR = create_player_actor $PLAYER_CHAR 
07AF: $PLAYER_GROUP = player $PLAYER_CHAR group 
0373: set_camera_directly_behind_player 
01B6: set_weather 0 
0001: wait 0 ms 
087B: set_player $PLAYER_CHAR clothes_texture "PLAYER_FACE" model "HEAD" body_part 1 
087B: set_player $PLAYER_CHAR clothes_texture "JEANSDENIM" model "JEANS" body_part 2 
087B: set_player $PLAYER_CHAR clothes_texture "SNEAKERBINCBLK" model "SNEAKER" body_part 3 
087B: set_player $PLAYER_CHAR clothes_texture "VEST" model "VEST" body_part 0 
070D: rebuild_player $PLAYER_CHAR 
01B4: toggle_player $PLAYER_CHAR can_move 1 
016A: fade 1 time 0 
04BB: select_interior 0 
0629: change_integer_stat 181 to 4 
016C: restart_if_wasted_at 2027.77 -1420.52 15.99 angle 137.0 town_number 0 
016D: restart_if_busted_at 1550.68 -1675.49 14.51 angle 90.0 town_number 0 
0180: set_on_mission_flag_to $ONMISSION // Note: your missions have to use the variable defined here 
0004: $DEFAULT_WAIT_TIME = 250
03E6: remove_text_box 
0417: start_mission 0  // Initial 
wait 0
// put your create_thread commands here
00D7: create_thread @TUT_MISSIONS_SNIFFER 

:MAIN_LOOP
0001: wait $DEFAULT_WAIT_TIME ms
0002: jump @MAIN_LOOP 



// put your mods (threads) here
:TUT_MISSIONS_SNIFFER
thread "TUT_SNIFF"
$MARKER_SWEET_HOUSE = Marker.CreateIconAndSphere(42, $X_SWEET_HOUSE, $Y_SWEET_HOUSE, $Z_SWEET_HOUSE)
repeat
 wait $DEFAULT_WAIT_TIME 
 if and
   player.Defined($PLAYER_CHAR)
   $ONMISSION == 0 
 then
   if and
     00FF:   actor $PLAYER_ACTOR sphere 0 in_sphere $X_SWEET_HOUSE $Y_SWEET_HOUSE $Z_SWEET_HOUSE radius 1.0 1.0 2.0 on_foot 
     Player.Controllable($PLAYER_CHAR)
     $TUT_MISSIONS_PASSED == 0
   then
     $ONMISSION = 1
     00BA: show_text_styled GXT 'INTRO_1' time 1000 style 2  // Big Smoke
    start_mission 1  
   end


 end 
until $TUT_MISSIONS_PASSED == 1
marker.Disable($MARKER_SWEET_HOUSE)
end_thread 

//-------------Mission 0---------------
:INITIAL
$TUT_MISSIONS_PASSED = 0
$ONMISSION = 0

$X_SWEET_HOUSE = 2515.07 
$Y_SWEET_HOUSE = -1673.98 
$Z_SWEET_HOUSE = 12.71 
0629: change_integer_stat 225 to 999 

end_thread

//-------------Mission 1---------------
// Mission wrapper
:TUT_MISSION_1
thread 'TUT 1' 
 gosub @TUT_MISSION_1_MAIN 
 if wasted_or_busted 
 then 
   gosub @TUT_MISSION_1_FAIL 
 end
 gosub @TUT_MISSION_1_CLEANUP 
end_thread 

//-------------------------------------
:TUT_MISSION_1_MAIN
//Load models
model.Load(#m4)
model.Load(#BFYST)
model.Load(#BMYST)
model.Load(#TAMPA)

038B: load_requested_models 

:TUT_MISSION_1_LOAD
wait 0 ms 
if and 
 model.Available(#m4)
 model.Available(#BMYST)
 model.Available(#BFYST)
 model.Available(#TAMPA)
004D: jump_if_false @TUT_MISSION_1_LOAD 

01B2: give_actor $PLAYER_ACTOR weapon 31 ammo 10000 // Load the weapon model before using this
01B9: set_actor $PLAYER_ACTOR armed_weapon_to 31

0674: set_car_model #TAMPA numberplate "PATRICK_" 
$car_num = car.Create(#TAMPA,2488.56, -1666.84, 13.38)


$victim = Actor.Create(CIVFEMALE, #BFYST, 2488.56, -1656.84, 13.38)
$innocent = Actor.Create(CIVMALE, #BMYST, 2490.56, -1656.84, 13.38)
0187: $victim_marker = create_marker_above_actor $victim 

repeat
 wait 0 ms
 if actor.Dead($innocent)
 then
   jump @TUT_MISSION_1_FAIL
 end
until actor.Dead($victim)

:TUT_MISSION_1_PASSED
0394: play_music 1
$TUT_MISSIONS_PASSED += 1
Player.Money($PLAYER_CHAR) += 10000
01E3: show_text_1number_styled GXT 'M_PASS' number 10000 time 5000 style 1 // MISSION PASSED!~n~~w~$~1~
return

//-------------------------------------
:TUT_MISSION_1_FAIL
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1  // ~r~MISSION FAILED!
// Hier kun je alles kwijt wat moet gebeuren als de missie gefaald is. Bv. bepaalde dingen weer terugdraaien
0555: remove_weapon 31 from_actor $PLAYER_ACTOR 
return 

//-------------------------------------
:TUT_MISSION_1_CLEANUP
$ONMISSION = 0 
// Hier komt alle code om  dingen op te ruimen die voor de missie zijn geladen
// En om speciale settings voor deze missie terug te zetten naar normaal 
Marker.Disable($victim_marker)
010D: set_player $PLAYER_CHAR wanted_level_to 0 
model.Destroy(#BFYST)
model.Destroy(#BMYST)
model.Destroy(#M4)
mission_cleanup 
return 



//-------------External script 0---------------
// put your external scripts here

Het eerste deel van de code, is een standaard stuk dat iedereen wel zal kennen van de stripped SCM file.

Het enige dat daaraan is toegevoegd, is het starten van de snifferthread:

00D7: create_thread @TUT_MISSIONS_SNIFFER

En ten slotte laten we de main-thread rondjes draaien in :MAIN_LOOP

Daarna volgt de sniffer-thread. Gebasseerd op de template, maar beperkt tot maar 1 missie.

Je ziet dat we twee missies hebben gedefineerd, de eerste (Missie 0) gebruiken we net als rockstar voor het initialiseren van allerlei dingen. Hier zou je ook car_generators, en b.v. wapen pickups kunnen plaatsen. Wij zetten hier de $TUT_MISSIONS_PASSED op 0, en plaatsen de locatie van de mission trigger in 3 variabelen, zodat we ze makkelijk kunnen gebruiken op verschillende plekken.

De tweede missie (Missie1) is volgens de template opgezet. In het main deel worden eerst de modellen geladen, actors gespawned, wapens toegekend en een auto gespawned, zoals we in voorgaande tutorials al gezien hebben. Daarna wacht de code in een lus, totdat de $VICTIM wordt doodgeschoten, in dat geval loopt de code door in de mission_passed routine en is de missie dus afgelopen. Tijdens de lus wordt ook gechecked of het onschuldige mannetje nog leeft. Is dat niet meer het geval, dan springen we naar de mission_failed routine, en is de missie ook afgelopen.

In de mission passed routine, zetten we een boodschap op het scherm, geven we de speler het beloning-bedrag en hogen de $TUT_MISSIONS_PASSED op.

In de mission failed routine zetten we de boodschap op het scherm, en pakken de speler het wapen af dat hij gekregen heeft.

In de cleanup routine, ruimen we alle gebruikte modellen op en zetten het wanted-level terug op 0.

We hebben de templates en de voorbeeld missie ook als bijlage toegevoegd, zodat je ze makkelijk kunt downloaden.

missie_template.txt

missie_sniffer_template.txt

tut_missie.txt

Geplaatst:

Status Balken

Deze tutorial gaat over Status Texten, ofwel de balkjes die je bijvoorbeeld tegenkomt bij de missie "Drive-by" en de missie "Supply Lines". Op aanvraag van Tjerk, onze dank daarvoor.

 :SWEET4_47
Model.Load(#GREENWOO)
038B: load_requested_models 

:SWEET4_103
if
   not Model.Available(#GREENWOO)
else_jump @SWEET4_152 
wait 0 
jump @SWEET4_103 

:SWEET4_152
1@ = 2508.16
2@ = -1666.47 
3@ = 13.0
4@ = 16.0 
0395: clear_area 1 at 1@ 2@ 3@ range 6.0 
5@ = Car.Create(#GREENWOO, 1@, 2@, 3@)
0229: set_car 5@ color_to 59 34 
Car.Angle(5@) = 4@
Car.Health(5@) = 1450
$6674 = Car.Health(5@)

Dit is gewoon het spawnen van een voertuig, de Greenwood. Daarnaast wordt de variabele $6674 aangemaakt, dat betekent de car health van de Greenwood.

Ik zal eerst even het principe uitleggen. Het balkje gaat van 0 tot 100, gemeten in percentages. Je hebt de car health van de Greenwood op 1450 staan. Onder de 250 gaat de auto branden en ontploffen. Als je dus zegt dat 250 de 0 is van het balkje, dan is de 1450: 1200 (1450 - 250 = 1200). Aangezien je maar van 0 tot 100 mag hebben, moet je dat getal dus delen door 12. Dat gaan we nu eerst laten zien.

 0084: $6673 = $6674 // integer values and handles
if
  $6673 > 250 // integer values
else_jump @SWEET4_11472
$6673 -= 250 // integer values

:SWEET4_11472
$6673 /= 12 // integer values

Voor je bij $6674 250 af gaat trekken, moet je eerst kijken of hij boen de 250 is. Anders kom je in een negatief getal en dat kan het balkje dus niet aan. Dus als het getal onder de 250 ligt moet je alvast verder gaan bij het volgende label (door de jump), als het getal boven de 250 ligt moet je er 250 vanaf halen.

Vervolgens stel je de variabele $6673 gelijk aan de variabele $6674 (de car health - 250 dus). Dat getal deel je door 12. Zo heb je dus in plaats van een getal tussen 250 en 1450, een getal tussen 0 en 100. In verhouding hetzelfde, maar zo kan je dus instellen voor dat balkje.

 0151: remove_status_text $6673 
03C4: set_status_text_to $6673 1 'SWE4_08'  // CAR HEALTH

Dit is de code van "het balkje". Je ziet niet "car health" staan, aangezien de thread niet overeenkomt met het deel uit de GXT wat aangeroepen wordt.

Je kunt de 1 ook veranderen in een 0, dan is het niet meer een balkje, maar een getal. Dan begin je dus met 100 en dan eindig je met 0 en alle waardes daar tussenin.

 repeat
wait 0 ms
$6674 = Car.Health(5@)

0084: $6673 = $6674 // integer values and handles 
if 
  $6673 > 250 // integer values 
else_jump @SWEET4_11472 
$6673 -= 250 // integer values   

:SWEET4_11472
$6673 /= 12 // integer values

until  $6674 < 250

0151: remove_status_text $6673

end_thread

Wat we hier maken is dat je het balkje ziet tot de auto kapot is (balkje verdwijnt als de variabele op 0 komt dus).

Dit is een repeat-wait-until structuur. Hij moet dus alles herhalen vanaf repeat, totdat $6674 kleiner is als 250 (dan is $6673 0 dus). Waarom hebben we nou nog een stuk erin gekopieerd? Omdat hij in de repeat, telkens moet checken of de car health veranderd, dat telkens gelijk moet stellen aan $6673, van $6673 telkens 250 af moet trekken, en $6673 telkens weer moet delen. Anders blijft hij natuurlijk op hetzelfde getal staan, en zal het balkje nooit aflopen.

Je wacht dus tot $6674 (de car health) onder de 250 komt. Dan ontploft de auto namelijk. Dan laat je het balkje met de code "0151: remove_status_text $6673" verdwijnen. Tot slot nog een end_thread, zodat het spel niet crasht en verder gaat met de main thread.

Alles in een stripped SCM file, dus dat je een auto ziet en dat het balkje loopt tot hij kapot gaat, zie je hieronder. Tip: gooi dit even in SannyBuilder om te kijken hoe het er werkelijk uit ziet, zodat je je het beter voor kunt stellen.

Code in een stript scm.

Hopelijk is het een beetje duidelijk, reactie en/of vragen kan je altijd in het reactietopic kwijt.

Geplaatst:

Actor Animations en Animation Paths

Inleiding

Je kunt allerlei soorten animaties aan actors meegeven, gewoon om je missie wat leuker te maken. Je moet twee dingen weten over animaties: de naam van de animatie en de naam van de IFP-file waarin de animatie zich bevindt. Je kunt hier een lijst daarvan vinden. De grote vetgedrukte woorden zijn de namen van de IFP-files, daarna zullen de animatie namen binnen die IFP-file volgen. Bijvoorbeeld, wanneer je wilt dat een actor danst, moet je kijken in de lijst naar de IFP-file "DANCING". Die file bevat allerlei soorten animaties, in deze tutorial zullen we "dnce_M_a" gebruiken. Natuurlijk kan je een actor ook andere animaties geven, maar ik beloof niet dat ze allemaal zullen werken.

Animatie geven

Allereerst moeten we een actor creëren, die de animatie moet doen. Wanneer je de andere tutorials in dit topic gelezen heb, heb je geen uitleg hierbij nodig. Als je het niet snapt, ga dan terug naar de tutorial over actors.

0247: load_model #BFYST
038B: load_requested_models

:MODEL_LOAD
if
8248:   not model #BFYST available
else_jump @MODEL_SPAWN
wait 0 ms
jump @MODEL_LOAD

:MODEL_SPAWN
10@ = Actor.Create(CIVFEMALE, #BFYST, 2491.3635, -1661.4694, 13.3359)
Actor.Angle(10@) =  182.9651

0249: release_model #BFYST

Allereerst moeten we de IFP file laden, daarna moeten we checken of de animatie geladen is. Pas daarna kan je een actor een animatie geven. Dit kan je doen met de volgende opcodes:

04ED: load_animation "DANCING"

repeat
wait 0
until 04EE:   animation "DANCING" loaded 

0605: actor 10@ perform_animation_sequence "DNCE_M_A" IFP_file "DANCING" 10.0 loop 1 0 0 0 time -1 // versionA 

Soms hoef je geen animatie te laden, maar ik moet eerlijk bekennen dat ik niet precies weet wanneer. Ik heb veel scripts met bugs gezien omdat ze de animatie niet laadde, dus mijn advies is om gewoon altijd te laden. Liever een paar regels maar, dan een script met bugs!

Opcode 0605 is precies dezelfde opcode als 0A1A en 0812. Het maatk dus niet uit welke opcode je kiest. Ik zal alleen het belangrijkste deel van de code uitleggen. Voel je vrij om te experimenteren met de andere parameters.

Allereerst moet je zeggen welke actor je een animatie wil geven, dat is in ons geval dus 10@ (welke we net gemaakt hebben). De eerste "integer" nummer, de enige "1" in de code hierboven, geeft aan hoe vaal de animatie zichzelf moet herhalen. Wanneer je het 0 maakt, zal de animatie slechts één keer spelen. Wanneer je 1 maakt, zal het zich herhalen.

Na "time" zie je "-1". Dit betekent dat de actor de animatie doet, tot er een opcode komt die zegt dat hij moet stoppen. Je kunt dit wijzigen in 4000, dat betekent dat de animatie voor 4 seconden doorgaat.

Er is ook een variant op deze opcode:

0829: actor 10@ perform_animation "DNCE_M_A" IFP_file "DANCING" 4.0 time 4000 and_dies 

Een beejte stom als je het mij vraagt, maar je kunt het proberen. Nadat de actor de animatie voor 4 seconden heeft gedaan, zal hij doodgaan. Maar het is niet zoals je zou verwachten, de actor bevriest alleen. Er zal bloed op de grond liggen, maar de actor staat nog steeds, bevroeren. Je kunt er doorheen lopen en zal alleen vallen als je hem schopt. Wel grappig om te zien...

0804: AS_actor 10@ walk_to 2498.1187 -1671.9563 13.3427 angle 0.0 radius 0.2 animation "GRLFRD_KISS_03" IFP_file "BD_FIRE" 4.0 LA 0 LX 0 LY 0 LF 0 LT -1 
0804: AS_actor 10@ walk_to 2498.1187 -1671.9563 13.3427 angle 0.0 radius 0.2 animation "DNCE_M_A" IFP_file "DANCING" 4.0 LA 0 LX 0 LY 0 LF 0 LT -1 

Twee voorbeelden van één opcode, je kunt het proberen om het resultaat te zien (je kunt het kopiëren naar de code aan het einde van deze tutorial, als je het moeilijk vind om dit in een nieuwe stripped file te zetten. De actor loopt vanaf coördinatie die jij hebt opgegeven en zal daarna een animatie doen. In de eerste zal de actor naar een punt lopen en een kus geven. Aan niemand, in dit geval, maar je kunt een actor ernaast zetten. De tweede zal de actor laten dansen wanneer hij op een locatie aan komt.

0611:   actor 2@ performing_animation "LRGIRL_IDLE_TO_L0" 
8611:   not actor 2@ performing_animation "LRGIRL_BDBNCE" 

Deze opcode is een conditie, dus je moet het gebruiken in (bijvoorbeeld) een if-structuur. Het kan handig zijn als je wilt checken of een animatie reeds gestopt is (of dat de actor nog niet klaar is). Hieronder een voorbeeld van een code die wacht tot de animatie gestopt is:

0605: actor 10@ perform_animation_sequence "DNCE_M_A" IFP_file "DANCING" 10.0 loop 1 0 0 0 time 3000 // versionA 
repeat
 wait 0
until 8611:   not actor 10@ performing_animation "DNCE_M_A" 

Weer een andere opcode voor een animatie:

0612: set_actor 10@ animation "DNCE_M_A" paused 1 

Met deze code kan je een animatie laten pauzeren. 1 betekent dat hij begint, 0 betekent dat hij pauzeert. Als voorbeeld zullen we een actor met een animatie maken, die na 1 seconde stopt (voor 1 seconde), en daarna weer door gaat.

0605: actor 10@ perform_animation_sequence "DNCE_M_A" IFP_file "DANCING" 10.0 loop 1 0 0 0 time -1
wait 1000
0612: set_actor 10@ animation "DNCE_M_A" paused 0 
wait 1000
0612: set_actor 10@ animation "DNCE_M_A" paused 1

0605: actor 10@ perform_animation_sequence "DNCE_M_A" IFP_file "DANCING" 10.0 loop 1 0 0 0 time -1
wait 3000
0614: set_actor 10@ animation "DNCE_M_A" progress_to 0.5 // 0.0 to 1.0 

0614 is een andere opcode. Je kunt de animatie splitsen. De gehele animatie is 1.0, het start op 0.0. Dus je kunt zeggen: ik wil dat de actor een animatie voor 3 seconden doet, en dan moet hij beginnen vanaf 0.5. Natuurlijk kan je ook weer opnieuw laten beginnen, dan moet je 0.0 gebruiken.

Release animatie

Natuurlijk moet je hem unloaden nadat je hem gebruikt hebt:

04EF: release_animation "DANCING"

Animation Paths

0754: define_new_animation_path 
0755: add_animation_path_3D_coord 2496.5234 -1671.363 13.3359 animation "ROADCROSS" IFP_file "PED" 
0755: add_animation_path_3D_coord 2499.4873 -1661.1962 13.3587 animation "ROADCROSS" IFP_file "PED" 
0755: add_animation_path_3D_coord 2490.1294 -1661.246 13.3359 animation "ROADCROSS" IFP_file "PED"

Allereerst moet je de animation path definieren. Je begint met "define new animation path". Daarna moet je daar coördinaten aan toevoegen. In dit voorbeeld zullen we drie coördinaten toevoegen. De animatie en de IFP-file is precies hetzelfde als die van de animaties eerder in deze tutorial genoemd. Je kunt ook "NONE" in plaats van "ROADCROSS" en "PED" gebruiken, maar dan doet hij geen animatie. De animatie zal worden gedaan op dat coördinaat, dus niet gedurende de tijd dat hij naar dat coördinaat toe loopt.

Daarna moet je een actor toevoegen aan het animation path:

0817: assign_actor 10@ to_animation_path_with_walk_mode 4 route_mode 3 

Je kunt makkelijk met deze opcode experimenteren: The route-mode:

0-normal order of waypoints, once (ABCD)

1-normal order of waypoints and reverse, once (ABCDCBA)

2-normal order of waypoints plus reversed, looped (ABCDDCBAABCD...)

3-normal order of waypoints, looped (ABCDABCDABCD...)

(Bron: dit topic)

Stript file met een actor die een animatie doet.

Tot zover deze tutorial, ik hoop dat je het begreep. Voor vragen en opmerkingen; zie reactietopic.

Geplaatst:

Pickups

Wat mist er nu echt in deze tutorial? Inderdaad, een tutorial over pickups. Daar gaat deze tutorial dus over.

Algemene Pickups

0213: $HEALTH = create_pickup #HEALTH type 3 at 2490.5598 -1658.3495 13.3528

Dit is de opcode voor het creëren van een pickup. Allereerst de "handle", zodat je daar later eigenschappen (zoals een marker) aan kunt geven. Daarna moet je een model opgeven voor de pickups:

  • Health: #HEALTH
  • Armor: #BODYARMOUR
  • Bribe: #BRIBE
  • Info: #INFO
  • Keycard: #KEYCARD
  • Save pickup: #PICKUPSAVE
  • Rhymesbook: #RMB_RHYMESBOOK
  • Briefcase: #BRIEFCASE
  • Clothes: #CLOTHESP
  • Jetpack: #JETPACK
  • Parachute Pack: #PARA_PACK
  • Parachute: #PARACHUTE

Na "type", moet je aangeven of hij "nooit beschikbaar" (1), "één keer beschikbaar" (3) of "meerdere keren beschikbaar" (15) is. Er zijn meerdere types, maar deze zijn de meest voorkomende. Wanneer je een volledige lijst met types wil hebben, kan je op URL=http://www.gtamodding.com/index.php?title=Pickup]deze pagina[/url] kijken. In dit geval kan je de HEALTH pickup dus maar één keer oppakken. De laatste drie parameters zijn de coördinaten.

Weapon Pickups

0213: $BAT = create_pickup #BAT type 3 at 2490.5598 -1658.3495 13.3528

Deze opcode, dezelfde als de opcode hierboven, kunnen ook worden gebruik voor wapens. Maar je kunt ze geen ammo geven, dus meestal kan je het alleen voor melee wapens gebruiken. Wanneer je een andere wapen pickup wil hebben, zoals een minigun, dan zal er een standaard waarde aan ammo worden gegeven. Voor een minigun is dat 500, voor een rocket launcher is dat slechts 4. Je kunt er dus wel alle wapen pickups mee maken, maar het is gebruikelijker om de volgende te gebruiken:

032B: $M4 = create_weapon_pickup #M4 group 15 ammo 150 at 2490.5598 -1658.3495 13.3528 

Bijna dezelfde als 0213, maar nu kan je het ammo geven. Dus deze opcode spawnt een M4 meerdere keren, met een ammo van 150 op plaats 2490.5598 -1658.3495 13.3528.

Money Pickups

Het is ook mogelijk om een geld pickup te maken, met behulp van de volgende opcode:

02E1: $MONEY = create_cash_pickup 500 at 2490.5598 -1658.3495 13.3528 permanence_flag 1

$MONEY is natuurlijk de "handle". 500 is het bedrag aan geld dat de player krijgt iedere keer dat hij het geld oppakt. Daarna staan de coördinates. Wanneer de flag 1 is, is het geld permanent. Het zal niet verdwijnen totdat de player het pakt. Wanneer de flag 0 is, zal het na 30 seconden verdwijnen.

Asset Pickups

Er zijn twee soorten asset pickups: beschikbare en niet-beschikbare assets. De beschikbare assets kunnen worden gekocht door de speler, de niet-beschikbare (nog) niet.

0517: $asset = create_unavailable_asset_pickup 'PROP_4' at 2490.5598 -1658.3495 13.3528  
0518: $asset2 = create_available_asset_pickup 'PROP_3' at 2489.5598 -1658.3495 13.3528  price 1

De eerste zorgt voor een niet-beschikbare asset. Wanneer de speler dichtbij is, zal de text "PROP_4" worden getoond ("You cannot buy this property yet).

De tweede is de beschikbare asset. Achter "price" kan je de prijs van de asset invullen.

Collectables Pickups

Je kunt een Horseshoe, een Photo Opportunity of een Oyster plaatsen met de volgende opcodes. Ik heb een wapen pickup voor de camera geplaatst, anders kan je de Photo Opportunity niet zien wanneer je ingame checkt.

032B: $camera = create_weapon_pickup #CAMERA 15 ammo 50 at 2488.5598 -1663.3495 13.3528  
0959: $horse = create_horseshoe_at 2490.5598 -1658.3495 13.3528
0958: $photo = create_photo_at 2489.5598 -1658.3495 13.3528
095A: $oyster = create_oyster_at 2488.5598 -1658.3495 13.3528 

Andere opcodes met betrekking tot pickups pickups

0213: $BAT = create_pickup #BAT type 3 at 2490.5598 -1658.3495 13.3528
03DC: 1@ = create_marker_above_pickup $BAT 

Met deze opcode creëer je een marker boven de pickup, net zoals we bij eerdere tutorials hebben gedaan.

0214:   pickup $BAT picked_up 
8214:   not pickup $BAT picked_up

Deze opcodes zijn condities. Je kunt deze gebruiken om te controleren of de speler een pickup heeft opgepakt. Bijvoorbeeld:

0213: $BAT = create_pickup #BAT type 3 at 2490.5598 -1658.3495 13.3528
repeat
wait 0
until 0214:   pickup $BAT picked_up 

Soms wil je misschien een pickup laten verdwijnen. Dit kan je als volgt doen:

0213: $BAT = create_pickup #BAT type 3 at 2490.5598 -1658.3495 13.3528
wait 2000
0215: destroy_pickup $BAT

Door deze code zal een pickup worden gecreërd, en na 2 seconden verdwijnen.

Een klein script...

Eerst spawnen we drie pickups: een asset voor 100 dollar, een health pickup en een minigun wapen pickup. Boven de minigun pickup maken we een marker. Wanneer de speler de minigun heeft opgepakt, moet de marker verdwijnen en een actor spawnen. De actor heeft ook een minigun, en we zullen haar health en accuracy aanpassen. De actor zal proberen om de speler te vermoorden en de speler moet de actor vermoorden. Wanneer de speler de actor vermoord, krijgt hij 100 dollar, en kan hij de asset kopen. Daarna zullen we een text laten verschijnen.

Allereerst gaan we drie pickups spawnen evenals een marker boven de minigun:

0518: $ASSET = create_available_asset_pickup 'PROP_3' at 2487.5598 -1658.3495 13.3528  price 100
0213: $HEALTH = create_pickup #HEALTH type 3 at 2484.5598 -1658.3495 13.3528
032B: $MINIGUN = create_weapon_pickup #MINIGUN group 15 ammo 5000 at 2490.5598 -1658.3495 13.3528 
03DC: 1@ = create_marker_above_pickup $MINIGUN

Nu moeten we wachten tot de speler de minigun heeft opgepakt. Daarna moet de marker verdwijnen en de actor worden gecreërd (met wat eigenschappen):

repeat
wait 0
until 0214:   pickup $MINIGUN picked_up

0164: disable_marker 1@

0247: load_model #BFYST
0247: load_model #MINIGUN
038B: load_requested_models

:MODEL_LOAD
if and
8248:   not model #BFYST available
8248:   not model #MINIGUN available
else_jump @MODEL_SPAWN
wait 0 ms
jump @MODEL_LOAD

:MODEL_SPAWN
10@ = Actor.Create(CIVFEMALE, #BFYST, 2488.5601, -1680.84, 13.3438 )
01B2: give_actor 10@ weapon 38 ammo 500 // Load the weapon model before using this 
02E2: set_actor 10@ weapon_accuracy_to 90 
0223: set_actor 10@ health_to 1000 

De actor moet de speler aanvallen. Daarna moet de code wachten tot de speler de actor vermoord heeft. Als een beloning krijgt de speler 100 dollar.

05E2: AS_actor 10@ kill_actor $PLAYER_ACTOR

repeat
wait 100
until 0118:   actor 10@ dead 

0109: player $PLAYER_CHAR money += 100

Tot slot moet er een tekst komen wanneer de asset is opgepakt.

repeat
wait 100
until 0214:   pickup $ASSET picked_up

00BC: show_text_highpriority GXT 'MCAT07E' time 3000 flag 1

Complete code in een stripped file.

Geplaatst:

Teksten

Deze tutorial gaat over teksten ingame. Er zijn allerlei soorten teksten: groot, klein, vetgedrukt, gekleurd...

Display Teksten

00BA: show_text_styled GXT 'BEEFY' time 3000 style 1

Je moet de naam van de GXT entry tussen de ' ' plaatsen. Achter tijd moet je aangeven hoe lang de tekst in beeld moet zijn. Er zijn 7 stijlen die je achter style in kunt vullen:

  • 1: In het midden, zoals wanneer je een missie gehaald hebt of wanneer je een race gewonnen hebt.
  • 2: Rechts onderin, zoals wanneer je een missie start.
  • 3: Witte tekst in het midden, net zoals wasted of busted.
  • 4: Stijl 1, maar dan kleiner.
  • 5: Zelfde als stijl 4, maar dan hoger in beeld.
  • 6: Kleine witte tekst in het midden van het scherm.
  • 7: Lichtblauwe tekst bovenin het scherm.

Pas op: 0 is geen stijl, en daardoor zal de game crashen!

Je kunt een witte tekst aan de onderkant van het scherm in beeld laten komen door de andere opcodes te gebruiken. Er is een verschil tussen highpriority en lowpriority opcodes. De highpriority zal de lowpriority vervangen. Bijvoorbeeld:

00BB: show_text_lowpriority GXT 'IE23' time 3000 flag 1 
wait 1000
00BC: show_text_highpriority GXT 'MTIME3' time 3000 flag 1

Met deze code zal eerst 'IE23' in beeld komen, maar na 1 seconden (ondanks dat de originele eigenlijk 3 seconden moet duren) zal hij vervangen worden door 'MTIME3'.

Je kunt de teksten verwijderen met behulp van de volgende opcodes:

00BE: text_clear_all 
03D5: remove_text 'MTIME3'

Display teksten met een nummer

01E3: show_text_1number_styled GXT 'BB_15' number 500 time 5000 style 1

Met deze opcode kan je een nummer in de text plaatsen. In dit geval: your new high score will be 500. De stijlen zijn precies hetzelfde als de eerder genoemde. Maar let op: je moet een gxt entry gebruiken die aangeeft dat hij een nummer wil hebben. Dat doe je door middel van ~1~ in de tekst. Bij de bovenstaande opcode moet dus de volgende tekst entry zijn: Your new high score will be ~1~.

Er zijn meer opcodes die hiermee te maken hebben. Ik denk dat ze voor zich spreken.

01E4: show_text_1number_lowpriority GXT 'HJ_IS' number $var time 2000 flag 1  
036D: show_text_2numbers_styled GXT 'TX_SEQ' numbers $var $var2 time 5000 style 5 
02FD: show_text_2numbers_lowpriority GXT 'BB_05' numbers $var $var2 time 5000 flag 1  
02FF: show_text_3numbers GXT 'WHEEL02' numbers $var $var2 $var3  time 3000 flag 1  
0302: show_text_4numbers GXT 'WHEEL01' numbers $var $var2 $var3 $var4  time 3000 flag 1 
0303: show_text_4numbers_highpriority GXT 'QUAR_P6' numbers $var $var2 $var3 $var4  time 10000 flag 1  
0308: show_text_6numbers GXT 'HJSTAT' numbers $var $var2 $var3 $var4 $var5 time 5000 flag 5

Wanneer je meer dan 1 nummer erin wil hebben, moet je dus één van deze opcodes gebruiken. Bijvoorbeeld: "You have won ~1~ dollar, your current amount is now ~1~.". Je moet de variabelen in de opcode in dezelfde volgorde houden, dus als eerst moet komen hoeveel je gewonnen hebt, dan hoeveel je in totaal hebt.

Display text boxes

03E5: show_text_box 'HELP101'

Dit is een "normale" textbox. Het zal na een bepaalde tijd verdwijnen. Een textbox is de zwarte rechthoek in de linker bovenhoek met witte letters.

0512: show_permanent_text_box 'HOSP_1'

Deze text box is, zoals de opcode al wel doet vermoeden, permanent. Het blijft in beeld tot er een opcode komt die het verwijderd. Dat is de volgende:

03E6: remove_text_box

Bijvoorbeeld:

0512: show_permanent_text_box 'HOSP_1' 
wait 1000
03E6: remove_text_box

Met deze code zal er een textbox in beeld komen, 1 seconde in beeld blijven, en daarna verdwijnen.

0513: show_text_box_1number 'SLOT_02' number 2

Dit is een opcode voor een textbox met een nummer in de tekst, dat in dit geval 2 is (je kunt ook een variabele gebruiken in plaats van die twee!). Dit moet in de entry weer aangegeven worden met ~1~.

Er zijn drie opcodes die checken of er een textbox op het scherm staat:

0A2A:   text_box 'SGPUNT' displayed
08FE:   text_box_displayed 
88FE:   not text_box_displayed

0989: set_text_boxes_width 500

Met deze opcode kan je de breedte van de textbox aangeven. Om het verschil te zien, kan je de code hieronder testen:

0512: show_permanent_text_box 'HOSP_1' 
wait 1000
0989: set_text_boxes_width 500

Draw Teksten

033E: set_draw_text_position 300.0 200.0 GXT 'BJ_PUSH'

Dit is een voorbeeld van een draw text. Je kunt de positie bepalen door de 300.0 en 200.0 te veranderen. De 300.0 is horizontaal, de 200.0 is verticaal.

Een draw text is normaal gesproken een kleine witte tekst. Dit kan je echter veranderen met opcodes 133F en 1340. Je kunt het alleen verwijderen met behulp van de volgende opcode:

03F0: enable_text_draw 0

Je kunt ook een draw text maken met nummers:

045A: draw_text_1number 320.0 155.333 GXT 'WINNER' number 1000
045B: draw_text_2numbers 320.0 390.0 GXT 'TIME' numbers 20 30

Ik denk dat deze opcodes voor zichzelf spreken.

Andere tekst opcodes

0A19: display_zone_text 'MARKS'

Met deze opcode kan je een tekst in beeld laten komen zodra je een zone binnenkomt. Bijvoorbeeld Saint Mark's.

09C1: add_next_text_to_brief_history 1

Deze opcode kan je gebruiken voor het toevoegen van de tekst bij "brief" in het main menu, zodat de player het terug op kan zoeken. Een 1 betekent dat het in "brief" opgeslagen moet worden, 0 betekent dat dat niet hoeft. Je moet deze opcode gebruiken VOOR je de tekst in beeld laat komen. Bijvoorbeeld:

09C1: add_next_text_to_brief_history 1 
00BB: show_text_lowpriority GXT 'IE23' time 3000 flag 1

Wanneer je een voorbeeld van een tekst wil zien in een korte missie, kan je terugkijken naar de vorige tutorials, die een voorbeeld van teksten bevatten.

Geplaatst:

Custom Save Point

In deze tutorial zullen we een simpele custom save point gaan maken. Maar let op: dit werkt niet zo goed in MPACK. Wanneer je een custom save point wil maken met behulp van scm, doe het dan in de main.scm en niet in MPACK.

Plan van aanpak

1) Creëer een pickup en kijk of de player het opgepakt heeft.

2) Laat het save screen zien, en wacht tot de save klaar is.

3) Opruimen

1) Creëren van een pickup en kijken of de player die opgepakt heeft

Dit is niet al te moeilijk. Wanneer je de andere tutorials in dit topic al heb gevolgd, moet je die zelf kunnen maken. De onderstaande code is dan ook niet al te moeilijk te begrijpen.

$save_x = 2488.6506
$save_y = -1660.9884
$save_z = 13.3359

0395: clear_area 1 at $save_x $save_y $save_z range 1.0 
$SAVE_PICKUP = Pickup.Create(#PICKUPSAVE, 3, $save_x, $save_y, $save_z)

repeat
   wait 100
until 0214:   pickup $SAVE_PICKUP picked_up 

Als je niet begrijpt wat ik hier doe, moet je de tutorial over pickups even opnieuw doornemen. ;)

2) Save screen laten zien en wachten tot gesaved is

Je kunt een save screen oproepen met slechts 1 opcode.

03D8: show_save_screen 

Maar we moeten wel het een en ander doen voordat we deze opcode kunnen gebruiken. Allereerst moeten we de $ONMISSION variabele op 1 zetten, zodat de speler geen telefoontjes of andere dingen kan krijgen. Ten tweede moeten we ervoor zorgen dat de player niet kan bewegen. Het zou erg vreemd staan als de speler op een totaal andere plaats staat dan waar in eerste instantie werd opgeslagen.

$ONMISSION = 1 // integer values 
Player.CanMove($PLAYER_CHAR) = False

We moeten wachten tot het saven klaar is. Hoewel je de opcode "save_done" niet kunt vinden in de opcode search tool of in de main.scm (je kunt 83D9 (not save_done) wel vinden), is het te gebruiken en erg makkelijk.

repeat
   wait 100
until 03D9:   save_done 

Wanneer deze fragmenten worden gecombineerd, dan wordt het tweede deel als volgt:

$ONMISSION = 1 // integer values 
Player.CanMove($PLAYER_CHAR) = False
03D8: show_save_screen 

repeat
   wait 100
until 03D9:   save_done 

3) Clean up

Wat hebben we nu? We hebben een pickup, welke opgepikt moet zijn. Dan hebben we een save screen, en de code moet wachten tot de speler klaar is met opslaan. Je hoeft niets te doen met betrekking tot dat opslaan, dat is hardcoded. In dit laatste deel zullen we de camera fixen en checken of de speler niet meer in de buurt van de save pickup is. Daarnaast moeten we de pickup destroyen.

Pickup.Destroy($SAVE_PICKUP)
repeat
   wait 100
until Player.Defined($PLAYER_CHAR) 

Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
Player.CanMove($PLAYER_CHAR) = True

$ONMISSION = 0 

repeat
wait 0
until 80EC:   not actor $PLAYER_ACTOR 0 near_point 2488.6506 -1660.9884 radius 2.0 2.0 

jump @SAVE_LOOP

De eerste regel is om de pickup te "destroyen". Op het einde zullen we terugspringen naar het begin (nadat we hebben gewacht tot die speler niet meer op die plek staat), zodat de pickup weer opnieuw wordt gecreëerd. Daarna zullen we de camera herstellen. De speler moet weer kunnen bewegen. Tot slot moeten we $ONMISSION terug zetten naar 0, anders is het niet mogelijk om een nieuwe missie te starten of een telefoontje te krijgen.

The full code of a custom save point thread:

:SAVE
thread "SAVE"

// location of the save pickup
$save_x = 2488.6506
$save_y = -1660.9884
$save_z = 13.3359

:SAVE_LOOP
0395: clear_area 1 at $save_x $save_y $save_z range 1.0 
$SAVE_PICKUP = Pickup.Create(#PICKUPSAVE, 3, $save_x, $save_y, $save_z)

repeat
   wait 100
until 0214:   pickup $SAVE_PICKUP picked_up 

$ONMISSION = 1 // integer values 
Player.CanMove($PLAYER_CHAR) = False
03D8: show_save_screen 

repeat
   wait 100
until 03D9:   save_done 

Pickup.Destroy($SAVE_PICKUP)

repeat
   wait 100
until Player.Defined($PLAYER_CHAR) 

Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
Player.CanMove($PLAYER_CHAR) = True

$ONMISSION = 0 

repeat
   wait 0
until 80EC:   not actor $PLAYER_ACTOR 0 near_point $save_x $save_y radius 2.0 2.0 

jump @SAVE_LOOP

end_thread

Totale code in een stripped file

Gast
Dit onderwerp is gesloten.
  • Recent actief   0 leden

    • Er zijn hier geen geregistreerde gebruikers aanwezig.
×
×
  • Create New...