• 28 Mars 2024, 22:22:32


Auteur Sujet: [Aide] Comment savoir quel joueur à détruit un véhicule ?  (Lu 3397 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne 4L3X76

  • *
  • Nouveau
  • Messages: 2
    • Voir le profil
Bonjour à tous,

Je suis nouveau par ici, j'ai passé 1 an à scripter des serveurs SAMP, et je suis passé il y'a deux mois au scripting d'un petit serveur MTA San Andreas.

Je fais un petit code dont le but est de rajouter des bonus (d'XP) au joueur qui aurait détruit un véhicule ennemi (dans le cas où celui-ci contient lui même des ennemis), et d'en faire perdre si c'est un véhicule allié.
Il y'a moyen de trouver qui se trouvait dans le véhicule au moment de l'explosion, mais, après de longues recherches, je n'ai trouvé aucun moyen de savoir qui en est cause...

J'aimerais donc savoir s'il existe un moyen de savoir qui à détruit un véhicule.

Merci d'avance pour votre aide :)

Hors ligne Citizen

  • Scripteur LUA confirmé
  • *
  • Messages: 235
    • Voir le profil
    • Byston Evolution
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #1 le: 15 Mai 2012, 00:01:50 »
Bonsoir 4L3X76 ( alex76 c'est ça ? :D )

L'idée est intéressante, et en regardant un peut tous les events, j'ai trouvé cette event:
onClientPlayerWeaponFire
Pour l'instant, je ne vois que cette event comme solution car dans les arguments qu'elle envoie, il y a ceci:
hitElement: an element which was hit by a shot.

C'est du client-side par contre donc le plus simple c'est de vérifier si hitElement est un véhicule, et si la source de cette event est le joueur local ( getLocalPlayer() ) et si c'est le cas, il faut faire un triggerServerEvent( maFonction, getLocalPlayer(), hitElement). /!\ Voir EDIT à la fin de ce post /!\
INFO: j'ai mit getLocalPlayer() en tant que source de cette event car getLocalPlayer() permet de récupérer le joueur

Si je résume, pour chaque joueur qui va tirer sur un véhicule, il ( le joueur ) va dire à la fonction côté serveur:
"Ah tiens, je viens d’endommager ce véhicule"

Maintenant, il faut que la fonction côté serveur dise quelquechose du genre:
"Ok, je te mets en tant que dernier joueur ayant endommager ce véhicule."

Et que plus tard, dès qu'un véhicule explose, une fonction qui reçoit le "onVehicleExplode", aille vérifier quel était le dernier joueur à avoir endommager ce véhicule.
"Ok une voiture vient d'exploser, je vérifie qui était le dernier joueur à avoir endommager le véhicule, je vérifie si c’était un véhicule allié ou ennemi et je lui donne ou enlève des points en conséquences"


donc dans ta fonction maFonction( vehicleHited ), tu peux faire un
Code: (lua) [Sélectionner]
setElementData(vehicleHited, "lastAttacker", source)Info: la variable source est une variable créer par ton triggerServerEvent qui contient le joueur ( car on l'a mit en source de ce triggerServerEvent )
Là, on vient de faire:
Citer
"Ok, je te mets en tant que dernier joueur ayant endommagé ce véhicule."

ensuite:
Code: (lua) [Sélectionner]
fonction monAutreFonction()
   local theVehicle = source
   local lastAttacker = getElementData( theVehicle, "lastAttacker" )
   if ( getElementType( lastAttacker ) == "player" ) then
       if ( )then -- verifier si c'est un ennemie ou un allié par rapport à l’attaqueur
          -- lui donner ses points
       else
          -- lui en enlever
       end
end
addEventHandler( "onVehicleExplode", getRootElement(), monAutreFonction )
Et la on vient de faire:
Citer
"Ok une voiture vient d'exploser, je vérifie qui était le dernier joueur à avoir endommager le véhicule, je vérifie si c’était un véhicule allié ou ennemi et je lui donne ou enlève des points en conséquences"

Voilà je peux pas plus détaillé pour ce soir, je te laisse tester tout ça et si tu as des problèmes n'hésite pas.

A plus !

Citizen

EDIT: En réfléchissant un peu plus ce matin, on peut y apporter un légère modification qui va nous permettre de supprimer notre notre triggerServerEvent et la fonction maFonction()
Au lieu que ce soit le serveur qui dit qui à touché le véhicule en dernier, ça va être le joueur lui-même ( donc en client-side ) qui va dire au véhicule:
Citer
Je t'ai touché en dernier
Pour cela, il suffit de remplacer le
Code: (lua) [Sélectionner]
triggerServerEvent( maFonction, getLocalPlayer(), hitElement)par
Code: (lua) [Sélectionner]
setElementData(hitElement, "lastAttacker", source)car le setElementData est synchronisé entre le serveur et le client donc notre getElementData dans monAutreFonction fonctionnera très bien ;)

NOTE: ce code ne marchera que pour les armes à balles, ça ne marchera pas avec lances roquettes et autres armes explosifs :(
Il faudra un autre bout de code pour cela.

Bon codage !
« Modifié: 15 Mai 2012, 21:23:31 par Citizen »
The rEvolution is coming ...

vincentdu90

  • Invité
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #2 le: 16 Mai 2012, 14:39:08 »
Bonjour Citizen,

   Je viens de lire la réponse que tu as faite à Alex et je me demandais en regardant à quoi pouvait bien servir la fonction setElementData ?
J'ai bien une petite idée mais je voudrais en être sûr.  :)

Merci

Hors ligne Citizen

  • Scripteur LUA confirmé
  • *
  • Messages: 235
    • Voir le profil
    • Byston Evolution
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #3 le: 17 Mai 2012, 13:39:04 »
Salut Vincent,

( au passage, je viens de répondre à ton post sur les maps )

en gros, le setElementData permet de créer une sorte de variable propre à un élément.
c'est donc très pratique pour enregistrer des informations sur un véhicule comme son prix.
Tiens, c'est un bon exemple ça :D
Imaginons que je veuille mettre un véhicule à 20 000$, je vais donc faire:
Code: (lua) [Sélectionner]
function maFonction( thePlayer, cmd, arg1 )
-- on vérifie s'il est dans un véhicule grâce à getPedOccupiedVehicle
local vehicule = getPedOccupiedVehicle( thePlayer )
if ( vehicule == false ) then -- s'il n'est pas dans un véhicule
outputChatBox( "Vous devez être dans un véhicule !", thePlayer, 200, 0, 0 )
return
end
-- si la fonction arrive jusque là, cela veut dire qu'il est bien dans un véhicule
        local prix = tonumber( arg1 ) -- ( voir explications après )
if ( not prix or type( arg1 ) ) ~= "number" ) then
-- si le joueur n'a pas mit de prix ( s'il a juste tapé /prix )
-- ou si le prix qu'il a mit n'est pas un nombre
-- alors on lui affiche la synaxe en rouge
outputChatBox( "SYNTAXE: /prix [nombre]", thePlayer, 200, 0, 0 )
-- et on empêche la fonction de faire ce qu'il y a en-dessous
return
end
-- si la fonction arrive jusque là, cela veut dire qu'il:
-- - est bien dans un véhicule
-- - à bien mit un prix et que celui-ci est bien un nombre

-- on enregistre une information propre à ce véhicule ( le prix de celui-ci )
setElementData( vehicule, "prix", prix )

-- on récupère le prix de ce véhicule pour vérifier que ça à bien fonctionner
local leprix = getElementData( vehicule, "prix" )
-- et on l'affiche
outputChatBox( "Le prix de ce véhicule est maintenant de: "..leprix, thePlayer, 0, 200, 0 )
end
addComandHandler( "/prix", maFonction, false, false )
Je n'aurais plus qu'a taper /prix 20000 pour mettre le prix du véhicule dans lequel je suis.

Note: le 20000 que j'ai tapé est considéré comme du texte, c'est pour ça que j'ai fait un tonumber pour essayer de transformer la valeur de arg1 en nombre. Si c'est bien un nombre, il va nous mettre ce nombre dans la variable prix, sinon, il ne va pas réussir ( ex: /prix lol ou /prix 20XD ) et il va mettre nil à la place.
Donc type( arg1 ) ne sera pas égal à "number" mais à "nil" ( oui le type de variable de nil est nil :D )

J'espère que tu auras compris mon explication  :happy

Citizen
The rEvolution is coming ...

vincentdu90

  • Invité
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #4 le: 17 Mai 2012, 15:46:44 »
J'ai tout compris , ca comfirme bien ce que je pensais.
J'aimerai juste savoir à quoi servent les "return" ? Et si j'ai bien compris le " ~="number" sert à vérifier que c'est bien un nombre ?

Merci

Hors ligne Citizen

  • Scripteur LUA confirmé
  • *
  • Messages: 235
    • Voir le profil
    • Byston Evolution
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #5 le: 17 Mai 2012, 19:55:47 »
Citer
le " ~="number" sert à vérifier que c'est bien un nombre ?
Heuu nan, ~= veut dire "n'est pas égal"

et la fonction type() est une fonction lua qui permet de convertir en nombre.
donc
Code: (lua) [Sélectionner]
if ( type( mavariable ) ~= number thenveut dire en français: "Si le type de la variable mavariable n'est pas un nombre, alors ..."

sur le code plus haut, j'ai afficher un message d'erreur car ce qu'il a rentré n'est pas un nombre et j'arrête la fonction.

Citer
J'aimerai juste savoir à quoi servent les "return"
C'est pas très compliqué tu vas voir :P



En gros, le return permet d'arrêter la fonction et si l'on souhaite, de renvoyer une valeur.

Prenons par exemple cette fonction:
Code: (lua) [Sélectionner]
function multiplier( a, b )
local resultat = a*b -- on multiplie a et b et on met le résultat dans la variable
return resultat -- la fonction s'arrête ici et renvoie le résultat de la multiplication
outputChatBox( "Code pas exécuté !" ) -- ce code n'est pas exécuté car il est après le return
end

la même fonction mais en plus court:
Code: (lua) [Sélectionner]
function multiplier( a, b )
return a*b -- ici, il va d'abord multiplier a*b et renvoyer le résultat
end

Et je peux donc appeler la fonction comme ceci:
function maFonction()

-- j'appel la fonction multiplier pour qu'elle me multiplie 3 et 6
multiplier( 3, 6 )

end
addCommandHandler( "test", maFonction, false, false )

?? C'est bien joli, mais comment je récupère le résultat que la fonction essaye de me renvoyer ??

Et bien tout simplement comme ceci:
Code: (lua) [Sélectionner]
function maFonction()

-- j'appel la fonction multiplier pour qu'elle me multiplie 3 et 6
        -- je récupère le résultat que la fonction me renvoie, grâce au return, dans mavariable
local mavariable = multiplier( 3, 6 )
outputChatBox( "Le résultat de 3*6 est: "..mavariable )

end
addCommandHandler( "test", maFonction, false, false )

D'ailleurs, toutes les fonctions de MTA utilisent des return, par exemple la fonction setPlayerMoney:
Citation de: Wiki
Returns

Returns true if the money was added, or false if invalid parameters were passed.

Et ba dans cette fonction, elle va changer l'argent du joueur par le montant qu'on lui a dit puis vérifie que ça à fonctionné, si c'est le cas, elle va faire un return true, sinon elle va faire un return false.

Visualisation:
function setPlayerMoney( thePlayer, money )
-- instructions pour changer l'argent du joueur
if ( blabla ) then -- Si ça a fonctionné
return true -- elle renvoie true
else -- sinon
return false -- elle renvoie false
end
end

Donc comme t'as pu le voir, le return sans rien permet juste d’arrêter la fonction et un return suivie de quelquechose permet d’arrêter la fonction et d'envoyer ce quelquechose à l'endroit où la fonction a été appelée.

J'espère que tu as compris, et surtout n'hésite pas a faire des tests pour bien assimiler.

( Tu t'es approprié un peu le post d'4L3X76 :laugh )

Citizen

The rEvolution is coming ...

vincentdu90

  • Invité
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #6 le: 17 Mai 2012, 22:50:29 »
Ok ok je comprends mieux le principe des returns maintenant :).
En tout cas encore merci à toi , tex explications sont vraiment bien détaillés. Je vais essayer de mettre en place tout ça et je vais éviter de polluer ce sujet.

Encore Merci Citizen , vraiment généreux de ta part.

Hors ligne Citizen

  • Scripteur LUA confirmé
  • *
  • Messages: 235
    • Voir le profil
    • Byston Evolution
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #7 le: 18 Mai 2012, 10:34:27 »
Y'a aucun soucis, c'est mon rôle et j'aime bien partager mes connaissances de la façon la plus claire possible  :happy

Bon codage !

Citizen
The rEvolution is coming ...

Hors ligne 4L3X76

  • *
  • Nouveau
  • Messages: 2
    • Voir le profil
Re : [Aide] Comment savoir quel joueur à détruit un véhicule ?
« Réponse #8 le: 19 Mai 2012, 11:23:49 »
Salut à vous,

Merci beaucoup Citizen pour cette réponse rapide :D

Le code fonctionne très bien, je vais juste rajouter un timer de 5 ou 10 secondes pour mettre à nil le "lastAttacker", dans le cas où le véhicule exploserait beaucoup plus tard à cause d'un choc, ou autre...

Ce serait bien plus pratique s'il existait un évènement du genre "onVehicleTakeDamage", avec un paramètre "attacker", ou bien un paramètre "killer" à l'évènement "onVehicleExplode" ^^

Merci encore pour ton aide :D

PS: C'est bien Alex76, mais c'est la première fois que j'utilise ce pseudo (au cas où tu me prendrait pour quelqu'un d'autre ^^) :)
« Modifié: 19 Mai 2012, 11:25:32 par 4L3X76 »