Jump to content

[Résolu] Problème d'écriture dans une table


Recommended Posts

Bonjour, après de multiples essais, j'ai enfin obtenu ce que je voulais, enfin, presque... Mon problème et que j'ai fait un créer une fonction permettant de vérifier les véhicules possédés par le joueur, de les écrire dans une table pour ensuite les inscrires sur un "tableau" si on peut appeler ça comme sa.

J'ai identifié le porblème mais n'arrive pas à le régler, le problème et que comme j'utilise onClientRender, les véhicules ne vont pas s'arrêter de s'ajouter à la table, pour mieux comprendre, voici un screen:

1456927206-sans-titre-1.jpg

On peut voir, premièrement que je possède une "Sanchez" et un "Monster 3", mais ce n'est pas le sujet principal, ce qui nous intérresse, c'est la répétition infinie de ceux-ci (à un tel point que le texte sort même du tableau :D).

Vu que le texte se répète, la fonction n'est pas dur à imaginer, mais je compte quand même vous la prêter:

vehs = {} 
function getPlayerVehicles(player) 
    posV = 1 
    for i,v in ipairs (getElementsByType("vehicle")) do 
        local owner = getElementData(v, "owner") 
        local pName = getPlayerName(player) 
        if (owner == pName) then 
            local vName = getVehicleName(v) 
            table.insert(vehs, posV, vName) 
            posV = posV + 1 
        end 
    end 
    return table.concat(vehs, " | ") 
end 

Ce que je n'arrive pas à faire, c'est empêcher cette duplication du texte, pour vous aider, je met aussi la fonction qui appel celle-ci:

function Infos() 
    --[...]-- 
    local vehs = getPlayerVehicles(localPlayer) 
    --[...]-- 
    dxDrawText("Véhicules: "..vehs, screenW * 0.3968, screenH * 0.5664, screenW * 0.6032, screenH * 0.5924, tocolor(255, 255, 255, 255), 1.00, "default", "left", "center", false, false, false, false, false) 
    --[...]-- 
end 

J'ai déjà essayer de pacer la table dans la fonction (après le "PosV = 1") mais le problème était pire puisque ducoup, la table se revidais en boucle :)

J'ai tout dis de mon avis (enfin... pour le moment :D) et je vais vous laisser me sauver tel des Super-Héros (même si vous en êtes pas, fin... je crois).

Sur ce, merci d'avance pour l'aide ;)

Edited by Guest
Link to comment
  • Moderators

Il suffit juste de ne pas faire de table.insert dans ton onClientRender.

J'ai séparer ta fonction en 2 dont chacune à son rôle définit:

-- S'occupe juste de mettre à jour pVehicles (à appeler lors d'un achat et vente d'un veh) 
function updatePlayerVehicles() 
    pVehicles = {} 
    for i,v in ipairs (getElementsByType("vehicle")) do 
        local owner = getElementData(v, "owner") 
        local pName = getPlayerName(localPlayer) 
        if (owner == pName) then 
            table.insert(pVehicles, v) 
        end 
    end 
end 
addEvent("onPlayerVehiclesChanged", true) 
addEventHandler("onPlayerVehiclesChanged", localPlayer, updatePlayerVehicles) 
  
-- Va retoruner "Sanchez | Monser 3" 
function getPlayerVehiclesStr() 
    local vehStr = "" 
    for k, v in ipairs( pVehicles ) do 
        local vehName = getVehicleName(v) 
        vehStr = vehStr + vehName 
        if k < #pVehicles then 
            vehStr = vehStr + " | " 
        end 
    end 
    return vehStr 
end 

La première se charge juste de mettre à jour la table pVehicles et va contenir la liste des véhicules (et non pas leurs noms) que le joueur possède. Cette fonction est à appeler à chaque fois qu'il y aura une modification dans la liste des véhicules possédés par le joueur.

Comme j'imagine que ce genre de modification sera réalisé du côté serveur, j'ai fait en sorte que tu puisses appeler cette fonction, qui est du côté client via la ligne suivante:

triggerClientEvent(player, "onPlayerVehiclesChanged", player) 

la variable player doit évidemment être le joueur qui à réalisé la modification (achat, vente).

La deuxième se charge de construire ton "tableau" en parcourant la liste des véhicules et en les mettant à la suite dans un string et en les séparant via un pipe ("|"). Ça sera la méthode à appeler dans ton onClientRender:

function Infos() 
    --[...]-- 
    local vehStr = getPlayerVehiclesStr() 
    --[...]-- 
    dxDrawText("Véhicules: "..vehStr, screenW * 0.3968, screenH * 0.5664, screenW * 0.6032, screenH * 0.5924, tocolor(255, 255, 255, 255), 1.00, "default", "left", "center", false, false, false, false, false) 
    --[...]-- 
end 

Avec ces modifications là, ça devrait fonctionner comme tu le souhaites.

Link to comment

Ah ouai, j'y avais pas pensé... à force de vouloir faire compliqué, je ne pense plus à ce qui est simple (malheureusement), Merci d'avoir pris le temps de répondre alors que la solution était toute simple (et surtout alors que j'avais la réponse devant les yeux, et ce, dans tous les sens tu terme) et j'éspère ne plus chercher compliqué quand il faut faire simple.

Pour pas te laisser dans le doute, ce que je pensait faire avant d'avoir ton aide était de vérifier si un véhicule était déjà présent dans la liste, si il y était, vérifier que ce ne soit pas le même véhicule pour enfin définir si oui ou non le véhicule devait s'ajouter à la table. Quand je dis que je cherchais compliqué, c'est que je cherchais vraiment trop loin :D

Link to comment
  • Moderators

Oui ça aurait fonctionner mais au niveau perfs ça n'aurait pas été terrible.

Il faut éviter d'exécuter du code trop compliqué/long a exécuter dans un onClientRender.

En plus dans ton cas, la valeur afficher (la liste des véhicules) ne va pas changer souvent pour un joueur (aller, grand maximum 10 fois dans le mois xD).

Imaginons qu'un joueur fait tourner son jeu à 30FPS, ton code allait boucler sur TOUS les véhicules présent sur le serveur (potentiellement >500 vehs), en récupérant le owner et reconstruisant la table et tout ça 30 fois par seconde !! (et 60fois/s pour 60FPS etc).

Tu aurais utilisé pas mal de ressource pour rien et qui aurait pu être utiliser pour autre chose.

Il vaut mieux recalculer la table que quand il y en a besoin (lorsque le joueur se connecte, lorsqu'il achète, et lorsqu'il vend ou échange un véhicule).

On aurait pu encore améliorer les perfs en évitant de reconstruire le string que retourne getPlayerVehiclesStr pour exactement le même raisons (tu peux le faire si tu veux en mettant le string en global que tu utiliseras directement dans ton dxDrawText). Mais le gain de perfs pour cette fonction sera minime.

Le onClientRender est très pratique mais il faut faire attention à ce qu'on lui fait faire. A utiliser avec précaution !

Cordialement,

Citizen

Link to comment
On aurait pu encore améliorer les perfs en évitant de reconstruire le string que retourne getPlayerVehiclesStr

C'est ce que je vient de faire car il était impossible d'additionner 2 strings (d'après le debugscript qui m'affichait gentilement "[...] to perform arithmetic on local 'vehStr' (a string value)"

C'est donc depuis mon repassage (je sais pas si je peut le dire parce que sa me donne l'impression da parler de vêtements) que le tout marche. Et en ce qui concerne l'actualisation de la liste, j'ai préféré qu'elle s'actuallise juste avant d'afficher le tableau, c'est toujours mieux sachant que je n'ai pas finis mes scripts du carshop ^^

Encore merci de m'avoir aidé et je n'ai plus qu'à passer le sujet en "Résolu" ;)

Link to comment
  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...