Jump to content

[V|C++|Script Hook V] GTA V C++ Coding Guide


Recommended Posts

Geplaatst:

GTA V C++ Coding Guide

Inleiding

In deze coding guide staat een reeks tutorials en achtergrondinformatie die je op weg helpen om je eigen "script-mod" te maken.

Waarschuwing

Door het gebruik van de Script Hook kan je niet meer GTA Online spelen!

Wil je toch GTA Online spelen, verwijderd of verplaats de bestanden van de Script Hook naar een andere map waar je ze terug kan vinden.

Er zijn ook onoficiele Script Hook's in omloop waarmee je wel GTA Online kan spelen, GEBRUIK DEZE NIET!

Online-cheaten is niet toegestaan en daarnaast krijg je van Rockstar een ban!

Benodigdheden

  • Grand Theft Auto 5 PC versie (patch: 1.0.335.2, 1.0.350.1 of 1.0.350.2 [2 mei 2015])
  • Visual Studio

Er zijn meerdere versies van Visual Studio geschikt voor deze tutorials, de volgende zijn gratis versies:

■ Express 2013 for Windows Desktop

■ Community 2013 (voor niet commercieel gebruik)

Beide versies zijn
van de website van Microsoft. Ben je een student? Dan kan je via de Microsoft
de (betaalde) Professional-versie gratis downloaden.

Voor deze tutorial voldoet de Express 2013 for Windows Desktop of Community 2013 versie.
  • Script Hook V en SDK: Hier te downloaden: download link
  • Ervaring met programmeren, bij voorkeur C en/of C++. (geen vereiste, zie de achtergrondinformatie: Basis C++)


Inhoud

Achtergrondinformatie

[table=header]Naam|Beschrijving|Prioriteit

Native Functions|Hierin wordt uitgelegd wat native functions zijn|Hoog, Lees dit eerst!

Structuur Script Hook V project|Hierin wordt uitgelegd hoe een Script Hook V project in elkaar zit|Hoog, Lees dit eerst!

Basis C++|Een korte uitleg over C++|lees dit eerst indien je niet bekend bent met C++[/table]

Tutorials

[table=header]#|Tutorial naam|Beschrijving|Moeilijkheidsgraad

1|Project template|Uitleg over hoe je een C++ Script Hook V project maakt|Beginner

2|Hello World|Een simpel project die de tekst Hello World laat zien. Met dit project weet je zeker dat je plugin werkt.|Beginner

3|Models|Laden/ontladen van models, models verkrijgen van bestaande entiteiten|Beginner

4|Peds|In deze tutorial komen o.a. de volgende punte aan bod: Spawnen van een ped, Locatie van een ped verkrijgen|Beginner

5|Wapens|In deze tutorial komende o.a. de volgende punten aan bod: Wapen aan een ped geven, Status van wapen opvragen.|Beginner / Gevorderd

6|Voertuigen|In deze tutorial komen o.a. de volgende punten aan bod: Spawnen van een voertuig, kleur veranderen, snelheid opvragen|Beginner / Gevorderd[/table]De tutorials die bouwen voort op kennis in eerdere tutorials. Volg de tutorials op volgorde van nummer.

Handleidingen

[table=header]Naam|Beschrijving|Extra informatie

Visual Studio|Hierin wordt de globale werking van Visual Studio uitgelegd die benodigd zijn voor deze tutorial|Visual Studio is een vereiste om verder te kunnen gaan.

Script Hook V ontwikkelaarsfunctie|Hierin wordt uitgelegd hoe je de ontwikkelaars-reload functie kan activeren|-[/table]

In dit topic wordt alleen tutorials en achtergrondinformatie geplaatst. Reacties en vragen kan je plaatsen in het reactietopic. Ook kan je in het reactietopic nieuwe tutorials aanvragen.

Geplaatst:

Achtergrondinformatie

Native Functions

Wat zijn native functions?

In GTA V worden in scripts functies gebruikt die GTA V beschikbaar stelt, deze functies zijn native functies. Deze functies worden gebruikt in .YSC scripts maar ze kunnen ook buiten het script aangeroepen door het geheugen van deze functie aan te roepen.

Welke native functies zijn er?

Er zijn ongeveer 4500 native functies in GTA V, deze worden bijna allemaal gebruikt in de standaard scripts.

Er zijn verschillende native functies voor verschillende doeleinden. Een lijst met de native functies met bijbehorende parameters kan worden gevonden op de site van Alexander Blade: Native Database.

De native functies staan gesorteerd per categorie.

Ten tijden van schrijven zijn nog niet alle native functies en parameters bekend.

Onbekende native functies

In de lijst zien je (momenteel) verschillende native functies die er bijvoorbeeld uit zien als:

Any _0xCEEAD94B(Any p0, Any p1, Any p2)

Van zulke native functies is de naam nog niet bekend en welke argument types het heeft. Wanneer de werking van zo'n native functie bekend is, kan deze gewoon gebruikt worden.

De namen van native functies zijn allemaal hashes van de originele naam. De originele naam van een native functie verkrijgen is een lastig karwei en komt veel handmatige controle aan te pas. Het in kaart brengen van alle originele namen van native functies en hoe deze gebruikt kunnen worden zal nog enige tijd duren.

Geplaatst:

Achtergrondinformatie

Basis C++

Script-mods m.b.v. de Script Hook worden gemaakt in de programmeertaal C++. De taal C++ is zeer uitgebreid en dit is niet een C++ tutorial, enkel een referentie voor de meest basale functies en mogelijkheden. Met deze beschrijving kan je de beginners tutorials volgen, wanneer je de "advanced" of "expert" tutorials wilt volgen, raadpleeg dan C++ documentatie op de site: cppreference.com


De volgende uitleg is een vrij vertaalde en ingekorte versie van een tutorial op cplusplus.com.

Hoofdletter gevoelig

Bij het schrijven van C++ code moet je goed opletten op de naamgeving. De taal is hoofdletter gevoelig, dit betekent dat lettter geschreven als een hoofdletter niet hetzelfde zijn als kleine letters. Zo is bijvoorbeeld: Result niet hetzelfde als result of RESULT!

Structuur van een programma / library

Elk programma of library (Een .asi plugin is een library (dll)) heeft een standaard manier waar het programma begint. Bij C++ begint een programma of ten alle tijde bij een functie genaamd main. Bij een library heet de standaard functie: DllMain.

Voorbeeld van een hello world programma

// Hello World programma
#include <iostream>

int main()
{
std::cout << "Hello World!";
}

Hierboven zie je het standaard "hello World" programma die de tekst "hello world" laat zien.

Laten we bovenstaand voorbeeld analyseren:

Regel 1: // Hello World programma

Twee // achter elkaar geeft aan dat dit alles wat er achter de // staat commentaar is. Hier kan je neerzetten wat je wilt, dat heeft geen invloed op de werking van het programma. Met commentaar kan je er tekst neerzetten waarmee je duidelijkheid aan je code kan geven.

Regel 2: #include <iostream>

Alle lijnen die beginnen met een hekje (#) zijn directives en worden gelezen door een zogenaamde preprocessor. Deze lijnen worden gelezen voordat de code gelezen worden. De include betekend dat de preprocessor code van een andere locatie moet gebruiken. In dit geval hebben we de code van iostream nodig omdat we hiermee tekst op het scherm kunnen zetten.

Regel 3: Een lege regel

Lege regels hebben geen invloed op het programma.

Lijn 4: int main ()

Deze regel declareert een functie. Een functie is gegroepeerde code met een naam, in dit geval: main. Wanneer de functie main aangeroepen wordt dan zal alle code wat bij deze functie hoort uitgevoerd worden. Verderop zal er verder ingegaan worden op functies.

Een functie met de naam main is een speciale functie in C++. Wanneer een programma opgestart wordt dan wordt er ten alle tijden gezocht naar een functie met de naam main, deze functie wordt dan aangeroepen.

Regel 5 en 7: { en }

De accolades open ( { ) op regel 5 geeft het begin van de main functie aan. De accolades sluiten ( } ) op regel 7 geeft het einde van de main functie aan. In dit geval: Alles wat tussen de accolades staat hoort bij de functie main.

Regel 6: std::cout << "Hello World!";

Dit is een statement. Met een statement kan je een actie laten gebeuren. Statements worden uitgevoerd van boven naar beneden.

In dit geval bestaat het statement uit drie onderdelen:

Het eerste gedeelte is std::cout, deze geeft aan dat we uit de bibliotheek std (Standard library) de character output device willen hebben (meestal een command prompt console). Het tweede gedeelte de invoeg operator (<<) geeft aan dat wat daarna komt, ingevoegd moet worden in het gedeelte ervoor, in dit geval std::cout. Het derde gedeelte bestaat uit de tekst Hello World, deze tekst staat tussen quotes ("Hello world"), dit is vereist voor teksten.

Aan het einde van elk statement staat een puntkomma( ; ). Een puntkomma geeft het einde van een statement aan. Alle statements in C++ moeten eindigen met een puntkomma.

Variabelen en types

Indentifiers

Een geldige indentifier is een reeks van een of meerdere letters, cijfers of een underscore ( _ ). Een indentiefier is een naamgeving voor een data type of actie. C++ heeft verschillende indentificatie operatoren voor acties en data types, de naamgeving voor deze indentifiers kunnen niet gebruikt worden voor eigengemaakte indentifiers.

De standaard C++ indentifiers zijn:

alignas, alignof, and, and_eq, asm, auto, bitand, bitor, bool, break, case, catch, char, char16_t, char32_t, class, compl, const, constexpr, const_cast, continue, decltype, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, noexcept, not, not_eq, nullptr, operator, or, or_eq, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_assert, static_cast, struct, switch, template, this, thread_local, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while, xor, xor_eq

Fundamentele data types

Data types beschrijven over wat voor soort waarde het gaat, zoals bijvoorbeeld: letters (string of char array) of een cijfer (integer) of een cijfer met decimalen (double / float) etc.

Fundamentele data types zijn data types die standaard aangeboden worden door C++. Deze datatypes kunnen geclassificeerd worden in de volgende categorieën:

  • Karakter types

Deze types representeren 1 teken. De meest basale type is
char
, welke bestaat uit 1 byte.
  • Numerieke integer types

Deze types bevatten een cijfer. De minimale en maximale waarde van een type kan verschillen door de grootte die het type aangeeft en of het signed of unsigned is.
  • Floating point types

Deze types bevatte waardes met waardes achter de komma, hoe precies de waarde achter de komma is ligt aan het gebruikte data type.
  • Boolean types

Dit type kent maar twee waardes: Waar (true) of false (onwaar).

[table=header]Groep|Type namen|Informatie over grootte of precisie|Minimale waarde|Maximale waarde

Karakter types|char|Precies 1 byte groot (8 bits)

|char16_t|Niet kleiner dan char (16 bits)

|char32_t|Niet kleiner dan char16_t

|wchar_t|Grootst mogelijke char

Integer types (signed)|signed char|1 byte|-128|127

|signed short int|2 bytes (16 bit)|-32768|32767

|signed int|2 bytes (16 bit)|-32768|32767

|signed long int| 4 bytes (32 bit)|–2.147.483.648|2.147.483.647

|signed long long int| 8 bytes (64 bit)|–9.223.372.036.854.775.808|9.223.372.036.854.775.807

Integer types (unsigned)|unsigned char|1 byte|0|255

|unsigned short int|2 bytes (16 bit)|0|65.535

|unsigned int|2 bytes (16 bit)|0|65.535

|unsigned long int| 4 bytes (32 bit)|0|4.294.967.295

|unsigned long long int| 8 bytes (64 bit)|0|18.446.744.073.709.551.615

Floating point types|float|||

|double|Preciezer dan een float||

|long double|Prezierer dan een double||

Boolean type|bool|||

Void type|void|geen opslag||

Null Pointer|decltype(nullptr)|||[/table]

Bepaalde types kunnen afgekort worden, zo kan een integer opgeschreven worden als een int. Standaard zijn waardes in C++ signed (dus zowel negatieve en positieve cijfers) dus hoeft signed niet ervoor te staan, natuurlijk wel als je unsigned waardes (dus waardes die niet negatief mogen zijn) wilt gebruiken.

Declaratie van variabelen

C++ is een sterk-type taal, dit betekent dat elke variabele met z'n type gedeclareerd moet zijn voordat het gebruikt kan worden. De syntax om een variabele te declareren is heel simpel: eerst moet het type geschreven worden gevolgd door de naam die je de variabel wilt geven.

[i]TYPE NAAM[/i]

Een voorbeeld:

int a;
float nummer;

In bovenstaande stuk code wordt op de eerste regel een variabel gedeclareerd van het type integer (afgekorte versie wordt hier gebruikt) en met de naam a. Op de tweede regel wordt een variabel van het type float gedeclareerd met de naam nummer. Nu de variabelen gedeclareerd zijn kan je ze gebruiken door de naam aan te roepen (in dit geval a en nummer).

Wanneer je meerdere variabelen van hetzelfde type wilt declareren kan je het op de volgende manier doen:

int a, b, c;

In bovenstaand stuk code worden er drie variabelen gedeclareerd van het type int. Deze code heeft hetzelfde resultaat als:

int a;
int b;
int c;

Initialisatie van variabelen

Wanneer variabelen gedeclareerd zijn (zoals hierboven beschreven) hebben ze een onbekende of standaard waarde totdat ze een waarde krijgen toegewezen voor de eerste keer. Het toewijzen van een waarde aan een variabelen heet het initialiseren van een variabel.

In C++ zijn er drie manieren om een variabel te initialiseren.

De eerste en meest gebruikte methode is na de declaratie een = (toewijzing) teken te zetten met daarachter de waarde:

int a = 0;

De tweede methode staat bekend als de constructor initialisatie waarbij de waarde tussen twee haakjes ( ) wordt gezet:

int a(0);

De derde methode staat bekend als de uniform initialisatie waarbij de waarde tussen twee accolades { } wordt gezet:

int a{0};

Operatoren

Met operatoren kan je variabelen waardes opvragen, wijzigen of veranderen.

Toewijzing operator ( = )

Met de toewijzings operator kan je een waarde aan een variabel toewijzen.

a = 5;

Bovenstaande code wijst een integer met de waarde 5 toe aan de variabel met de naam a. De toewijzing vindt ten alle tijden plaats van rechts naar links. Je kan ook de waarde van een variabel aan een andere variabel toewijzen:

a = b;

Bovenstaande code krijgt de variabel met de naam a de waarde die in variabel b staat.

Rekenkundige operatoren

In C++ zijn de er vijf rekenkundige operatoren:

[table=header]Operator|Beschrijving

+|Optellen

-|Aftrekken

*|Vermenigvuldigen

/|Delen

%|Modulatie[/table]Bovenstaande operatoren op die van modulatie na doen precies hetzelfde zoals ze in de wiskunde gebruikt worden.

int a = 5 + 10;
int b = a - 5;
int c = a * b;
float d = c / 10;

De modulatie operator wordt weergegeven als een procent teken (%). Deze operator geeft het restant van een deling terug:

a = 11 % 3;

In dit voorbeeld zal de variabel a de waarde 2 toegewezen krijgen (11 delen door 3 resulteert in 3 met een rest van 2).

Samengestelde operatoren

Samengestelde operatoren zijn operatoren waarbij er een waarde toegewezen wordt en tegelijkertijd wordt er een actie uitgevoerd. Deze operatoren hebben hetzelfde resultaat als eerst een waarde toewijzen en daarna een actie erop uit voeren (zoals optellen, aftrekken etc.):

[table=header]Expressie|Staat gelijk aan

a += b| a = a + b

a -= 5| a = a - 5

a /= b| a = a / b

a *= b + 50|a = a * (b + 50)[/table]

Vermeerdering / verminderings operatoren

Wanneer je 1 bij een variabel wilt optellen of aftrekken dan is er nog een snellere manier dan met samengestelde operatoren, hiervoor heb je de increase (++) en decrease (--) operatoren. Deze staan gelijk aan: +=1 en -= 1.

Er zijn twee manieren om deze operator te gebruiken: Voor de toewijzing en na de toewijzing:

Voorbeeld 1:

a = 3;
b = ++a;

Variabel a bevat: 4

Variabel b bevat: 4

Voorbeeld 2:

a = 3;
b = a++;

Variabel a bevat: 4

Variabel b bevat: 3

Bij voorbeeld 1 is de waarde die aan b toegewezen wordt, de waarde van a nadat er 1 bij op is geteld.

Bij voorbeeld 2 is de waarde die aan b toegewezen wordt, de waarde van a voordat er 1 bij op is geteld.

Relationele en vergelijkings operatoren

Twee relationele en vergelijkings expressies kunnen gebruikt worden voor het vergelijken van waardes. Bij een vergelijking is de uitkomst altijd van het type boolean (waar of onwaar).

C++ heeft de volgende operatoren hiervoor:

[table=header]Operator|Beschrijving

==|Gelijk aan

!+|Ongelijk aan

<|Kleiner dan

>|Groter dan

<=|Kleiner dan of gelijk aan

>=|Groter dan of gelijk aan[/table]

Voorbeeld:

(7 == 5) //Geeft false
(5 > 4) //Geeft true
(3 != 2) //Geeft false
(6 >= 6)//Geeft true
(5 < 5) //Geeft false

Logische operatoren

In C++ is de operator ! een boolean operator voor NOT (niet). Deze operator keert de waarde van de boolean om. False wordt true en omgekeerd.

Voorbeeld:

!(5 == 5) //Geeft false
!(6 <= 4) //geeft true
!true //is false
!false //is true

De logische operatoren && en || worden gebruikt om twee of meerdere expressies 1 resultaat terug te geven.

Met de && operator kan je twee of meerdere vergelijkingen 1 resultaat terug laten geven. Wanneer alle vergelijkingen kloppen zal de waarde true terug gegeven worden, wanneer 1 of meerdere vergelijkingen niet kloppen dan zal de waarde false terug gegegen worden. Voorbeeld:

a = 5;
b = 10;
(a == 5 && b == 10) //Geeft true
(a != b && b == 10) //Geeft true
(a == b && b == 10) //Geeft false

Met de || operator kan je meerdere vergelijkingen maken waarvan er maar 1 hoeft te kloppen:

a = 5;
b = 10;
(a == 5 || b == 10) //Geeft true
(a !=b || b == a) //Geeft true

Statements

Selectie statement: If en else

Het if sleutelwoord wordt gebruikt om een statement of groep code uit te voeren wanneer er aan de conditie voldaan wordt.De conditie van een if statement kan enkel van het type boolean zijn (true of false). De syntax is:

if (conditie) statement of code

Wanneer er aan de conditie voldaan is dan zal de code die bij de if hoort uitgevoerd worden.

Wanneer er enkel 1 regel code na de if statement komt dan kan de code er direct onder gezet worden, bijvoorbeeld:

if(a == 100)
b = 20;

In deze code wordt enkel de waarde 20 aan b toegewezen als de waarde in a gelijk is aan 100.

Wanneer je meer dan 1 regel code nodig heb dan gebruik je de accolades:

if(a ==100)
{
b= 20;
c =30;
}

Wanneer je op een andere conditie wilt controleren als een conditie niet voldoet dan kan je het else sleutelwoord gebruiken:

if(a == 100)
b = 20;
else if(a > 200)
b = 30;
//Ook kan dit met blokhaken:
if(a == 100)
{
b = 20;
c = 30;
}
else if(a > 200)
{
b = 30;
c= 40;
}

Je kan het else sleutelwoord ook gebruiken zonder conditie:

if(a == 100)
b = 20;
else
b = 30;
//Of met blokhaken:
if(a == 100)
{
b = 20;
c = 30;
}
else
{
b = 30;
c = 40;
}

iteratie statements: Loops

Een loop vergelijking die die herhaald wordt totdat er aan een conditie is voldaan. In een loop kan code neergezet worden die elke keer uitgevoerd wordt zolang de loop herhaald wordt. Er zijn 4 soorten loops:

While loop:

Bij een while loop is de controle op de conditie vooraf. Een while loop heeft de volgende syntax:

while (conditie) statement / code

De while loop blijft herhalen zolang de conditie true is. Voorbeeld:

int a = 0;
int b = 5;
while(a < 10)
{
b += 100;
a++;
}

In bovestaand voorbeeld herhaald de loop zolang de waarde in de variabel a lager is dan 10. In de loop tellen we steeds 1 bij a op en tellen we 100 bij de variabel b op. Na 10 keer zal de loop stoppen, de variabel a = 10 (aan de conditie wordt voldaan, is niet meer lager dan 10) en de variabel b heeft de waarde 1005.

Do While loop:

Bij een while loop is de controle achteraf. Een Do While loop heeft de volgende syntax:

do statement / code while (conditie)

Het verschil met de while loop is dat hier de controle achteraf plaats vind in plaats van vooraf.

int a = 0;
int b = 5;
do
{
b += 100;
a++;
}while(a < 10)

For loop:

De for loop is gemaakt om een bepaald aantal keer door een loop te gaan. De syntax is:

for(initialisatie; conditie; expressie) statement / code

In deze loop declareer je bij de initialisatie een variabel die je gaat gebruiken in de loop. Bij de conditie zet je een vergelijking neer en bij de expressie doe je een actie die de conditie kan beïnvloeden. De variabel die je declareert bij de initialisatie kan je gebruiken in de code in de loop:

int a = 0;
for(int i = 0; i < 10; i++)
{
a += i;
}

In dit voorbeeld is er in de loop een variabel van het type integer en met de naam i gedeclareerd en deze is meteen geïnitaliseerd met de waarde 0. Als conditie staat er dat de waarde in variabel i lager moet zijn dan 10. Als expressie wordt er steeds 1 bij i opgeteld. In de code van de loop wordt de waarde van i steeds bij de variabel a opgeteld.

Reeks gebaseerde loop:

Wanneer een variabel uit meerdere variabelen bestaat (zoals in een array of een list) dan kan met deze loop langs elke variabel gegaan worden. De syntax hiervoor is:

for(declaratie : reeks) statement / code

Een voorbeeld van zo'n loop:

std::string voorbeeld {"test"};
for(char c : voorbeeld)
{
std::cout << c;
}

Omdat een string (tekenreeks) uit chars (teken) bestaat kan er door een string geloopt worden. In dit voorbeeld zal de loop door alle letters gaan van het woord: test.

Jump statements

Met jump statements kan de volgorde van code veranderd worden, dit wordt vooral gebruikt in loops.

Met het statement break kan je een loop vroegtijdig stoppen (voordat er aan de conditie is voldaan).

for(int i = 0; i < 10; i++)
{
if( i == 5)
break;
}

In dit voorbeeld zal de loop stoppen wanneer de waarde van de variabel i gelijk is aan 5.

Met het statement continue kan je in de loop de rest van de code overslaan en meteen doorgaan naar de volgende iteratie van de loop:

int a = 0;
for(int i = 0; i < 10; i++)
{
if( i == 5)
continue;

a++;
}

In dit voorbeeld zal de loop de code onder continue overslaan wanneer de waarde van variabel i gelijk is aan 5.

Functies

Een functie is een stuk gegroepeerde code die je kan aanroepen vanuit een andere functie. Wanneer een functie aangeroepen wordt dan wordt de code die hierin staan van boven naar beneden uitgevoerd. Als de functie ten einde is, dan keert het programma terug naar het punt waar die functie is aangeroepen en gaat verder.

De syntax om een functie te declareren is:

type naam (argumenten) statement / code

Een functie begint altijd met het type. Dit type geeft aan wat voor waarde de functie terug kan geven. Wanneer er geen gegevens terug gegeven hoeven te worden dan kan het het sleutelwoord void gebruiken, hiermee wordt aangegeven dat die functie geen waarde terug geeft.

Als tweede moet er voor de functie een naam opgegeven worden, met deze naam kan de functie aangeroepen worden.

Als derde kunnen er optioneel argumenten meegegeven worden. Argumenten zijn een of meerdere (tijdelijke) variabelen die je in de code kan gebruiken. Argumenten komen altijd tussen haken ( en ) te staan. Wanneer je meerdere argumenten wilt gebruiken dan moeten die gescheiden worden met een komma ( , ).

Voorbeeld van functies:

//main is de standaard functie die aangeroepen wordt wanneer het programma start.
int main()
{
int b = testfunctie_1();
testfunctie_2();
}
int testfunctie_1()
{
return 5;
}
void testfunctie_2()
{
std::cout << "Hallo";
}

Functies met argumenten

Aan een functie kan je ook argumenten meegeven, je declareerd voor de functie variabelen die je in de functie kan gebruiken:

int main()
{
int a = functie_met_argumenten_1(5, 10);
}
int functie_met_argumenten_1(int a, int b)
{
return a * b;
}

In bovenstaand voorbeeld staat in de functie main een variabel a gedeclareerd. Met het resultaat van de functie "unctie_met_argumenten_1" wordt die variabel geïnitialiseerd.

In de functie "functie_met_argumenten_1" staan 2 argumenten gedeclareerd (int a en int b), in de code van deze funtie worden de twee waardes vermenigdvuldigd en middels het sleutelwoord return terug gegeven. De functie met parameters roep je simpelweg aan door de naam aan te roepen en tussen de haakjes de waardes te zetten die overeen komen met het type zoals gedeclareerd in de funtie.

Vele onderwerpen zijn hier niet behandeld zoals bijvoorbeeld: Scopes, pointers en references. Dit wordt later aangevuld.

Gebruik voor nu de documentatie op cppreference.com en cplusplus.com.

Wanneer je fouten ontdekt hebt stuur dan naar mij (Crypteq) een PB. Wanneer je suggesties of vragen hebt gebruik dan het reactietopic.

Geplaatst:

Achtergrondinformatie

Structuur Script Hook V project

De Script Hook V SDK heeft enkele bestanden die ten alle tijden vereist zijn. Ook zijn er enkele optionele bestanden die bij de Native Trainer voorbeeld meegeleverd worden die je ook kan hergebruiken in andere projecten.

Het project heeft een standaard indeling van een win32-dll project. Voor meer informatie over hoe je een template project kan maken, zie de tutorial: Project Template.

Vereiste bestanden

ScriptHookV.lib

Dit bestand bevat code die vereist is om een project te kunnen compilen (bouwen), zonder dit bestand kan je geen Script Hook plugin maken.

enums.h

In het bestand Enum.h kan je enumeratie variabelen declareren.

Voor verdere uitleg omtrent enums zie de documentie: Enumerated types (enum)

natives.h

In dit bestand staan alle native functies gedeclareerd die je kan gebruiken.

Pas dit bestand niet aan!

types.h

In dit bestand staat verschillende data types gedefinieerd die je kan gebruiken.

main.h

In de main.h staan code die onderdelen gedeclareerd en inlaad voor een correcte werking van een Script Hook plugin.

main.cpp

In dit bestand staat de speciale funtie DllMain. Deze functie wordt aangeroepen om de DLL (wat een .asi bestand is) in te laden.

Hierin staan twee condities:

  • Wanneer de DLL geladen wordt

Hier wordt de functie scriptRegister aangeroepen. Hiermee wordt je script ingeladen.
  • Wanneer de DLL ontladen wordt

Hier wordt de functie scriptUnregister aangeroepen. Hiermee wordt je script ontkoppeld.

Optionele bestanden

keyboard.h

In dit bestand staan de functies gedeclareerd die in keyboard.cpp geïnitialiseerd zijn en gebruikt worden. Dit bestand moet je ook "includen" als je deze functies wilt kunnen aanroepen.

keyboard.cpp

Dit bestand bevat de code van de functies die gedeclareerd staan in keyboard.h. Wanneer de functies in keyboard.h aangeroepen worden, dan worden de corresponderende functies in dit bestand uitgevoerd.

Geplaatst:

Handleiding

Visual Studio

Installatie en instellen

Installatie

De installatie van Visual Studio is eigenlijk bijna hetzelfde als elk ander programma. Visual Studio Express 2013 for Windows Desktop en Community 2013 zijn beide op de site van Microsoft te downloaden: download hier.

Een video over hoe je Visual Studio kan downloaden en installeren (niet door mij gemaakt):

Eerste keer opstarten

Wanneer je Visual Studio voor de eerste keer opstart krijg je een scherm te zien waar je de "development settings" moet instellen. Dit scherm ziet er (ongeveer) zo uit:

image14.png

Kies in dit scherm voor Visual C++ Development Settings.

Deze handleiding is niet compleet en zal later (indien er behoefte voor is) aangevuld worden

Geplaatst:

Handleiding

Script Hook V ontwikkelaarsfunctie

Sinds versie 1.0.350.2 heeft Script Hook V een reload functie om de plugins opnieuw te laden. Dit betekent dat je het spel niet opnieuw hoeft op te starten om een bijgewerkte / aangepaste versie van je script te laden.

Instellen van de reload functie

Om de reload functie te kunnen inschakelen moet je een leeg bestand maken in je GTA V map met de naam: ScriptHookV.dev

Dit bestand maken kan o.a. op de volgende manier:

  1. Start kladblok (notepad) op.
  2. Ga naar bestand > Opslaan (Ctrl+S)
  3. Navigeer naar de map waar je GTA V geïnstalleerd hebt.
  4. Vul als naam het volgende in: ScriptHookV.dev
  5. Achter de tekst Opslaan als (save as) kies je uit de lijst: Alle bestanden (all files)
  6. Druk op opslaan (save)

Reload functie gebruiken

Wanneer je ingame bent dan kan je een plugin bijwerken/vervangen door de volgende stappen te volgen:

  1. Ingame druk je op de toetsen: Ctrl + R (Control en de R toets tegelijkertijd)
  2. Je hoort nu een "beep" geluidje.
  3. Wissel naar je bureaublad en vervang de plugin door een bijgewerkte versie.
  4. Wissel terug naar GTA V.
  5. Druk nogmaals op Ctrl + R
  6. Je hoort nu twee keer achter elkaar een "beep" geluidje, je plugins zijn succesvol herladen.

F.A.Q.

Q: Hoe kan het dat ik de plugins niet kan herladen? / Ik hoor ook geen "beep" geluidje.

A: Zorg ervoor dat er in je GTA V folder een bestand staat met de naam ScriptHookV.dev (met de extensie .dev), zie stappen hierboven.

Q: Hoe kan het dat ik een foutmelding krijg dat het bestand in gebruik is?

A: Dan heb je ingame niet op CTRL+R gedrukt, dit zorgt ervoor dat je de plugin kan vervangen.

Geplaatst:

Tutorial

Project template

Om aan de slag te kunnen moet er allereerst een project gemaakt worden waar de code van het script in gezet kan worden. Zoals te zien is in Achtergrondinformatie: Structuur Script Hook V project zijn er enkele bestanden die we nodig hebben voor het project.

Indien je nog niet de Script Hook SDK hebt gedownload, download die dan eerst op de site van Alexander Blade.

Pak het zip bestand uit op een locatie die je makkelijk terug kan vinden.

1. Start Visual Studio op en ga in het menu naar: File > New > Project (Ctrl+Shift + N).

2. Selecteer in het dialoog aan de linkerkant: Visual C++ > Win32.

  • Selecteer Win32 Project.
  • Geef achter de tekst "Name" de naam op die je je plugin wilt geven.
  • Indien gewenst kan de locatie van de solution aangepast worden.
  • Geef achter de tekst "Solution name" de naam van de solution op of laat de standaard ingevulde naam staan.

Voor de reeks van deze tutorials worden de volgende namen gebruikt:

(Project)naam: Coding_Guide_Tutorial_X
(waarbij X staat voor het nummer van de desbetreffende tutorial)

Solution naam: Coding_Guide

VisualStudio_1.png

3. Druk op OK, een nieuw venster verschijnt. Druk op Next.

4. In het nieuwe dialoog zet de instellingen als volgt:

  • Application type: DLL
  • Additional options: Alles indien mogelijk de-selecteren (niet mogelijk bij precompiled headers)
  • Add common header files for: Vink ATL aan.

VisualStudio_2.png

5. Druk op finish.

6. Selecteer aan de rechterkant de mappen (filters): Header Files, Resources Files en Sources Files en het bestand Readme.txt en verwijder deze bestanden.

VisualStudio_3.png

7. Open in Windows de volgende mappen:

  • Map van de Script Hook SDK
  • Map van de solution (zelfde pad als is opgegeven bij stap 2: Location)

8. In de map van Script Hook SDK kopieer je de mappen: inc en lib.

9. Plak de twee mappen inc en lib naar de map waar ook de map van de solution in staat.

10. Ga terug naar Visual Studio: Rechtermuisknop op het project > Add > New Filter. Vul als naam in: include

11. Ga in Windows naar de inc (die bij stap 9), kopieer alle bestanden in deze map.

12. Ga naar Visual Studio en plak de bestanden in het filter / de map: include.

13. In Visual Studio: Rechtermuisklik op het project > Add > New Item. Selecteer in de dialoog: C++ File (.cpp). Vul bij Name het volgende in: main.cpp en druk op Add.

14. Het bestand main.cpp wordt in Visual Studio geopend. Zet de volgende code in main.cpp:

#include "..\..\inc\main.h"

BOOL APIENTRY DllMain(HMODULE hInstance, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

15. Ga in Visual Studio naar het project in de solution explorer: Rechtermuisknop op het project > Properties. Een nieuw dialoog verschijnt.

16. Klik rechtsboven op: Configuration Manager. Een nieuw Dialoog verschijnt.

17. Kies in de lijst "active solution configuration" voor: Release

18. Kies in de lijst "Active Solution platform" voor: <New..>

19. Een nieuw dialoog verschijnt, kies bij "Type or select new platform" voor: x64 en druk op OK. Druk in het venster Configuration Manger op close.

20. Ga in de dialoog van de Property Pages aan de linkerkant naar:Configuration Properties > General en stel in:

  • General > Output Directory: bin\$(Configuration)\
  • General > Intermediate Directory: tmp\$(Configuration)\
  • General > Target Extension: .asi
  • Project Defaults > Character set: Use Multi-Byte Character Set

21. Ga in de dialoog van de Property Pages aan de linkerkant naar:Configuration Properties > C/C++ > Code Generation en stel in:

  • Runtime Library: Multi-threaded (/MT)
  • Floating point model: Fast (/fp:fast)

22. Ga in de dialoog van de Property Pages aan de linkerkant naar:Configuration Properties > C/C++ > Precompiled Headers en stel in:

  • Precompiled Header: Not Using Precompiled Headers

23. Ga in de dialoog van de Property Pages aan de linkerkant naar:Configuration Properties > Linker > Debugging en stel in:

  • Generate Debug Info: No

24. Ga in de dialoog van de Property Pages aan de linkerkant naar:Configuration Properties > Linker > Command Line en stel in:

  • Additional Options: ..\..\lib\ScriptHookV.lib

25. In Visual Studio: Rechtermuisklik op het project > Add > Class. Selecteer in de dialoog: C++ Class en druk op Add. Een nieuw dialoog verschijnt. Vul in:

  • Class name: script
  • De rest van de automatisch ingevulde gegevens zo laten staan.

Druk op Finish.

26. Script.h is automatisch geopend. Vervang de code die in het bestand staat door:

#pragma once
#include "..\..\inc\natives.h"
#include "..\..\inc\types.h"
#include "..\..\inc\enums.h"
#include "..\..\inc\main.h"
void ScriptMain();

Hier includen we enkele headers van de ScriptHook SDK en defineren een funtie genaam: ScriptMain. Deze funtie zal aangeroepen worden door de main.

27. Ga naar het bestand main.cpp en pas de code aan:

#include "..\..\inc\main.h"
#include "script.h"
BOOL APIENTRY DllMain(HMODULE hInstance, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
scriptRegister(hInstance, ScriptMain);
break;
case DLL_PROCESS_DETACH:
scriptUnregister(ScriptMain);
break;
}
return TRUE;
}

28. Ga naar het bestand script.cpp en vervang de code door:

#include "script.h"
void main()
{
while (true)
{
WAIT(0);
}
}
void ScriptMain()
{
main();
}

29. Als alle stappen goed doorlopen zijn dan heb je nu een correct werkend project. Om te kijken of alles correct is moet je het project "builden". Rechtermuisklik op het project > Build. Wanneer alles goed is gegaan dan krijg je geen error en zal het volgende weergegeven worden (onderaan, tab output):

1>------ Rebuild All started: Project: Coding_Guide_Tutorial_1, Configuration: Release x64 ------

1> main.cpp

1> script.cpp

1> Generating code

1> Finished generating code

1> Coding_Guide_Tutorial_1.vcxproj -> D:\Programming\GTA\GTA V\Coding_Guide\Coding_Guide_Tutorial_1\bin\Release\Coding_Guide_Tutorial_1.asi

========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

Naamgeving en pad kan verschillen.

Keyboard hook (optioneel, wordt wel gebruikt in de tutorials)

Optioneel kan ook de keyboard hook gebruikt worden. Dit is een stuk code waarmee gemakkelijker op toetsen combinaties gecontroleerd kan worden. Deze bestanden zijn meegeleverd met de Native Trainer die als voorbeeld is meegeleverd in de SDK.

1. Ga in Windows naar de Script Hook SDK map. Ga dan naar de map: Samples > NativeTrainer en kopieer de bestanden keyboard.h en keyboard.cpp.

2. Ga in Windows naar de map van je project. (hier staan o.a. ook de bestanden: main.cpp, script.h en script.cpp) Plak de twee bestanden in deze map.

3. Ga in Visual Studio naar je project. Rechtermuisknop > Add Existing Item. Navigeer naar de map van je project en selecteer de bestanden: keyboard.h en keyboard.cpp en druk op Add.

4. Nu moet deze bestanden nog ge-include worden. Ga naar main.cpp en zet onder "#include "script.h"" het volgende neer:

#include "keyboard.h"

5. Ook moeten we voor de keyboard de register en unregister aanroepen:

  • Zet onder "scriptRegister(hInstance, ScriptMain);" het volgende neer: keyboardHandlerRegister(OnKeyboardMessage);
  • Zet onder "scriptUnregister(ScriptMain);" het volgende neer: keyboardHandlerUnregister(OnKeyboardMessage);

6. Ga naar script.cpp en zet onder "#include "script.h"" het volgende neer:

#include "keyboard.h"

7. Build het project om te kijken of het werkt (zie stap 29 bij vorige deel)

Tip

Nadat je deze stappen hebt doorlopen, maak een kopie van het project / solution zodat je dit steeds kan hergebruiken.

Geplaatst:

Tutorial

Hello World

In deze tutorial wordt er door middel van een toetsencombinatie de tekst "Hello World" op het scherm neergezet.

Er zijn verschillende manieren met de Script Hook om tekst weer te geven. In deze tutorial laten we de tekst als een notificatie boven de map weergeven.

Code

Voor deze reeks tutorials zal alle code staan in script.cpp. Het is mogelijk om dit over meerdere headers/source bestanden te plaatsen maar om het simpel te houden gebeurd dat in deze tutorial reeks niet.

In de main.cpp wordt de volgende functie aangeroepen:

scriptRegister(hInstance, ScriptMain);

Deze code zorgt ervoor dat deze plugin begint door de funtie ScriptMain aan te roepen, die we kunnen vinden in Script.cpp.

Vanuit de funtie ScriptMain wordt de funtie main aangeroepen waar een loop in staat die continue blijf loopen. De aanroep naar de funtie WAIT(0) moet ten alle tijden in deze loop blijven staan!

Allereerst gaan we zorgen dat we een functie kunnen aanroepen wanneer er op een bepaalde toets / toetsencombinatie wordt gedrukt. Om te detecteren of er op een bepaalde knop is gedrukt gebruiken we de code van keyboard.h/keyboard.cpp.

In dit voorbeeld gaan we controleren of er op de knop F9 is gedrukt, dit gaan we doen met de functie: IsKeyJustUp:

#include "script.h"
#include "keyboard.h"

void main()
{
   while (true)
   {
       if (IsKeyJustUp(VK_F9)){
      	 //Code hier
       }

       WAIT(0);
   }
}

void ScriptMain()
{
   main();
}

Nu er een controle is om te controleren of de knop F9 ingedrukt is, moeten we de tekst laten zien.

De code om een notificatie boven de map te laten zien is:

void notifyAboveMap(char* msg) {
   UI::_0x202709F4C58A0424((DWORD *) "STRING");
   UI::_ADD_TEXT_COMPONENT_STRING(msg);
   UI::_0x2ED7843F8F801023(FALSE, FALSE); // = DRAW ABOVE MAP
}

Let op: hiervan zijn de orginele namen van 2 native funties niet bekend maar wel wat deze native funties doen.

Zet bovenstaande code boven de functie main.

De code in script.cpp ziet er nu zo uit:

#include "script.h"
#include "keyboard.h"

void notifyAboveMap(char* msg) {
   UI::_0x202709F4C58A0424((DWORD *) "STRING");
   UI::_ADD_TEXT_COMPONENT_STRING(msg);
   UI::_0x2ED7843F8F801023(FALSE, FALSE); // = DRAW ABOVE MAP
}

void main()
{
   while (true)
   {
       if (IsKeyJustUp(VK_F9)){
           notifyAboveMap("Hello World!");
       }

       WAIT(0);
   }
}

void ScriptMain()
{
   main();
}

Build het project (Rechtermuisknop op het project > Build).

Wanneer deze succesvol gebouwd is, kopieer dan de .asi van het project naar de GTA V root map.

Resultaat



Tutorial_1_result.png



Download

Geplaatst:

Tutorial

Models

Elk ped (persoon), object of voertuig heeft een model, het model is wat bepaald hoe het eruit ziet. Voordat je een ped/object/voertuig kan spawnen moet je eerst het model inladen.

Allereerst moet je weten wat voor model je wilt laden. Een lijst van model namen is te vinden in het topic Models & Color Hashes op gtaforums.com.

Model laden a.d.h.v. model naam / hash

Wanneer je de naam van een model weet dan kan je de hash-key opvragen (de hash-key wordt intern door het spel gebruikt), dat kan met de volgende native functie:

GAMEPLAY::GET_HASH_KEY("NAAM VAN MODEL HIER")

Het spel vragen om het model in geheugen te laden gebeurd met de volgende native functie:

STREAMING::REQUEST_MODEL(MODEL HASH-KEY HIER)

Om te controleren of het model reeds in het geheugen geladen is kan met de volgende native functie:

STREAMING::HAS_MODEL_LOADED(MODEL HASH-KEY HIER)

Wanneer we deze samen gaan gebruiken in een script dan is dit een geldig voorbeeld:

Hash model = GAMEPLAY::GET_HASH_KEY("a_c_chimp");
STREAMING::REQUEST_MODEL(model);
while (!STREAMING::HAS_MODEL_LOADED(model))
WAIT(0);

In dit voorbeeld vragen we de hash-key op van het model "a_c_chimp". We doen een aanvraag om dit model te laden in het geheugen. Daarna loopen we net zolang totdat het model geladen is.

Model ontladen

Wanneer een model niet langer nodig is dan moet deze weer "vrijgegeven" worden. Dit kan gedaan met de volgende native functie:

STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(MODEL HASH-KEY);

Controleren of een model bestaat

Als je wilt controleren of een bepaald model bestaat dan zijn daar ook native functies voor.

Met de volgende native functie wordt gekeken of het model voorkomt in de game-archieven:

STREAMING::IS_MODEL_IN_CDIMAGE(MODEL HASH-KEY HIER)

De volgende native functie is om te kijken of een model geldig is:

STREAMING::IS_MODEL_VALID(MODEL HASH-KEY HIER)

Model opvragen van een ped/object/voertuig

In de Script Hook SDK zijn peds, objecten en Voertuigen allemaal een ENTITY.

We kunnen met de volgende native functie het model van al deze ophalen:

ENTITY::GET_ENTITY_MODEL(PED / OBJECT / VOERTUIG)

Een geldig voorbeeld in een script is bijvoorbeeld:

Ped playerPed = PLAYER::PLAYER_PED_ID();
Hash model = ENTITY::GET_ENTITY_MODEL(playerPed);

In dit voorbeeld wordt eerst het PED ID opgehaald van de speler. Daarna wordt van de Ped de hash-key van het model opgehaald.

De uitleg en deze code zal gebruikt worden in de volgende tutorials over: Peds en voertuigen.

Geplaatst:

Tutorial

Peds

In deze tutorial worden er met modellen gewerkt, zorg ervoor dat je eerst de tutorial: Model laden hebt gelezen.

Spawnen van een ped

Voor het spawnen van een ped moeten we eerst het model van een ped laden. In deze tutorial is er gekozen om het model "a_c_chimp" te laden.

De stappen voor het laden zijn:

  1. Hash van de modelnaam opvragen
  2. Controleren of het model bestaat
  3. Model aanvragen
  4. Wachten tot het model geladen is
  5. Ped spawnen op een gegeven locatie
  6. Model als niet langer nodig markeren

De code hiervoor is:

Hash model = GAMEPLAY::GET_HASH_KEY("a_c_chimp"); //Hash verkrijgen van het model met de naam a_c_chimp
if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_VALID(model)) //Controleren of het model voorkomt in de game archiveven en of het model geldig is
{
STREAMING::REQUEST_MODEL(model); //Model aanvragen
while (!STREAMING::HAS_MODEL_LOADED(model)) //Loopen totdat het model geladen is
WAIT(0);

Ped spawnedPed = PED::CREATE_PED(26, model, 0.0,0.0,0.0, 0.0, false, true); //Creeër een ped op locatie: x 0 y 0 z 0

STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); //Model als niet langer nodig markeren
notifyAboveMap("Chimp Spawned!"); //Tekst weergeven
}

Omdat we toch graag de ped zien, moeten we de ped dicht bij de speler spawnen.Hiervoor moeten we de locatie van de speler achterhalen. Omdat de speler ook een ped is moeten we eerst het Ped-ID ophalen van de speler, dat kunnen we doen met de volgende native functie:

PLAYER::PLAYER_PED_ID()

Nu moeten we enkel nog de locatie van de player-ped opvragen, ook willen we graag dat de locatie net iets van de speler af is. Dit kunnen we doen met de volgende native functie:

ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PED, x offset, y offset, z offset);

Deze native functie geeft een waarde terug van het type Vector3, hieruit kunnen we de x y z locaties halen om de ped te spawnen.

Wanneer we dit samenvoegen dan hebben we deze code:

#include "script.h"
#include "keyboard.h"


void notifyAboveMap(char* msg) {
UI::_0x202709F4C58A0424((DWORD *) "STRING");
UI::_ADD_TEXT_COMPONENT_STRING(msg);
UI::_0x2ED7843F8F801023(FALSE, FALSE); // = DRAW ABOVE MAP
}
void main()
{
while (true)
{
 if (IsKeyJustUp(VK_F9)){
  Ped playerPed = PLAYER::PLAYER_PED_ID(); //PED ID van de speler ophalen
  Hash model = GAMEPLAY::GET_HASH_KEY("a_c_chimp"); //Hash verkrijgen van het model met de naam a_c_chimp
  if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_VALID(model)) //Controleren of het model voorkomt in de game archiveven en of het model geldig is
  {
   STREAMING::REQUEST_MODEL(model); //Model aanvragen
   while (!STREAMING::HAS_MODEL_LOADED(model)) //Loopen totdat het model geladen is
 WAIT(0);

   Vector3 playerOffsetLocation = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(playerPed, 1.0, 0.0, 0.0); //Positie van de player-ped opvragen met een 1.0 offset op de x-as
   Ped spawnedPed = PED::CREATE_PED(26, model, playerOffsetLocation.x, playerOffsetLocation.y, playerOffsetLocation.z, 0.0, false, true); //Creeër een ped op de aangegeven locatie
   STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); //Model als niet langer nodig markeren
   notifyAboveMap("Chimp Spawned!"); //Tekst weergeven
  }
 }
 WAIT(0);
}
}

void ScriptMain()
{
main();
}

Resultaat

Tutorial_4_result.png

Download

Geplaatst:

Tutorial

Wapens

Om een wapen te spawnen/te geven aan een ped, hoeft niet het model eerst geladen te worden.

Wapen geven aan ped

het geven van een wapen aan een ped is zeer simpel, dat kan met de volgende native functie:

WEAPON::GIVE_WEAPON_TO_PED(PED, WAPEN HASH-KEY, AMMO, METEEN DRAGEN ,AMMO GEVULD);

Wanneer we dezelfde code gebruiken als bij de vorige tutorial dan krijg je bijvoorbeeld dit:

Hash WeaponHash = GAMEPLAY::GET_HASH_KEY("WEAPON_MINIGUN");
WEAPON::GIVE_WEAPON_TO_PED(spawnedPed, WeaponHash, 10000, true, true);

Resultaat

Tutorial_5.1_result.png

Download

Ammo status (niet meer herladen)

Als je in onderstaande code het volgende teken tegen komt: & of *, dan gaat het om een pointers, uitgebreide uitleg hierover is hier te vinden: cplusplus.com Pointers.

Als we ervoor willen zorgen dat we niet meer hoeven te herladen, dat dus de ammo steeds bijgevuld wordt, dan moeten we de volgende stappen doorlopen:

  1. Controleren of de speler bestaat
  2. Controleren welk wapen de speler momenteel draagt.
  3. Controleren of dit een geldig wapen is
  4. Controleren wat de maximale ammo in het magazijn is voor het huidige wapen
  5. De ammo in het magazijn gelijk stellen aan de het maximale in het magazijn.

Omdat we constant moeten controleren voor de ammo (dus niet enkel wanneer er op een knop o.i.d. gedrukt wordt), kan het voorkomen dat de speler niet bestaat (bijvoorbeeld tijdens wisselen tussen de personages), daarom moeten we controleren of de speler bestaat voordat we er iets mee kunnen doen. Omdat de speler een ped is, en omdat een ped een entity is, kunnen we controleren of de speler bestaat met de volgende native functie:

ENTITY::DOES_ENTITY_EXIST(ENTITY);

Als we zeker weten dat de speler bestaat dan kunnen we het huidige wapen opvragen. Dit doen we met de volgende native functie:

WEAPON::GET_CURRENT_PED_WEAPON(PED, &HASH-KEY, 1))

Als we het wapen achterhaald hebben dan kunnen we controleren of dit een geldig wapen is, dat doen we met:

WEAPON::IS_WEAPON_VALID(WAPEN HASH-KEY)

De volgende native functie kan gebruikt worden om de waarde te verkrijgen van de maximale hoeveelheid ammo in het wapen. Wanneer dit wapen geen ammo heeft dan geefte de functie de waarde false terug, anders true.

WEAPON::GET_MAX_AMMO(PED, WAPEN HASH-KEY, &MAXIMALE AMMO)

We kunnen ook de ammo in het hele wapen aanpassen met de volgende native functie:

WEAPON::SET_PED_AMMO(PED, WAPEN HASH-KEY, AMMO);

Om de waarde te verkrijgen van de maximale hoeveelheid ammo in een magazijn is, gebruiken we deze native functie:

WEAPON::GET_MAX_AMMO_IN_CLIP(PED, WAPEN HASH-KEY, 1);

Ammo in het magazijn aanpassen kan met de volgende native functie:

WEAPON::SET_AMMO_IN_CLIP(PED, WAPEN HASH-KEY, AMMO);

Wanneer we all deze functies op een logische manier gaan gebruiken, kom je bijvoorbeeld uit op dit:

while (true)
{
Ped playerPed = PLAYER::PLAYER_PED_ID(); //Ped van de speler opvragen
BOOL doesPlayerExists = ENTITY::DOES_ENTITY_EXIST(playerPed); //Controleren of de ped bestaat
if (doesPlayerExists){ //Wanneer de speler-ped bestaat
Hash weaponHash;
if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &weaponHash, 1)) //Wanneer de speler een wapen heeft + zet de wapen-hash-key in de variabel weaponHash
{
if (WEAPON::IS_WEAPON_VALID(weaponHash)) //Wanneer het wapen geldig is
{
 int maximumWeaponAmmo;
 if (WEAPON::GET_MAX_AMMO(playerPed, weaponHash, &maximumWeaponAmmo)) //Wanneer het wapen ammo kan hebben + zet de maximum ammo in de variabel maximumWeaponAmmo
 {
 WEAPON::SET_PED_AMMO(playerPed, weaponHash, maximumWeaponAmmo); //Pas de ammo aan zodat het wapen maximale ammo heeft
 int maximumAmmoInClip;
 maximumAmmoInClip = WEAPON::GET_MAX_AMMO_IN_CLIP(playerPed, weaponHash, 1); //Verkrijg de maximale in het magazijn van het wapen
 if (maximumAmmoInClip > 0) //wanneer de maximale ammo in het magazijn hoger is dan 0
 WEAPON::SET_AMMO_IN_CLIP(playerPed, weaponHash, maximumAmmoInClip); //Vul het magazijn totdat het maximaal gevuld is
 }
}
}
}
WAIT(0);
}



Download

Geplaatst:

Tutorial

Voertuigen

Spawnen van een voertuig

In deze tutorial worden er met modellen gewerkt, zorg ervoor dat je eerst de tutorial: Model laden hebt gelezen.

Voor het spawnen van een voertuig moeten we net zoals bij een ped eerst het model van het voertuig laden. In deze tutorial is er gekozen om het model "LAZER" te laden.

De stappen voor het laden zijn:

  1. Hash van de modelnaam opvragen
  2. Controleren of het model bestaat
  3. Model aanvragen
  4. Wachten tot het model geladen is
  5. Voertuig spawnen op een gegeven locatie
  6. Model als niet langer nodig markeren

De manier van laden kan worden ingezien in de tutorial: Peds.

Nadat het model geladen is kunnen we met de volgende native functie een voertuig spawnen:

VEHICLE::CREATE_VEHICLE(MODEL HASH-KEY,X LOCATIE, Y LOCATIE, Z LOCATIE, HOEK, 1, 1)

Om te zorgen dat het voertuig correct geplaatst is kunnen we de volgende native functie gebruiken:

VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(VOERTUIG);

Wanneer we een deel van de code gebruiken van de tutorial: Peds, dan komen we uit op dit resultaat:

 if (IsKeyJustUp(VK_F9)){
  Ped playerPed = PLAYER::PLAYER_PED_ID(); //PED ID van de speler ophalen
  Hash model = GAMEPLAY::GET_HASH_KEY("LAZER"); //Hash verkrijgen van het model met de naam LAZER
  if (STREAMING::IS_MODEL_IN_CDIMAGE(model) && STREAMING::IS_MODEL_VALID(model)) //Controleren of het model voorkomt in de game archiveven en of het model geldig is
  {
STREAMING::REQUEST_MODEL(model); //Model aanvragen
while (!STREAMING::HAS_MODEL_LOADED(model)) //Loopen totdat het model geladen is
 WAIT(0);

Vector3 playerOffsetLocation = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(playerPed, 5.0, 0.0, 0.0); //Positie van de player-ped opvragen met een 5.0 offset op de x-as
Vehicle spawnedVehicle = VEHICLE::CREATE_VEHICLE(model, playerOffsetLocation.x, playerOffsetLocation.y, playerOffsetLocation.z, 0.0, 1, 1); //Voertuig spawnen op de aangegeven locatie
VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(spawnedVehicle); //Zorg dat het voertuig goed op de grond staat
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); //Model als niet langer nodig markeren

notifyAboveMap("Vehicle spawned!"); //Tekst weergeven
  }
 }

Resultaat

Tutorial_6.1_result.png

Download

Gast
Dit onderwerp is gesloten.
  • Recent actief   0 leden

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