-
Posts
1,803 -
Joined
-
Last visited
-
Days Won
8
Everything posted by Citizen
-
1 et 2: Ta fonction MortCriminel est exécutée à chaque fois que quelqu'un meurt sur le serveur. Il faut donc savoir si le joueur qui vient de mourir est bien le criminel choisit par notre fonction BlipCriminel. On va utiliser les fonctions set/get ElementData comme ça je répondrai en même temps à ta deuxième question. Un élément data est une variable/donnée que l'on peut "attacher" à un élément et identifié par une clé (véhicules, markers, joueurs etc). Par exemple, si je veux ajouter une variable qui permet de savoir combien de fois le joueur X est mort depuis qu'il s'est connecté. Lorsqu'un joueur se connecte, je vais lui mettre un element data qui va s'appeler "morts" et le mettre à 0. function playerConnected() setElementData(source, "morts", 0) --d'après le wiki, source est le joueur qui vient de se co. end addEventHandler("onPlayerJoin", root, playerConnected) Donc là à chaque fois qu'un joueur se connectera, l'element data "morts" vaudra 0. Maintenant on veut que lorsqu'il meurt, on lui rajoute +1 à son nombre de morts. fonction playerDeath() local nbMorts = getElementData(source, "morts") --on récupère la valeur de la clé "[b]morts[/b]" setElementData(source, "morts", nbMorts+1) end addEventHandler("onPlayerWasted", root, playerDeath) C'est donc très pratique pour rajouter des variables persos sur des éléments. On pourrait aussi par exemple faire un système de lock sur les voitures. Imaginons qu'un joueur tape /lock dans un véhicule, on mettrait la clé "locked" sur le véhicule à true et si quelqu'un veut rentrer dans le véhicule (y a un event pour ça), tu vérifies si la clé vaut true et si c'est le cas, tu annules l'event (tu peux annuler des events) du coup le joueur ne pourra pas le carjacker. Pour annuler un event: cancelEvent(). Voici donc ma correction: j'ai aussi mit un element data pour le blip et le marker pour être en mesure de les récupérer car un variable local est détruit au premier end qui suit (la variable, pas l'objet). function BlipCriminel ( thePlayer ) local Criminel = getRandomPlayer () if Criminel then local BlipCriminel = createBlipAttachedTo ( Criminel, 23 ) local PickUpCriminel = createPickup ( 0, 0, 0, 3, 1254 ) attachElements ( PickUpCriminel, Criminel, 0, 0, 5 ) setElementData(Criminel, "isCriminel", true) setElementData(Criminel, "attachedBlip", BlipCriminel) setElementData(Criminel, "attachedPickup", PickUpCriminel) outputChatBox ("Le Criminel aléatoire est : "..getPlayerName(Criminel)..", poursuivez et tuez cette personne.", getRootElement(), 255, 0, 0, true) else --Afficher à l'auteur de la commande que le criminel n'a pas pu être choisit --C'est impossible de retrouver dans ce cas là, car si cette fonction à été appelée, c'est forcement -- par un joueur qui a tapé la commande, donc il y a forcement quelqu'un sur le serveur. outputChatBox ("Le Criminel aléatoire n'a pas pu être choisit (personne sur le serveur) !", thePlayer, 200, 0, 0) end end addCommandHandler ("CrimiAleatoire", BlipCriminel) function MortCriminel () if ( getElementData(source, "isCriminel") == true ) then destroyElement ( getElementData(source, "attachedBlip") ) destroyElement ( getElementData(source, "attachedPickup") ) outputChatBox ("Le Criminel "..getPlayerName(source).." a été éliminé.", getRootElement(), 0, 255, 0, true) end end addEventHandler ("onPlayerWasted", getRootElement(), MortCriminel) -------------------------------------------------------------------------------------------------- 3: Hummm t'essayes d'utiliser un mod qui ne convient pas à ce que tu veux faire car il faut définir les différents levels dans le fichier levels.xml. Je pense que la solution la plus simple serait de remplir ce xml: <levels> <level name = "level 1" experienceRequired = "1000" /> <level name = "level 2" experienceRequired = "2000" /> <level name = "level 3" experienceRequired = "3000" /> <level name = "level 4" experienceRequired = "4000" /> <level name = "level 5" experienceRequired = "5000" /> etc ... </levels> Après on pourrait faire un truc générique comme ça les levels sont infinis, mais il va falloir casser le système de ce mod pour gérer ça nous même. -------------------------------------------------------------------------------------------------- 4: Déjà tu nous as donné qu'une partie de ton code côté client et évidemment c'est pas là que se trouve le problème. Dans ton client tu dois avoir un addEvent("DEBUTcompteur") Hors, le wiki mentionne bien qu'il y a un deuxième paramètre qui est optionel et qui est par défaut false. Il permet de dire si cet event peut être "triggered"/appelé depuis l'autre côté via un triggerClientEvent ou triggerServerEvent. Par "autre côté", j'entends bien sur que si ton addEvent est du côté client, l'autre côté est le côté serveur et vice-versa. Donc si t'as bien compris, il te faut créer ton event comme ceci: addEvent("DEBUTcompteur", true) Et sinon t'as mis: function Countdown ( source ) D'abord source est une variable "invisible" que les events envoit à la fonction (mais pas en paramètre de celle-ci). Mais en plus tu ne l'utilise pas, donc tu peux le virer de partout. Ouf ! Enfin finit J'espère que mes explications on été clair et que tu as bien compris tes erreurs et l'utilisation des element datas. BONUS: Tu peux largement réduire ton code et la répétition pour le compteur comme ceci: local x, y, sx, sy = 450, 150, 250, 200 function Countdown( number ) if not number then number = 3 end if number > 0 then local img = "images/"..number..".png" if not imagecount then imagecount = guiCreateStaticImage (x, y, sx, sz, img, false) else guiStaticImageLoadImage( imagecount, img ) end setTimer(Countdown, 1000, 1, number-1) elseif number == 0 then guiStaticImageLoadImage( imagecount, "images/GO.png" ) guiSetSize( imagecount, sx+70, sy) --pour mettre sx à 320 setTimer(Countdown, 3000, 1, number-1) else destroyElement( imagecount ) end end
-
Hmmm you right, then this: local editBox = guiCreateEdit(0.3,0.1,0.4,0.1,"",true) addEventHandler("onClientGUIChanged", editBox, function() local text = guiGetText(source) or "" if tonumber(text) then return end local newText = "" for k=0, #text do local char = string.sub(text, i, i) if tonumber(char) then --it's a number newText..char end end guiSetText(source, newText) end)
-
Here is the more simple checker that you can do: local editBox = guiCreateEdit(0.3,0.1,0.4,0.1,"",true) addEventHandler("onClientGUIChanged", editBox, function() local text = guiGetText(source) or "" if not tonumber(text) then --if the text isn't a number (statement needed to prevent infinite loop) guiSetText(source, string.gsub(text, "%a", "")) --Remove all letters end end) It will remove all letters that are written into a memo or an editbox. Here I used an editbox at line 1, be sure to paste this addEventHandler right after the creation of your editbox and replace the variable at line 2 to match your editbox variable. EDIT: Oh and you only can write rounded numbers, you can't write a number like this: 100.5
-
Where are the modifications we asked you to put in ?? I also did a bit of the code you had to do yourself. You need a server side code and modify some stuff in your client-side code.
-
Yeah we got it, and Solidsnake just gave you the way to do it: On the server side, get the value of the setting you seted in the meta with the get function. Once you got it, send it on the client side with the triggerClientEvent function. On the client side, just get the value that was sent and store it in a global variable (variable that doesn't have the local keyword). And in your drawText function, do something like this: function drawText() --local r,g,b = (0,128,255) local color = myGlobalColor or tocolor(0, 128, 255) [...] dxDrawText(theText, leftB, topB, left, top, color, ...) [...] end
-
Damn it ! Was so close ! I thought ipairs could be used with table that references values with keys and that I'll be able to use index instead. But actually, it just should be used with tables that uses index instead of keys.
-
No you can create a donator group in the ACL just like for the admins and manually put the donators in that group.
-
Ok try this (copy-paste everything): DestructionDerby = setmetatable({}, RaceMode) DestructionDerby.__index = DestructionDerby DestructionDerby:register('Destruction derby') function DestructionDerby:isApplicable() return not RaceMode.checkpointsExist() and RaceMode.getMapOption('respawn') == 'none' end function DestructionDerby:getPlayerRank(player) return #getActivePlayers() end -- Copy of old updateRank function DestructionDerby:updateRanks() for i,player in ipairs(g_Players) do if not isPlayerFinished(player) then local rank = self:getPlayerRank(player) if not rank or rank > 0 then setElementData(player, 'race rank', rank) end end end -- Make text look good at the start if not self.running then for i,player in ipairs(g_Players) do setElementData(player, 'race rank', '' ) setElementData(player, 'checkpoint', '' ) end end end function endTheMap() RaceMode.endMap() end function DestructionDerby:onPlayerWasted(player) if isActivePlayer(player) then self:handleFinishActivePlayer(player) if getActivePlayerCount() <= 0 then endTheMap() else TimerManager.createTimerFor("map",player):setTimer(clientCall, 2000, 1, player, 'Spectate.start', 'auto') end end RaceMode.setPlayerIsFinished(player) showBlipsAttachedTo(player, false) end function DestructionDerby:onPlayerQuit(player) if isActivePlayer(player) then self:handleFinishActivePlayer(player) if getActivePlayerCount() <= 0 then endTheMap() end end end function checkForHunter(number,pickType,model) if #getElementsByType("player") <= 0 then return end local activePlayers = getActivePlayers() if #activePlayers == 1 then local vehicle = getPedOccupiedVehicle(activePlayers[1]) if getElementModel(vehicle) == 425 then setElementHealth(activePlayers[1],0) end end end addEvent('onPlayerPickUpRacePickup',true) addEventHandler("onPlayerPickUpRacePickup", getRootElement(), checkForHunter) function DestructionDerby:handleFinishActivePlayer(player) -- Update ranking board for player being removed if not self.rankingBoard then self.rankingBoard = RankingBoard:create() self.rankingBoard:setDirection( 'up', getActivePlayerCount() ) end local timePassed = self:getTimePassed() self.rankingBoard:add(player, timePassed) -- Do remove finishActivePlayer(player) -- Update ranking board if one player left local activePlayers = getActivePlayers() if #activePlayers == 2 then triggerClientEvent ( "savetag3",getRootElement(),_getPlayerName(player)) end if #activePlayers == 1 then triggerClientEvent ( "savetag2",getRootElement(),_getPlayerName(player)) end if #activePlayers == 0 then self.rankingBoard:add(activePlayers[1], timePassed) triggerClientEvent ( "savetag",getRootElement(),_getPlayerName(player)) triggerEvent("peds",getRootElement()) --triggerEvent("onPlayerDestructionDerbyWin", getRootElement(), player) --saveDeathPlayer(activePlayers[1]) --addPodiumPlayer(activePlayers[1]) local timeravviato = false if timeravviato == false then setTimer (checkForHunter , 100, 0, player ) timeravviato = true end end if #activePlayers == 1 then --showMessage(getPlayerName(activePlayers[1]) .. ' pwned you all!', 171, 7, 7) triggerClientEvent ( "Winnertext", getRootElement(), activePlayers[1] ) triggerEvent("onPlayerDestructionDerbyWin", getRootElement(), activePlayers[1]) local car = getPedOccupiedVehicle(activePlayers[1]) if car then local model = getElementModel(car) if model == 425 then setElementHealth(activePlayers[1],0) end end end end ------------------------------------------------------------ -- activePlayerList stuff -- function initializeCurrentRaceMode() g_CurrentRaceMode = {} g_CurrentRaceMode.activePlayerList = getElementsByType("player") g_CurrentRaceMode.finishedPlayerList = {} end addEventHandler("onResourceStart", resourceRoot, initializeCurrentRaceMode) addEvent("onMapStarting", true) -- not sure if needed addEventHandler("onMapStarting", root, initializeCurrentRaceMode) function isActivePlayer( player ) return table.find( g_CurrentRaceMode.activePlayerList, player ) end function addActivePlayer( player ) table.insertUnique( g_CurrentRaceMode.activePlayerList, player ) end function removeActivePlayer( player ) table.removevalue( g_CurrentRaceMode.activePlayerList, player ) end function finishActivePlayer( player ) table.removevalue( g_CurrentRaceMode.activePlayerList, player ) table.insertUnique( g_CurrentRaceMode.finishedPlayerList, _getPlayerName(player) ) end function getFinishedPlayerCount() return #g_CurrentRaceMode.finishedPlayerList end function getActivePlayerCount() return #g_CurrentRaceMode.activePlayerList end function getActivePlayers() return g_CurrentRaceMode.activePlayerList end ---- !!! DELETE THIS PART ONLY IF THE SERVER ASK YOU TO DELETE table.find !!! ---- if type(table.find) == nil then _G.table.find = function(t, d) if t == nil or d == nil or type(t) ~= "table" then return nil end for k, i in ipairs(t) do if i == d then return true end end return false end else outputDebugString( "table.find function is already defined, you can delete it !", 2) end ---- !!! DELETE THIS PART ONLY IF THE SERVER ASK YOU TO DELETE table.insertUnique !!! ---- if type(table.insertUnique) == nil then _G.table.insertUnique = function(t, d) if t == nil or d == nil or type(t) ~= "table" then return nil end for k, i in ipairs(t) do if i == d then return false end end return table.insert(t, d) end else outputDebugString( "table.insertUnique function is already defined, you can delete it !", 2) end ---- !!! DELETE THIS PART ONLY IF THE SERVER ASK YOU TO DELETE table.removevalue !!! ---- if type(table.removevalue) == nil then _G.table.removevalue = function(t, d) if t == nil or d == nil or type(t) ~= "table" then return nil end for k, i in ipairs(t) do if i == d then return table.remove(t, k) end end return false end else outputDebugString( "table.removevalue function is already defined, you can delete it !", 2) end And I don't understand this function: function checkForHunter(number,pickType,model) It will just kill the last guy that still alive and just got the hunter. But if he is the last guy, the game il already over and he can't get the hunter (imo) So I'm pretty sure that you can delete it since you are doing right at the end of the handleFinishActivePlayer method.
-
Did you try with my code ? If yes then I need the error that is in the clientscript.log: Mine is here: C:\Program Files (x86)\MTA San Andreas 1.3\MTA if this log file is too big to be opened, then just delete it and retry to do the open command. If you are admin in the ACL, then you also can use this command: debugscript 3 and you will get a little message box at the bottom of your script that will show you the errors/warning/infos from the server and client side.
-
Hummm why not using a showCursor( false ) when you want the cursor to be hidden ? I have to admit that I don't really understand your problem. I just understood that the cursor is already enabled when you join the server and it looks like you don't want this behaviour.
-
Don't use SQL functions that you don't know what it does. So it will only return a number, not a table with the datas we want to get ... Try this: Server -- vehTable = { } Delete this ! function openVehWindow(thePlayer, cmd) local acc = getAccountName(getPlayerAccount(thePlayer)) local vehRes = executeSQLQuery("SELECT vehicle, vehiclePrice FROM vehicles WHERE account=?", acc) if type(vehRes) == "table" and #vehRes > 0 then triggerClientEvent("openVehWindow", getRootElement(), vehRes) else outputChatBox("You don't have any vehicles!", thePlayer, 255, 0, 0) end end addCommandHandler("open", openVehWindow) Client -- vehTable = { } Delete this ! function showVehWindow(vehicles) vehicleWindow() if (vehWdw ~= nil) then guiSetVisible(vehWdw, true) guiSetInputEnabled(true) showCursor(true) centerWindow(vehWdw) guiGridListClear(veh_vehGrid) -- empty the grid for i, tableRow in ipairs(vehicles) do -- tableRow will contain 1 row that has 2 columns (vehicle and vehiclePrice) local row = guiGridListAddRow(veh_vehGrid) guiGridListSetItemText(veh_vehGrid, row, 1, tableRow[1], false, false) guiGridListSetItemText(veh_vehGrid, row, 2, tableRow[2], false, false) end end end If you were using the table vehTable just tell me how (on both side) because you don't need it imo. Best regards, Citizen
-
no he wants to hide the topbarchat and the regular chatbox.
-
No just remove that line from your meta.xml: <export function="outputTopChat" type="client"/> This line must only be in the meta of the resource that provides that function. The second thing you must do is to start the resource that contains that fonction in order to be called.
-
Hummm peut être que le plus important à été oublié. C'est une team de quoi ? Seules les personnes qui connaissent les serveurs FFS et KOG peuvent deviner. Je pense que c'est du DM ou DD vu que tu parles de campeurs. (Je ne suis pas du tout intéressé en tout cas) Cordialement, Citizen
-
Hummm no, there is now way to get the positions of the world models as far I know. The only way you can achieve this is to recreate the entire map in the map editor but it will take a lot of time !
-
As far I can see, the topbarchat doesn't let you show or hide it, maybe you will have to create a new exported function to the tobachat resource to let you get control on this (and probably a variable that you will use in an if statement you will have to add too in the render function). If you don't see what I mean, xXMADEXx will probably add this feature four you.
-
Well ... https://community.multitheftauto.com/
-
You failed to copy the IIYAMA's code, don't forget the ")" after the last end, it's not an error.
-
Well, there is nothing wrong in this code (just some bad copied-pasted instructions that could be in a seperate function to make this code cleaner. There can be 2 possibilities: - Another resource is conflicting with the dayz spawn system. - There is a code client-side that moves the player's camera. Try to check every functions that is "attached" with the event "onClientPlayerDayZLogin". But first try to comment the line 277: triggerClientEvent(player, "onClientPlayerDayZLogin", player) and check if it solves the problem. If it doesn't then there are a lot of chances to be the 1st possibility.
-
wut ? O_o what kind of magic is it ?!
-
First, why aren't you using local variables for drawY, nameWidth and teamWidth (95, 112 and 113) ? Also drawY is never used ... Second, why are you drawing 2 texts at line 116 and 117 ? Since only the color will change, only the second text (117) will be visible for the player. I'm guessing that it was for testing purposes. And I couldn't understand the y calculation of the texts It's looking like you tried random magic numbers untill you got the clan text at the position you wanted at. You should get the text height of the player name, adding it to the y player name text and add a margin to get a little space between the two lines/texts. Third, why are they two times the same if statements (121to123 and 124to126) ?? I'm guessing you want to draw the classicon on the left and on the right of the drawn texts. Well, you should put the two dxDrawImage in only one if statement. If you can't see the images, there is 2 possible issues: - the getElementData or the fileExists return false (or maybe both) so you never enter in that statement. You can easily check it by adding an outputChatBox before the 2 dxDrawImage like this: if getElementData(player, "Classicon") and fileExists ( ":Class/class/classicon_"..getElementData(player, "Classicon")..".png" ) then outputChatBox("I'm in !!") --It will flood your chatbox so remove it once you checked dxDrawImage ( sx - math.max(nameWidth/2, teamWidth/2) - imageSize - 1*scale, sy - imageSize, imageSize, imageSize, ":Class/class/classicon_"..getElementData(player, "Classicon")..".png" ) dxDrawImage ( sx + math.max(nameWidth/2, teamWidth/2) + 1*scale, sy - imageSize, imageSize, imageSize, ":Class/class/classicon_"..getElementData(player, "Classicon")..".png" ) end If it's flooding your chatbox with "I'm in !" then this wasn't the problem. - The second one is just that your images are drawn out of the screen. So try to output the calculated position (x and y) of the images. if it's under 0 or over your screen resolution, then that's the problem. Best regards, Citizen PS: Hey Solidsnake, it's been a long time I hope you still remember me (we were basically fighting to be the first to find the solutions ). And according to the number of messages, you stayed active all the time. I'm slowly coming back to MTA Cheers !
-
Just to let you know because no one mentioned this: You could set an high priority on your addEventHandler so that your function would be call before all others.
-
Can you post again your code as it is right now ? Thanks
-
Et oui ! je viens juste de revenir dans MTA avec beaucoup plus de motivation que lorsque j'ai "arrêter" !