Jump to content

Ceeser

Members
  • Posts

    38
  • Joined

  • Last visited

Posts posted by Ceeser

  1. Hey, renderTargets are squares and I want to display a circle by cutting out a part of the renderTarget.

    I've been trying the HUD Mask Shader, but that gives a weirdly distorted output image for some reason.
    Somebody told me that it is possible to "cut out" a circle from an input image using dxSetBlendMode and dxDrawCircle.
    I've been trying out a bit but it seems like I can't find a solution.. is it even possible to "cut images" using dxSetBlendMode and dxDrawCircle?

    Or even, like how does "overwrite" behaves? If I use dxDrawCircle(X, Y, r, 0, 360, tocolor(0, 0, 0, 0) I still see it as a black circle with 255 alpha - why?

  2. It seems like "forumConnection" simply doesn't exist ( "got nil" ).

    Where and how do you define/create it? (hide data like ip/login/password!)

    also:

    Why do you use

    if (mysql_ping(forumConnection) == false) then

    twice in the function? Does..

     

    		destroyForumConnection()
    		openForumDatabase(nil)

    establish a new connection between the 2 if's?

  3. I found, what's causing the problem I have.
    But idk how to write shaders, so not why it’s doing that..

    Im using the HUD Mask Shader of the MTA Wiki and somehow that shader causes the distortion.

    The Yellow lines represent my viewing angle and the yellow circle is the section visible on the radar.
    I drew the renderTarget (as source) on fullscreen and on the left side is the radar.

    spacer.png

    As you can see on the RenderTarget - Yellow Circle all lines are straight as wanted.
    On the radar the shades are shifted like a dxDrawRectangle rectangle cant even look.
    The radar gets drawn through the shader, so the shader has to do that to the renderTarget.


    Is there any other Mask Shader I could try?

  4. Yes, the player.png gets drawn from that path (line 68) - Should I create a texture for it too to speed up drawing?
    But that's anyways the only radar blip, for the player (and this is fine)^^

    Everything else gets created by the script (and shaped by the mask shader which gets drawn - line 67)
    But the problem is even before that, the renderTargets of the objects that get rendered are somehow "bend" if the objects rotation isn't "straight" like 0°, 90°, etc. (line 39 and 40, "object.rotZ").

    The base rotation of the renderTargets are also fine, but the corners are not 90° which doesnt make much sense since renderTargets can only have 90° corners..
    If the Object has a rotation of (like in the screen) 24° or sth the renderTarget basically gets rendered like this:
    spacer.png
    ..and that doesn't make any sense to me.

  5. There are a few things unknown to us, so its hard to help you at all.

    For example, how does currentCell gets defined / clicked / selected?
    Why are you looping through in a numeric for-loop and (as it seems) above the maximum => "maxRows + currentCell"?

    If you used only snippets, better post the complete code, at least with all important stuff thats needed for what you wanna do.

  6. Hey, I'm currently working on a minimap / radar that shows objects.

    And now I noticed that somehow my renderTargets are distorted/warped if drawn at objects rotation, example:
    spacer.png

    The objects that are at 0° rotation look straight, but the objects at 24° rotation are wierdly distorted.
    Ingame View of that: (to make the actual straight line - that should be visible on the radar - more clear I changed the color of the shades) spacer.png

    I hope you get my point.
    It shouldn't even be possible, that a renderTarget (the shade-image get created and colored by the script) gets bend like that..
    There is no parameter like for distortion in dxDrawImage, wtf
    .spacer.png

    These yellow lines is how it should get displayed - in a straight line, or am I dumb?
    Is there any reason why that happens and/or any way I could fix it?

    To the code:
    tl;dr: There is litterally nothing that could cause the effect visible on the radar
     

    Spoiler
    
    function getFilteredObjects()
    	for _, object in pairs(getElementsByType("object")) do
    		local iModel = getElementModel(object);
    
    		if (tblSupportedModelIDs[iModel]) then -- Only create renderTargets for supported models
    			if (not tblModelValues[iModel]) then -- Prevent dublications
    				tblModelValues[iModel] = getModelValues(object);
    			end
    		end
    	end
    end
    
    function getModelValues(uObject)
    	local iMinX, iMinY, iMinZ, iMaxX, iMaxY, iMaxZ = getElementBoundingBox(uObject);
    
    	local iSizeX, iSizeY = iMaxX - iMinX, iMaxY - iMinY;
    	local uRenderTarget = dxCreateRenderTarget(iSizeX, iSizeY);
    
    	dxSetBlendMode("modulate_add");
    	dxSetRenderTarget(uRenderTarget);
    	dxDrawRectangle(0, 0, iSizeX, iSizeY);
    	dxSetRenderTarget();
    	dxSetBlendMode("blend");
    
    	return {img = uRenderTarget, sizeX = iSizeX, sizeY = iSizeY};
    end
    
    function renderFilteredObjects(uObject)
    	dxSetBlendMode("modulate_add");
    	dxSetRenderTarget(Radar.renderTarget);
    
    	for model, modelObjects in pairs(tblFilteredObjects) do
    		for _, object in pairs(modelObjects) do
    			local posX, posY = convertCoordinatesToPixels(object.posX, object.posY);
    			local sizeX = tblModelValues[model].sizeX;
    			local sizeY = tblModelValues[model].sizeY;
    
    			dxDrawImage(posX - sizeX / 2, posY + sizeY / 2, sizeX, sizeY, tblModelValues[model].img, object.rotZ, 0, 0, tocolor(0, 0, 0, 64)); -- Shadow
    			dxDrawImage(posX - sizeX / 2 + 1, posY + sizeY / 2 + 1, sizeX - 2, sizeY - 2, tblModelValues[model].img, object.rotZ, 0, 0, tblSupportedModelIDs[model]); -- Object
    		end
    	end
    
    	dxSetRenderTarget();
    	dxSetBlendMode("blend");
    end
    
    function renderRadar()
    	local posX, posY = getElementPosition(localPlayer);
    	local uCamTarget = getCameraTarget();
    
    	posX = 0.5 - (Map.maxX + iRenderTargetExtraSpace - posX) / Map.sizeX;
    	posY = 0.5 - (Map.maxY + iRenderTargetExtraSpace - posY - 2.5) / Map.sizeY;
    
    	if (not uCamTarget) then
    		uCamTarget = localPlayer;
    	end
    
    	if (uCamTarget) then	
    		local _, _, iCameraRotation = getElementRotation(getCamera());
    		local _, _, iVehicleRotation = getElementRotation(uCamTarget);
    
    		dxSetShaderValue(uMaskShader, "gUVPosition", posX, posY);
    		dxSetShaderValue(uMaskShader, "gUVScale", 1 / iRadarZoom, 1 / iRadarZoom);
    		dxSetShaderValue(uMaskShader, "gUVRotAngle", math.rad(iCameraRotation + 180));
    
    		dxDrawImage(Radar.posX + Radar.size, Radar.posY, -Radar.size, Radar.size, uMaskShader);
    		dxDrawImage(Radar.posX + Radar.size / 2 - iPlayerSize / 2, Radar.posY + Radar.size / 2 - iPlayerSize / 2, iPlayerSize, iPlayerSize, "images/player.png", iCameraRotation - iVehicleRotation);
    	end
    end
    addEventHandler("onClientRender", root, renderRadar);

     

     

  7. That actually makes a difference.. Well for elementData you could do that:

     

    funciton getRichestPlayer()
    	local tblPlayersMoney = {};
    
    	for _, player in pairs(getElementsByType("player")) do
      		table.insert(tblPlayerMoney, {player = getPlayerName(player), money = getElementData(player, "money")});
      	end
    
    	table.sort(tblPlayersMoney, function (a, b) return a.money > b.money end);
    
    	for i, v in pairs(tblPlayersMoney) do
      		outputChatbox("Place " .. i .. " is " .. v.player .. " with " .. v.money .. "$", 255, 255, 255, true);
      	end
    end

     

  8. Hey, for a UI lib I want to create textures for all image files included to the resource.
    So when it starts, it calls the function to load the images, create and store textures for them.
    My problem is now, how to get all image paths / names?
    Since the meta.xml doesn't get downloaded, the client file cant open the meta.xml and search for file src's (like i tried in the example).
    Manually use downloadFile("meta.xml") doesnt work and using the event "onClientFileDownloadComplete" to get the names of downloaded images doesn't work as well.

    Example: (What ive tried)

    function loadTextures()
        local sourceResource = sourceResource or getThisResource(); -- This is if the call comes from another resource to load in the images of that resource
        local strResourePath = ":" .. getResourceName(sourceResource) .. "/";
        local tblImages = loadMetaImages(strResourePath);
    
        if (tblImages) then
            for _, image in pairs(tblImages) do
                local strName = removeImagePath(image);
    
                if (ELIB.textures[strName]) then
                    outputDebugString("@ELIB - loadTextures: Dublicated image name found in" .. strResourePath .. " old image overwritten!", 2);
                end
    
                ELIB.textures[strName] = dxCreateTexture(image, "dxt5", true, "clamp");
            end
        end
    end
    
    function loadMetaImages(strResourePath)
        local uFile = xmlLoadFile(strResourePath .. "meta.xml");
    
        if (uFile) then
            local tblImages = {};
    
            for _, node in ipairs(xmlNodeGetChildren(uFile)) do
                if (xmlNodeGetName(node) == "file") then
                    local strImagePath = xmlNodeGetAttribute(node, "src");
                    if (string.find(strImagePath, ".png") or string.find(strImagePath, ".jpg") or string.find(strImagePath, ".dds")) then
                        table.insert(tblImages, strImagePath);
                    end
                end
            end
    
            return tblImages;
        end
    end
    
    function removeImagePath(strPath)
        while (string.find(strPath, "/")) do
            strPath = string.sub(strPath, 2);
        end
    end

     

  9. Hello guys,

    A while ago I've been thinking "saving data is pretty annoying.. alot of lines, you are often doing it multiple times for different scripts."
    So I decided to make a resource as a central handler of data storing/loading.

    Now I want to share this resource to the community and hope that it will also help you save some time at scripting.

    The resource (including its functions) are added to the MTA Wiki which can be found here.

     


    What is xmlData?


    xmlData is a resource that provides 3 shared (so server-  and client-side) exported functions for automated saving/loding/deleting of files:

    xmlSaveData require the data it should store to be a table and xmlLoadData will return the data as a table.

    These functions are exported function by the resource, so you need to call them.
    Example:

    local xml = exports.xmlData
    local tbl = {posX = 500, posY = 300, sizeX = 300, sizeY = 200}
    
    -- Saving
    xml:xmlSaveData("myFileName", tbl, false, true) -- This will save the file non-serverProtected but encrypted
    -- or you can do this
    xml:xmlSaveData("myFileName", tbl, 7) -- This will save the file serverProtected, encrypted, resourceProtected
    
    -- Loading
    local myTable = xml:xmlLoadData("myFileName", 7) -- This will attempt to load the data saved in highest security level
    -- Note: You need to load the data on the same security level as you saved it.



    Data security


    This resource also gives you ways to secure the data you want to store:

    • Server protection -- If a file is server protected, only the server that has created it is able to read/modify it
    • Encryption -- If a file is encrypted humans won't be able to read/modify it
    • Resource Protection -- If a file is resource protected only a resource with the same name is able to read/modify it

    Combining these parameters will give you different levels of security for your file.
    For simplification you can instead of passing booleans just pass the security level you want to have (see the functions syntax please)

    • 0 - No protection (any server, any resource or humans could read/modify)
    • 1 - Very low protection (creator resource on any server or humans could read/modify)
    • 2 - Very low protection (any resource on any server could read/modify, humans cant)
    • 3 - Low protection (only creator resource on any server could read/modify, humans cant)
    • 4 - Medium protection (any resource on the creator server or humans could read/modify) - Default setting if no 'security parameters' are given
    • 5 - Medium protection (only creator resource on the creator server or humans could read/modify)
    • 6 - High protection (any resource on the creator server could read/modify, humans cant)
    • 7 - Very high protection (only creator resource on creator server could read/modify, humans cant)

     

    Other uses


    You can ofc use this script for example to save protected login data, but you can also use it in these ways for example:

    • Cross-Resource communication: You could save a file called "settings" in resourceA and then load it in resourceB. Like this you have an easy way to make your server resources talk with each other without the need of events, exported functions and passing arguments. (if the file is not resourceProtected)
    • Cross-Server communication: One step further could be that for example mapping script settings could be synchronized between different mapping servers (if the file is not serverProtected)

     

    Download


    The download for this resource can be found on the MTA Community page.
    Note: This resource does not require admin/any acl rank.

    I hope you like it and it will save you some work ;)


    Sincerely,
    Ceeser

    • Like 2
  10. Hello scripters and the ones who want to become a scripter,
     

    since a few days I've been frequently visiting this site and I often see problems that shouldnt even exist or some that can easily be fixed by knowing what you do.
    So thats why I wanted to make this topic to give some general instructions about how to script
    And by 'how to script' I don't mean that I'll teach you scripting, instead I would like to give you some tips and guidelines which you can follow to improve scripting, debugging, remembering your script.

     


    1. Variables


    Okay, lets start with some instructions to Lua:
    Lua is a very beginners-friendly 'programming language'. In Lua itself there are only a few syntaxes you need to remember, it doesnt cry if you use or dont use brackets at some points etc.
    The variables are type-undefined which is nice for an easy use, but also a point where you can lose track of what you are doing. For example:

     

    local myVariable = 1234 -- I gave this variable the value 1234 now
    
    -- some stuff in the script between
    
    myVariable = "asdf" -- Now I overwrote 'myVariable' with a string

    Lua is fine with that. You can do it. BUT it's very bad practice.
    By doing this you can easily break your script if you lose track of your script somewhere and actually need the number instead of a string.

    That's the point for my first tip:

    1.1: Hungarian Notation

    Hungarian Notation actually comes from other programming languages, but it's a nice way to declear your variables in Lua as well.
    Using Hungarian Notation basically means: Add the variable type as a prefix to your variables name.
    This will immediatly help you knowing what type your variable will / should contain. (And let you know that you made a mistake somewhere if there is a wrong type)

    I personally use these prefixes for variables (Lua, MTA specific):

    • i = integer (any number value - ignoring float, double, unsigned etc since Lua doesnt care if your number is an integer (round value), float (comma value) or positive/negative
    • str = string (string means a combination of characters, a-z, A-Z, 0-9 - yes, numbers can also be displayed as characters in a string, and all sorts of special characters)
    • tbl = table (a list / array of variables)
    • u = userdata (players, vehicles, objects, timers, ... all MTA elements are a kind of userdata)
    • f = function (yes, you can also store a function in a variable for faster/easier to handle/more performant use.

    Code examples:

    local iPositionLeft = 500; -- i = The name describes that this variable is meant for numbers only and I will never put another type in it.
    local strMessage = "Hello World"; -- This is a string (str)
    local tblPositions = {x = 200, y = 333, z = 1234}; -- This is a table/array

     

    Okay, now that we have the correct prefixes it's time for part 2:
    1.2: Proper names for variables

    Give all variables a proper name which you remember and from which you know what its meaning/what its purpose.
    I know, programmers are lazy - but writing a few more characters will help you later on. Example:

     

    -- The following variables are no joke. They actually exist in a script of a server-lobby.
    local x,y = guiGetScreenSize() 
    local l_sizeX,l_sizeY = x/9,x/4/4.5
    local l_posX,l_posY = x/2-l_sizeX/2,y/70
    local l_alpha = 0
    local r_scrollX = 0
    local r_px,r_py,r_size = x/2-x/10/2,y/2,x/10
    local a_size = x/40
    local a_posX,a_posY = x/2-a_size/2,y/2-a_size
    local a_posY_d = 0
    -- When you define these variables like this you may know what they mean.. but take a look into the script a few days later or even
    -- weeks/months later.. have fun searching for every single variable. And if another scripter sees this script - rip.
    
    -- Instead of doing the stuff as above, better do it like this:
    SX, SY = guiGetScreenSize(); -- define the screen sizes properly as global instead of seperate for every client script.
    
    local iLoginSizeX = SX / 2;
    local iLoginSizeY = SY / 2;
    local iLoginPosX = SX / 2 - iLoginSizeX / 2;
    local iLoginPosY = SY / 2 - iLoginSizeY / 2;
    ...
    
    -- Like this you immediatly know what each variable means.. but it takes alot of space to declear each variable. Please read below.

    Also, as you see in the example above: I really do recommend to seperate words by an uppercase character.. what is more readable:

    local iloginsizex = SX / 2;
    local iLoginSizeX = SX / 2;

     


    Now, since our variables are well defined and readable, lets move to the next step:
    1.3: Constants and variables that belong together

    Tables are a nice way to sort and organize your variables - especially when you have to deal with UI rendering.
    Rendering an UI can be a pain in the ass or fun to make, depending on how you do it imo.
    I personally always use a 'constants_c.Lua' file (_c describes that its defined as client file in meta and used on client side only).
    Inside that file I create all variables that will be used often inside a table of the name it belongs to.
    This will help you organize your script even more and saves alot of performance, because you dont need to calculate every number onClientRender anymore.
    It can also help you remembering positions etc - so faster scripting for UI's.
    Also, make a difference between "normal" variables and constants. Constants don't really exist in Lua, so you have to make your own rules.
    Constant mean that they will never be overwritten by a script (exception: If you can drag/move a panel or whatever they can be recalculated).
    Give a constant variable an full-uppercase name so that you immediatly see that it is a constant. (mainly for positioning variables)
    Additionaly, store them in a table with the name it belongs to. (POS as a general positions table, sub-names as element specified names)
    I personally only name the variable name itself with a lowercase character and without hungarian notation in a positions table. Example:
     

    -- So instead of declearing these variables
    local SX, SY = guiGetScreenSize();
    local iLoginPosX = SX / 2;
    ....
    
    -- Do this: Create a constants_c.Lua file and define all variables there as global.
    SX, SY = guiGetScreenSize(); -- Define the screen size X and Y once for the whole resource
    
    POS = {}; -- Global positions table
    POS.LOGIN = {}; -- Login specific positions table
    POS.LOGIN.sizeX = SX / 2; -- sizeX of the login
    POS.LOGIN.sizeY = SY / 2;
    POS.LOGIN.posX = SX / 2 - POS.LOGIN.sizeX / 2;
    POS.LOGIN.posY = SY / 2 - POS.LOGIN.sizeY / 2;
    -- If we now render a rectangle 'dxDrawRectangle(POS.LOGIN.posX, POS.LOGIN.posY, POS.LOGIN.sizeX, POS.LOGIN.sizeY, white)'
    -- The 'login window rectangle' will be perfectly centered
    
    -- For other UI 'elements' continue like this:
    POS.SCOREBOARD = {};
    ...
    
    -- Yes I know, usually you dont have a login panel and scoreboard in the same resource.. this is just an example.

     

    1.4: Globals and performance

    Basically every variable you didn't define as 'local' is a global variable, but global variables are accessable from any script of the resource (ofc split to client and server side).
    This will cost some performance - so try to define everything as local if you can, you can even define functions as a 'local function XY()'
    Even (global) math functions like math.sin can be defined as 'local sin = math.sin' to save some performance if you use it often (onClientRender + for loop as example)

    If you want to make a (non-constant) variable globally accessable (so for multiple scripts inside the resource) always mark it as a global by putting g_ infront of the variables name.
    This will help you notice its a global, non-constant variable and prevent unwanted overwriting / name-duplications.

     

    2. Debugging

    Debugging is a very important part of programming, especially if you are new to scripting / the type of script you are doing.
    (PS: Dont be afraid of making bugs.. programming is 50% creating bugs and 50% fixing bugs until you get what you want^^)
    MTA offers several ways of debugging:

    • outputChatBox - The mose obvious one, but it will/can spam the chat, errors in onClientRender using this debug method can also cause lag and it gives only the information you enter - useless for most debugs. - Only use this for test-wise debugging, alone.
    • outputDebugString - This is the one you should take for debugging and information outputs, you can also specify errorType and color.
    • iprint - A bit lazy, huh? Joke. This one has its 'i' for a reason: Its itelligent. It's displaying various datatypes without requiring tostring - it can even display table structures
    • More detailed information on screen? Use dxDrawText and display the information you need where you want it to be.

     

    3. Help

    For any problem you have there is a solution - thats for sure. But if you need help, the best practice is not to make a big shout-out for help on any mta-scripting-help-forum, instead:
    Please try to fix the problem yourself - make several tests / experiment around, because by finding out what you have done wrong you will learn the most.
    If you immediatly ask for help and get a finished solution you basically learned nothing about it - always remember that: Testing will help yourself improve.

    If you cant find a solution: MTA Wiki is your friend. Its well documented and give you any information you need about any implemented function.
    Maybe search for the function you have problems with or utility (aka 'useful') functions that users have created.
    In many cases you can find a solution by searching in the wiki.

    In the case you really cant find any solution there are some free sites to ask like this mta-sa scripting forum or the ffs-gaming scripting forum.

    I bet you will find somebody who can help you with any problem there if you cant find any solution.

     

    4. Script organizing

    Organizing each script, documentation and comments can help you alot.
    When writing code,  simply add a comment ('-- text') behind some importent lines while the comment should explain what it does / for what reason as short but understandable as possible.
    Seperate your code in several sections so that its easier to find functions that are somehow connected (if you have multiple render functions, put them all in a '-- Render' section for example)
    Also organize your script by adding a (lets call it:) 'namespace' to each script - so each script get its own table (defines as local or global as you need) - THIS IS NOT OOP! Example:

    -- ************************************************************************************************************************** --
    -- VARIABLES, EVENTS AND INFO --
    
    local Login = {}; -- Define the scripts "namespace", this is now local - so for this script only, not for the resource.
    Login.show = true;
    Login.accEdit = guiCreateEdit(0, 0, 0, 0, "");
    Login.passEdit = guiCreateEdit(0, 0, 0, 0, "");
    Login.selectedEdit = Login.accEdit; -- The selected edit (focused) to enter characters in
    
    -- ************************************************************************************************************************** --
    -- RENDERING --
    
    function Login.render() -- Yes, this function is basically a variable of "Login".
        if (Login.show) then 
            -- Render login window
        end
    end
    
    -- ************************************************************************************************************************** --
    -- CLICKING --
    
    function Login.click(strButton, strState)
        if (strState == "down") then
            -- Handle clicking of login window
        end
    end
    
    -- ************************************************************************************************************************** --
    -- START AND STOP --
    
    function Login.start()
        addEventHandler("onClientClick", root, Login.click);
        addEventHandler("onClientRender", root, Login.render);
    end
    addEventHandler("onClientResourceStart", resourceRoot, Login.start);
    
    function Login.stop()
        removeEventHandler("onClientClick", root, Login.click);
        removeEventHandler("onClientRender", root, Login.render);
    end

     

    5. Stick to one language

    Yes i know, this can sometimes be hard, but its nevertheless way better than a mix of different languages.
    English is ofc the language you should chose if you can, because its the most spoken/known language in the world.
    This can not only improve your english skills, it will also help others alot if they see your script for help/revision/enhancement.



    Thats it for now, this topic might be continued.
    If you have questions, simply write a comment, maybe I'll add the answer to this topic.

  11. local relX = valueX / screenW -- this will return a 0.X value, so the relative you need

     

    But in general I really recommend to use dxDraw values in a different way:

     

    SX, SY = guiGetScreenSize(); -- Define the screen variables global for all scripts inside the resource (NO local!)
    
    -- Then draw by dividing that
    dxDrawLine(SX / 2, SY / 4, SX / 2, SY / 2, tocolor(255, 165, 0, 255));
    -- Draws a vertical line from SY / 4 to SY / 2 (so from 1/4 of you screens height to your screen center)

     

    • Like 1
  12. MarkerBike = createMarker(1086.3326416016,-1802.1416015625,12.60143661499, "cylinder", 1.5, 255,255,255,50)
    BlipLS = createBlipAttachedTo(MarkerBike, 33)
    setBlipVisibleDistance(BlipLS, 800)
    --local Veiculos = {510} -- IDs dos Veículos.
    Rumpo = {}
    AparecerBike = Rumpo[source]
    -- EDIT
    tblBikes = {};
    -- /EDIT
    
    function spawn (source)
        if isElementWithinMarker(source, MarkerBike) then 
            if getPlayerMoney(source) >= 500 then 
                takePlayerMoney (source, 500)
                if AparecerBike and isElement(AparecerBike) then
                    destroyElement(AparecerBike)
                end
                AparecerBike = createVehicle (510, 1091.2088623047,-1796.9704589844,13.606305122375)   
                setElementData(AparecerBike, "kart.race", true)  
                setElementData(source, "owner", AparecerBike) 
                setElementData(AparecerBike, "conta.tempo", false)                                
                setElementRotation(AparecerBike,0,0,0)
                fadeCamera ( source, false, 0, 0, 0, 0 )
                -- EDIT
                tblBikes[AparecerBike] = {};
                tblBikes[AparecerBike].fadeTimer = setTimer ( fadeCamera, 500, 1, source , true, 0.5 )
                tblBikes[AparecerBike].targetTimer = setTimer ( setCameraTarget, 500, 1, source )
                -- /EDIT
                outputChatBox ("#FF0000✘ #ffffffINFO #FF0000✘➺ #FF0000Bicicleta Alugada com sucesso, faça bom uso!", source, 255, 255, 255, true)
                warpPedIntoVehicle (source, AparecerBike)
            else
                outputChatBox("#FF0000✘ #ffffffINFO #FF0000✘➺ #FF0000Você não tem dinheiro suficiente para alugar uma bike!", source, 255,255,255,true)
            end
        end
    end
    addCommandHandler("alugar", spawn)
    
    function enterVehicle ( player, seat, jacked ) 
        if getElementData(source, "kart.race") == true and seat == 0 then 
    	   local owner = getElementData(source, "owner")
    	   else
             cancelEvent()
            outputChatBox ( "Você não é dono desta bicicleta, alugue sua bike para poder usá-la.", player )
        end
      end
    addEventHandler ( "onVehicleStartEnter", getRootElement(), enterVehicle ) 
    
    
    function destroyVehicle(vehicle)
       local check=false
       for i,player in ipairs(getElementsByType("player")) do
           if getPedOccupiedVehicle(player)==vehicle then
               check=true
           end
       end
       if check==false then
           -- EDIT
           if (tblBikes[AparecerBike]) then
               for _, timer in pairs(tblBikes[AparecerBike]) do
                   if (isTimer(timer) then
                       killTimer(timer)
                       timer = nil
                   end
               end
           end
           -- /EDIT
           destroyElement(AparecerBike)
       end
    end
     
    local minutos = 1
    
    function exitVehicle(AparecerBike, seat)
        if getElementData(AparecerBike, "kart.race") == true and seat == 0 then
            if isTimer(Rumpo[AparecerBike]) then
                killTimer(Rumpo[AparecerBike]) -- killTimer does not work.
            end
            Rumpo[AparecerBike] = setTimer(destroyVehicle,5000*minutos,0,AparecerBike) -- This timer does not stop...
        end
    end
    addEventHandler("onPlayerVehicleExit",getRootElement(),exitVehicle)
    
    function onPlayerVehicleEnter (AparecerBike, seat)
        if getElementData(AparecerBike, "kart.race") == true and seat == 0 then
    	    if isTimer(Rumpo[AparecerBike]) then
    		    killTimer(Rumpo[AparecerBike])
    		end
    	end
    end
    addEventHandler("onPlayerVehicleEnter", getRootElement(), onPlayerVehicleEnter)
    
    function onResourceStop (AparecerBike)
        if isTimer(Rumpo[AparecerBike]) then
            killTimer(Rumpo[AparecerBike])
        end
    end
    addEventHandler("onResourceStop", getResourceRootElement( getThisResource() ), onResourceStop)
    
    function DestroyVeiculo ()
        if getElementData(source, "kart.race") then
            setElementData(source, "kart.race", false)
            destroyElement (AparecerBike)
            killTimer(Rumpo[AparecerBike])
        end
    end
    addEventHandler ("onPlayerLogout", root, DestroyVeiculo)
    addEventHandler ("onPlayerQuit", root, DestroyVeiculo)
    addEventHandler ("onPlayerWasted", root, DestroyVeiculo)
    addEventHandler ("onPlayerBan", root, DestroyVeiculo)
    addEventHandler ("onResourceStop", root, DestroyVeiculo)

    Dunno what this "Rumpo" stuff is, so i just made an example in the destroyVehicle function, hope you get what im on about, marked all changes with --EDIT and --/EDIT

  13. local iStartTick = 0 -- Needs to get set using getTickCount() when you want to start your animation
    local iAnimDuration = 2000 -- The animation takes 2s to perform
    
    local x1 = 100 -- Left START position of your rectangle
    local y1 = 100 -- Top START position of your rectangle
    local x2 = 500 -- Left END position
    local y2 = 500 -- Top END position
    
    function render()
        local iProgress = (getTickCount() - iStartTick) / iAnimDuration -- Get the difference between now and startTick and divide by wanted duration to get the progress of your animation
        local x, y = interpolateBetween(x1, y1, 0, x2, y2, 0, iProgress, "Linear")
      
        dxDrawRectangle(x, y, 100, 100, tocolor(255, 255, 255, 255))
      
        if (iProgress >= 1) then -- If the animation is done stop the animation + rendering
        	iStartTick = 0;
        	removeEventHandler("onClientRender", root, render)
        end
    end
    
    function startAnimation() -- Call this function when you want to start your animation
        iStartTick = getTickCount()
        
        addEventHandler("onClientRender", root, render)
    end

    This will start rendering and animation always when you call startAnimation()
    Hope with this you can do everything you want.

    • Thanks 1
  14. 3 hours ago, AlvarO said:

    I would use this:

    
    local marker = createMarker (0, 0, 0, "cylinder", 1.5, 255, 255, 0, 170 )
    
    function playerJoinMarker()
    	addEventHandler("onClientRender", getRootElement(), drawMarkerPanel)
    end
    addEventHandler( "onMarkerHit", marker, playerJoinMarker)
    
    function drawMarkerPanel()
    	--YOU CAN DRAW HERE YOUR PANEL, ALSO, ADD A CLOSE BUTTON WHICH REMOVE THE onClientRender EVENT
    end
    

     

    @thund3rbird23 You cant do it like this, because your script is serverside.
    Add the onClientRender event clientside in the function that get triggered by your event.

×
×
  • Create New...