[Tutorial] /enter, /exit & pickups
#1

Deze tutorial is aangevraagd via de PM. Het leek me wel interessant om hier op in te gaan en vandaar dat ik het aanbod heb aangenomen om deze tutorial te schrijven. In deze tutorial zullen we twee commando's schrijven:
  • /enter - om een gebouw te betreden als je dichtbij genoeg bent
  • /exit - om het gebouw weer te verlaten
Om alles begrijpelijk te houden en voor allemaal toegankelijk te maken (als je dus iets anders gebruikt dan de traditionele manier - dcmd, ycmd, zcmd etc - dan kan je deze tutorial nog steeds volgen) gebruiken we strcmp in OnPlayerCommandText().

We gaan teleporteren naar interieuren nadat men op een bepaald punt '/enter' in heeft getypt.

Voorbereiding
Als eerste hebben we wat coцrdinaten nodig waar we de pickups neer gaan zetten. Deze pickups gebruiken we zodat het makkelijk te vinden is waar we het gebouw kunnen betreden. Deze coцrdinaten kunnen we later weer gebruiken.

De coordinaten zetten we in een variabele die we 'locations' noemen:
pawn Код:
new Float:locations[NUMBER_OF_POINTS][3] = {
 {X,Y,Z,}
};
Vergeet niet om NUMBER_OF_POINTS op je aantal posities te zetten (in de uiteindelijke versie die je van mij krijgt zijn dat er 7)
Wat we nu met deze coordinaten doen is er pickups van maken. Scroll (of CTRL+F > "OnGamemodeInit") naar OnGameModeInit() en plaats de volgende code hier in:
pawn Код:
for(new id = 0; id < sizeof(locations); id++)
{
    CreatePickup(1272, 2, locations[id][0], locations[id][1], locations[id][2]);
    // CreatePickup(modelID, type, X, Y, Z);
}
Het modelID wat in dit voorbeeld is gegeven is een blauw huisje. Deze kun je vervangen door je eigen icoontje en staan allemaal beschreven op de SA:MP wiki. Het type (2) is een icoontje wat respawnt na het oppakken ervan (Meer info hierover ook weer op de SA:MP wiki)

Wat gebeurt er nu in de bovenstaande code?
Wat we doen is het maken van pickups voor iedere locatie die je hebt aangemaakt in de variabele 'locations'.

Als je nu je code compileert dan zul je zien dat er geen foutmeldingen zijn en dat er leuke pickups staan te zweven op de locaties die jij hebt aangegeven. Tot nu toe erg leuk, maar zeer nutteloos (behalve dan dat je kan zien waar de huizen komen). Laten we er even een berichtje bij typen die aantoont wat je kunt doen met deze pickup (nou ja, wat er aan het einde van deze tutorial mee kan doen):
pawn Код:
public OnPlayerPickUpPickup(playerid, pickupid)
{
    SendClientMessage(playerid, 0x00FF00AA, "Type /enter to enter the building");
    return 1;
}
Let op: Dit is al een bestaande callback, plaats dit bericht er in of overschrijf de hele callback.
Nog een sidenote is: als je hier al code in hebt staan (dus je begint niet met een schone gamemode) dan wordt deze tutorial ineens heel anders. Dan zal je een extra variabele toe moeten wijzen aan je pickups en in OnPlayerPickUpPickup moeten controleren of de opgepakte pickup een van jouw pickups is!

We gaan nu verder met het aanmaken van de commands. Het is namelijk een beetje zinloos om het bericht er te hebben staan, maar dat het commando niet bestaat. Hier is het commando in pseudocode:
Код:
als het commando is ingetypt
    ga dan alle locaties bij langs
        controleer voor iedere locatie of de speler in de buurt is van de locatie
            als de speler in de buurt is van de locatie, zet dan de positie naar de hand van die locatie
            zet het interieur van de speler naar het bijbehorende interieur
Dit is hopelijk stof tot nadenken over hoe je je commando gaat opbouwen.
In de oude 0.2.2 tijd had iemand een handige methode gemaakt: IsPlayerInRangeOfPoint. Deze methode is nu al standaard bij de SA:MP server bijgeleverd dus kan je hem gelijk gebruiken. Deze methode controleert of de speler in de buurt is van een bepaald aangegeven punt. We kunnen ons commando nu als volgt opbouwen:

pawn Код:
if (!strcmp("/enter", cmdtext, true))
    {
        for(new id = 0; id < sizeof(locations); id++)
        {
            if(IsPlayerInRangeOfPoint(playerid, 2.0, locations[id][0], locations[id][1], locations[id][2]))
            {
                // teleport
                SetPlayerPos(playerid, toPoint[id][0], toPoint[id][1], toPoint[id][2]);
                SetPlayerInterior(playerid, toInterior[id]);
                SendClientMessage(playerid, 0x00FF00AA, "Type /exit to exit the building");
                return 1;
            }
        }
        SendClientMessage(playerid, 0xFF0000AA, "You need to be closer to a pickup to enter a building!");
        return 1;
    }
toPoint? toInterior?
Inderdaad. Om op te slaan waar we naar toe moeten teleporteren bij een bepaalde pickup hebben we een nieuwe variabele nodig: toPoint. Deze variabele bestaat uit allemaal floating point coцrdinaten waar de speler naar toe moet teleporteren:
pawn Код:
new toPoint[NUMBER_OF_POINTS][3] = {
    {X, Y, Z}
};
Nu is het (misschien) wel bekend dat, mocht je naar een interieur willen teleporteren, je ook het interieur op moet geven. Het zou makkelijk zijn als we dat bij onze toPoint konden doen maar het interieur is van een ander type dan een coцrdinaat. Een coцrdinaat is een Floating Point variabele en een interieur is een Integer. We zullen dan ook een nieuwe variabele moeten aanmaken met alle interieurs (in de volgorde van de locations en toPoint zodat je wel naar het goede interieur linkt):
pawn Код:
new toInterior[NUMBER_OF_POINTS] = {
    int
};
Nu zijn alle variabelen gebruikt en kan je je code weer compileren. Als het goed is dan zal deze geen problemen opleveren en kan je teleporteren..... en toen? Toen zat je vast in een interieur.

Laten we gaan... maar hoe?
Het is tijd voor ons /exit commando. We kunnen een /exit commando klakkeloos schrijven als: teleporteer naar een random punt buiten het interieur maar dat wil je waarschijnlijk niet. Je wilt terug naar waar je bent begonnen. Waar je stond voordat je binnenkwam. We hebben de locatie niet hoeven opslaan omdat we die locatie al hebben! Hij stond namelijk bij een pickup! De coordinaten van die pickups hebben we opgeslagen in 'locations' dus we teleporteren hem daar weer heen.

Hoe slaan we dat op?
We slaan het op in ons /enter commando. We gaan globaal een nieuwe variable aanmaken om te gebruiken:
pawn Код:
new isInInterior[MAX_PLAYERS] = -1; // -1 omdat positie 0 al een ID is
In onze /enter commando slaan we daarna op naar welk interieur we springen:
pawn Код:
isInInterior[playerid] = id;
Plaats de bovenstaande lijn boven de SendClientMessage en onder de SetPlayerInterior. Het is niet echt belangrijk waar hij precies staat als je hem maar in de IsPlayerInRangeOfPoint doet en voor de return 1; daarvan.

Nu we weten waar hij zich bevond kunnen we hem ook weer terugzetten in onze /exit. We springen weer even naar pseudocode om je hersenen aan het werk te zetten:
Код:
als het commando /exit is ingevoerd
    als de speler in een interieur is (dus isInInterior is anders dan -1)
        zet de speler terug naar de locatie waar hij was
Ik zal je niet in spanning houden en het commando geven:
pawn Код:
if(!strcmp("/exit", cmdtext, true))
    {
        if(isInInterior[playerid] != -1)
        {
            SetPlayerPos(playerid, locations[isInInterior[playerid]][0] + 5, locations[isInInterior[playerid]][1], locations[isInInterior[playerid]][2]);
            isInInterior[playerid] = -1;
            SetPlayerInterior(playerid, 0);
            SendClientMessage(playerid, 0xFFFF00AA, "Thank you for visiting! Come again!");
        }
        return 1;
    }
let op de +5 bij de X van SetPlayerPos (2e parameter). Dit is expres zo gedaan omdat je dan niet weer op de pickup springt en weer het berichtje 'type /enter to enter this building' krijgt.
Vergeet zeker niet om de speler weer terug te zetten naar de originele interieur (0) anders ziet de wereld er heel raar uit

Uiteindelijk ziet het er zo uit: Source code.

Veel plezier, of zoals DracoBlue het altijd zegt: "Happy coding"

PS: Als je op zoek bent naar de locaties van deze spawnpunten dan moet je zoeken op de eerste verdieping van LS international airport en op de grote stijger in ?verona beach?. Ze springen naar de raarste locaties. Het is allemaal test spul
Reply
#2

HANDIG!!
Reply
#3

Mooie tutorial, zal veel mensen op weg helpen,
tip: maak een 2e voorbeeldvariant met hotkeys (enter toets ipv /enter) aangezien de meeste mensen dit via een hotkey willen laten gaan !
Reply
#4

Quote:
Originally Posted by gamer931215
Посмотреть сообщение
Mooie tutorial, zal veel mensen op weg helpen,
tip: maak een 2e voorbeeldvariant met hotkeys (enter toets ipv /enter) aangezien de meeste mensen dit via een hotkey willen laten gaan !
Zoals genoemd was dit aangevraagd op deze manier, vandaar dat ik het zo heb geschreven Bedankt voor de tip though
Reply
#5

Quote:
Originally Posted by gamer931215
Посмотреть сообщение
Mooie tutorial, zal veel mensen op weg helpen,
tip: maak een 2e voorbeeldvariant met hotkeys (enter toets ipv /enter) aangezien de meeste mensen dit via een hotkey willen laten gaan !
Ik heb met /enter&/exit hotkey gewoon zo ongeveer:
NumPad1::t/enter ( En misschien nog wat zoals /me in RP servers)
NumPad2::t/exit ( En misschien nog wat zoals /me in RP servers)

Handig toch
Reply
#6

Oke een klein vraagje.
Wat als de interior achter de deur zit?(zoal bij mij het geval)

EDIT:
Gevonde: gewoon 0 XD
Reply
#7

Dit doet me er aan denken hier ooit nog eens een programmaatje voor te maken
Reply
#8

Dat zou cool zijnXD.
Mare ik heb een rare bug als ik bij 2 pickup /enter doet en later /exit wilt doen kom ik gewoon weer op die spawn plek.
De interior ids zijn nul omdat de spawn van de /enter namelijk gewoon aan de andere kant van de muur zit.
Reply
#9

Quote:
Originally Posted by justsomeguy
Посмотреть сообщение
Dat zou cool zijnXD.
Mare ik heb een rare bug als ik bij 2 pickup /enter doet en later /exit wilt doen kom ik gewoon weer op die spawn plek.
De interior ids zijn nul omdat de spawn van de /enter namelijk gewoon aan de andere kant van de muur zit.
Hoe bedoel je?

Het systeem zoals hier in de tutorial is beschreven is gemaakt voor 1 pickup tegelijk. De laatste zal hij dus steeds pakken. Het is geen Stack of iets dergelijks.

Of begrijp ik je nu verkeerd?
Reply
#10

Nee ik heb het probleem gevonden: Als je /exit doet dan kom je wel BIJ de /enter pickup maar niet op, oftewel omdat de spawn plek waar je komt als je /enter doet achter een muurtje zit krijg je dus het geval dat je wel weer bij de enter pickup komt net aan de verkeerde kant van de muur-_-".
Das gewoon op te lossen door de angle van de pickup te veranderen:P
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)