• 28 Mars 2024, 18:49:03


Auteur Sujet: LUA Example : User selectable warp points.  (Lu 16662 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne spykerc8

  • *
  • 'The GTAOnline.fr GodFather'
  • Messages: 3821
    • Voir le profil
    • http://www.gtaonline.fr
LUA Example : User selectable warp points.
« le: 14 Janvier 2007, 18:59:23 »
Lien du script : à cette page

Démonstration du script :

[yt=250,250]OjuNWLmR3Pw[/yt]

Explications :

Dans ce script, nous allons créer un événement appelé Script_onResourceLoad, qui sera appelée quand le serveur chargera un mod/map qui contiendra cet évènement.

Ensuite nous allons créer une 'global key' pour activer ou désactiver le script. Les bindskey sont appelées pour assigner la touche à la fonction que nous allons créer.

Code: (lua) [Sélectionner]
AddEventHandler ( "onResourceLoad", getRootElement(), "Script_onResourceLoad" )
function Script_onResourceLoad ( resource )
    if ( resource == getThisResource() ) then
        -- for each player already in the server
        for index, player in getElementsByType ( "player" ) do
            -- binds the "i"-key to our function "modeIO"
            bindKey ( player, "i", "down", "modeIO" )
        end
    end
end

Il faut noter que l'on termine la fonction avec le mot 'end'.
Ceci dit, la fonction ne s'applique que aux joueurs déjà sur le serveur quand le script est appelé. C'est pourquoi, on va l'étendre à l'évènement onPlayerJoin.

Code: (lua) [Sélectionner]
addEventHandler ( "onPlayerJoin", getRootElement(), "Script_onPlayerJoin" )
function Script_onPlayerJoin ()
    -- binds the "i"-key to our function "modeIO"
    bindKey ( source, "i", "down", "modeIO" )
end

La key qu'on a défini est requise pour que les commandes d'origine n'interfèrent pas avec.


Faire marcher le curseur :

Spécifier un point précis avec une touche du clavier serait un peu compliquer, c'est pourquoi, MTA a de bonnes fonctions utilisant le curseur de la souris.
Voyons donc comment faire.
Il faut donc recréer la fonction  "modeIO" que l'on a vu précédemment :

Code: (lua) [Sélectionner]
function modeIO ( source, key, keyState ) -- function toggles the cursor
    if isCursorShowing ( source ) then -- if cursor was already showing:
        showCursor ( source, false ) --   hide it
    else -- if it wasn't showing:
        showCursor ( source, true ) --   show it
    end
end

Maintenant que nous avons trois fonctions et le curseur de la souris utilisable, le plus simple serait d'assigner chaque fonction à un bouton de la souris. C'est ce que nous allons faire.

MTA a un évènement appeler  "onPlayerClick" qui permet aux scripteurs de récupérer les coordonnées XYZ exactes du joueur. Cet évènement n'est possible que quand le curseur est visible.
Voyons comment faire la fonction principale "Script_onPlayerClick".

Code: (lua) [Sélectionner]
addEventHandler ( "onPlayerClick", getRootElement(), "Script_onPlayerClick" )
function Script_onPlayerClick ( key, keyState, element, x, y, z )
    if keyState == "up" then
        return -- ignore if the button was released
    end


Créer un marqueur :

Avant de faire ça, il faut voir comment fonctionne la hiérarchie des des éléments de MTA.
MTA utilise des 'elements' pour tout le langage. Les marqueurs, les objets, les véhicules, les joueurs, tous sont des 'elements'. Ces 'elements' rendent le codage plus facile car vous n'avez pas à vérifier de quel type d'élément il s'agit. Vous aurez juste à utiliser "destroyElement" ou "setElementPosition" pour ajouter ou supprimer un objet.

Dans cet exemple, nous ne voulons que deux marqueurs par joueur : un marqueur teleport et un marqueur "destination". Pour pouvoir avoir deux marqueurs, nous allons sauver l'ID du marqueur créer pour chaque joueur en utilisant "setElementData".

Si un utilisateur utilise le bouton gauche de la souris, cela créera un marqueur appeler "teleport" qui nous servira de porte de téléportation. Si l'utilisateur utilise le bouton droit de la souris, cela créera le marqueur de "destination".

Voyons comment coder les fonctions par rapports aux boutons :

Code: (lua) [Sélectionner]
if key == "left" then -- on a left mousebutton
    -- destroy his teleport point, if any
    destroyElement ( getElementData ( source, "teleport" ) )
    -- create a normal cylinder marker
    local marker = createMarker ( x, y, z, "cylinder", 2, 0, 255, 0, 50 )
    -- mark the cylinder as our "teleport" type
    setElementData ( marker, "type", "teleport" )
    -- link the creator (player) to the marker, and vice versa
    setElementData ( source, "teleport", marker )
    setElementData ( marker, "owner", source )
 
elseif key == "right" then -- on a right mousebutton
    -- destroy his destination point, if any
    destroyElement ( getElementData ( source, "destination" ) )
    -- create a glowing corona
    local marker = createMarker ( x, y, z+1, "corona", 1, 0, 255, 255, 50 )
    -- mark the corona as our "destination" type
    setElementData ( marker, "type", "destination" )
    -- link the creator (player) to the marker, and vice versa
    setElementData ( source, "destination", marker )
    setElementData ( marker, "owner", source )

Nous utilisons ici "setElementData" pour sauver les données des marqueurs pour le joueur.
"setElementData" et son partenaire,  "getElementData" intéragissent tous les deux avec les données de la fonction.
Ces données agissent donc comme une sorte de base de donnée qui sauvegarde les infos attachées à un 'element'. On peut par exemple attaché une valeur à un 'element' et l'utiliser plus tard avec "getElementData".

A part créer des marqueurs, on peut également faire des fonctions pour télécharger les joueurs où ils le souhaitent.

Code: (lua) [Sélectionner]
elseif key == "middle" then -- on a middle mousebutton
    -- teleport the player to whereever he clicked
    setElementPosition ( source, x, y, z+1 )
end

Téléporter le joueur :

Nous venons donc de créer des marqueurs, avec leurs propres évènements.
Pour que le script sache si le joueur est rentré dedans, il faudra donc utiliser une fonction pour le lui dire. Cette fonction est "onMarkerHit".

Code: (lua) [Sélectionner]
addEventHandler ( "onMarkerHit", getRootElement(), "Script_onMarkerHit" )
function Script_onMarkerHit ( player )

Maintenant il va falloir utiliser les données mises en mémoire dans la fonction "Script_onPlayerClick"  pour savoir de quel marqueur il s'agit.  Cela sera soit "teleport", soit "destination". On ne va agir que si le joueur entre dans un  marqueur "teleport".

Code: (lua) [Sélectionner]
    -- if the marker is a teleport point, proceed
    if getElementData ( source, "type" ) == "teleport" then
        -- get the owner linked to the "teleport" type marker
        local owner = getElementData ( source, "owner" )
        -- get the destination point linked to the owner
        local destination = getElementData ( owner, "destination" )
        -- if the destination point exists, proceed
        if destination then
            -- get the "destination" marker's position
            local x, y, z = getElementPosition ( destination )
            -- finally, warp the player there
            setElementPosition ( player, x, y, z )
        end
    end
end


Nettoyage du code :
Pour finir on va nettoyer le code et les infos pour chaque joueur. Cela est nécessaire si l'on ne veut pas qu'un marqueur reste après que le joueur ait quitter le serveur.
Tout comment l'évènement "onPlayerJoin", on dispose d'un évènement "OnPlayerQuit" qui est appelée quand un joueur quitte le serveur.

Code: (lua) [Sélectionner]
addEventHandler ( "onPlayerQuit", getRootElement(), "Script_onPlayerQuit" )
function Script_onPlayerQuit ( reason )
    --destroy his teleport point, if any
    destroyElement ( getElementData ( source, "teleport" ) )
    -- destroy his destination point, if any
    destroyElement ( getElementData ( source, "destination" ) )
end



CODE COMPLET :

Code: (lua) [Sélectionner]

-- :: MTA Scripting Tutorial I - User selectable warp points
-- http://www.mtasa.com/tutorial1.html
--
-- (C) The MTA Team, 2007
-- www.mtasa.com

addEventHandler ( "onMapLoad", getRootElement(), "Script_onMapLoad" ) --This event tells what happens when the map loads.
function Script_onMapLoad ()
for index, player in getElementsByType ( "player" ) do --For each player in the server,
bindKey ( player, "i", "down", "modeIO" ) --Bind the player's "i" key to the function "modeIO" when the key is pressed
end
end
 
addEventHandler ( "onPlayerJoin", getRootElement(), "Script_onPlayerJoin" ) --This event tells what happens when a player joins.
function Script_onPlayerJoin ()
bindKey ( source, "i", "down", "modeIO" ) --Bind the player's "i" key to the function "modeIO" when the key is pressed
end
 
function modeIO ( source, key, keyState ) --This function toggles the cursor on/off
if isCursorShowing ( source ) then --If cursor was already showing,
showCursor ( source, false ) --then hide it;
else --if it wasn't showing,
showCursor ( source, true ) --then show it.
end
end
 
addEventHandler ( "onPlayerClick", getRootElement(), "Script_onPlayerClick" ) --This event tells what happens when a player clicks on the screen with the cursor.
function Script_onPlayerClick ( key, keyState, element, x, y, z )
if keyState == "up" then return end --Don't do anything if he's releasing the button.
if key == "left" then --If it's left-click:
destroyElement ( getElementData ( source, "teleport" ) ) --Destroy his teleport point, if any
local theMarker = createMarker ( x, y, z, "cylinder", 2, 0, 255, 0, 50 ) --Create a cylindric marker
setElementData ( theMarker, "type", "teleport" ) --Mark the cylinder as a teleport
setElementData ( source, "teleport", theMarker ) --Link the creator to the teleport
setElementData ( theMarker, "owner", source ) --Link the teleport to its creator
 
elseif key == "right" then --If it's right-click
destroyElement ( getElementData ( source, "destination" ) ) --Destroy his destination point, if any
local theMarker = createMarker ( x, y, z+1, "corona", 1, 0, 255, 255, 50 ) --Create a glowing corona
setElementData ( theMarker, "type", "destination" ) --Mark the corona as a destination point
setElementData ( source, "destination", theMarker ) --Link the creator to the teleport
setElementData ( theMarker, "owner", source ) --Link the teleport to its creator
 
elseif key == "middle" then --If it's middle-click
setElementPosition ( source, x, y, z+1 ) --Teleport the player to where he clicked.
end
end
 
addEventHandler ( "onMarkerHit", getRootElement(), "Script_onMarkerHit" ) --This event tells what happens if a player steps inside a marker.
function Script_onMarkerHit ( player )
if getElementData ( source, "type" ) == "teleport" then --If the marker is a teleport point,
local owner = getElementData ( source, "owner" ) --Get the owner linked to the teleport point.
local destination = getElementData ( owner, "destination" ) --Get the destination point linked to the owner.
if destination then --If destination point exists,
local x, y, z = getElementPosition ( destination ) --Get the destination point's position.
setElementPosition ( player, x, y, z ) --Put the player there.
end
end
end
 
addEventHandler ( "onPlayerQuit", getRootElement(), "Script_onPlayerQuit" ) --This event tells what happens if a player disconnects.
function Script_onPlayerQuit ( reason )
destroyElement ( getElementData ( source, "teleport" ) ) --Destroy his teleport point, if any
destroyElement ( getElementData ( source, "destination" ) ) --Destroy his destination point, if any
end
« Modifié: 15 Janvier 2007, 11:53:32 par spykerc8 »


~ Leader honoraire de la FsK Team ~ -
~ Membre honoraire de la PCP Team ~

Co-fondateur de GTAO - Retraité de la communauté

"Nous ne sommes rien, soyons tout !"


Hors ligne Grounch

  • Le seul Russe du forum
  • *
  • Bandit
  • Mafieux en stage
  • Messages: 327
    • Voir le profil
Re : LUA Example : User selectable warp points.
« Réponse #1 le: 14 Janvier 2007, 20:49:49 »
Ah oui quand meme, rien que pour se teleporter :ninja

Hors ligne spykerc8

  • *
  • 'The GTAOnline.fr GodFather'
  • Messages: 3821
    • Voir le profil
    • http://www.gtaonline.fr
Re : LUA Example : User selectable warp points.
« Réponse #2 le: 16 Janvier 2007, 13:19:26 »
En lisant le code complet, c'est assez compréhensible, ceci dit, quand on connait pas le C, comme moi, c'est carrement impossible de coder à l'instinct..


~ Leader honoraire de la FsK Team ~ -
~ Membre honoraire de la PCP Team ~

Co-fondateur de GTAO - Retraité de la communauté

"Nous ne sommes rien, soyons tout !"


Hors ligne Grounch

  • Le seul Russe du forum
  • *
  • Bandit
  • Mafieux en stage
  • Messages: 327
    • Voir le profil
Re : LUA Example : User selectable warp points.
« Réponse #3 le: 16 Janvier 2007, 17:47:17 »
Ptet que sa me motivera a apprendre un language au moins.

 :dling :dling :dling :dling :dling :dling :dling :dling :dling :dling

ps: bon ok j'arete avec ce smiley

Hors ligne DeadPixel

  • Designer attitré et maître du monde en puissance.
  • *
  • Nouveau
  • I'M WITH STUPID ^
  • Messages: 12
    • Voir le profil
    • DeadPx.fr
Re : LUA Example : User selectable warp points.
« Réponse #4 le: 01 Février 2007, 17:55:03 »
Site du zéro, cours de C et C++ pour apprendre... en partant de zéro, comme des incultes que nous sommes. Mieux vaut s'y mettre maintenant ;)
FOR SERIOUS.