Jump to content

The_GTA

Helpers
  • Posts

    822
  • Joined

  • Last visited

  • Days Won

    86

Everything posted by The_GTA

  1. Yes, yes, yes and yes. The game provides the starting value, which is always true. But you cannot rely on any value because there are other scripts that may modify the value.
  2. Glad to help you! By the way, nice toilet roll avatar. I think it fits very much into today's times
  3. local function setFBumper() local theVeh7 = getPedOccupiedVehicle(localPlayer) if theVeh7 then local alreadyVisible = getVehicleComponentVisible(theVeh7, "bump_front_dummy") setVehicleComponentVisible(theVeh7, "bump_front_dummy", not alreadyVisible) end end addEventHandler("onClientGUIClick", fbumper, setFBumper, false) guiSetVisible (vehmod, false) fixed & optimized. Explanation: you have to give the component name as second argument to getVehicleComponentVisible for it to work the return value of getVehicleComponent is either true or false, not "true" not "false"
  4. Then I recommend just doing it like this: addEventHandler("onClientRender", root, showRadioSongName) setTimer( function() removeEventHandler("onClientRender", root, showRadioSongName) end, 5000, 1 ) This way showRadioSongName is executed for 5 seconds inside onClientRender and is removed after that.
  5. line 4: fromJSON(toJSON(query)) ? really? ? Why don't you just use ipairs? In case query is false then you just check for that error condition before the loop. if your token is a key to the accounts table then you can improve it to... function updateMoneyHandler(token) local query = exports.mysql:_Query("select gold from accounts where token = ?", token) if not (query) then outputDebugString("failed to query for account gold") return end local gold = query[1].gold; triggerClientEvent (source, "updateMoneyClient", root, gold) end Change in line 5: This way the only client that receives the gold is the element that you triggered "updateMoney" for. Also: I have no idea in what context you call triggerEvent with "updateMoney" and the client parameter so I am just going to assume that you know what the client global variable is and how to use it. EDIT: also change the client.Lua to... function updateMoneyClientHandler(gold) setPlayerMoney(tonumber(gold)) end addEvent("updateMoneyClient",true) addEventHandler("updateMoneyClient", root, updateMoneyClientHandler) I did not realize that you also changed that part of the code.
  6. Hello AlvarO, do you want it like this? timer_1 = setTimer(showRadioSongName, 5000, 1) addEventHandler("onClientRender", getRootElement(), showRadioSongName) timer_11 = setTimer ( function() removeEventHandler("onClientRender", getRootElement(), showRadioSongName) end, 5000, 1 ) if not isTimer(timer_1) and isTimer( timer_11 ) then killTimer( timer_11 ) end By the way... What is the showRadioSongName function doing? It is a function that draws dx on the screen? Why are you doing line 1? - Martin
  7. I recommend to check for an existing account like... -- I assume that there is a variable called "db_conn" with the MySQL connection. local function does_account_exist(username) local query = dbQuery(db_conn, "SELECT username FROM accounts WHERE username='?'", username); if not (query) then return false; end local results = dbPoll(query, -1); if not (results) then return false; end return ( #results >= 1 ); end Then you can use the "does_account_exist' function as part of if-condition to check for the existance. Like... local function create_error_message_dialog(msg) -- TODO: write the GUI logic in here. end local function create_account(username, password) if (does_account_exist(username)) then create_error_message_dialog("This name already exists"); return; end -- TODO: use dbExec to register a new account. end
  8. Do you have a database layout and a script with a login panel? We could work it out.
  9. I am glad to be of help! It is especially nice to see experienced developers around here. ? I recommend a read of the wiki's event system info for the full details. But in your case the "root" means to listen to the "updateMoney" event triggers on all elements in the MTA element tree. Thus if you were to execute... triggerEvent("updateMoney", resourceRoot) your server-local event would also fire. But if you were to use "resourceRoot" for the addEventHandler call instead then executing the above code on another resource would not trigger your event handler. The BIG BUT is: executing... triggerEvent("updateMoney", root) does trigger the event handler in both of the above cases. To improve the robustness (not security!) of your resource you can set the propagate argument of addEventHandler to false.
  10. Dear iwalidza, do you have a MySQL server set-up already? It can be placed either locally (recommended) or remotely, on another computer. You need to register a user with a secure password as well as a database for use with your resource. And how much experience do you have with MySQL databases in general? You should use the official MTA database functions to connect to your configured MySQL server, in particular... dbConnect - call it once at start of resource to initialize a database connection handle (you need a host, username and password, etc) dbExec - creating new accounts into the MySQL database dbQuery with dbPoll and dbFree - taking account information out of your database In order to implement "This name already exists" you need to query the accounts SQL table on the "username" column and see if any row with that username already exists, for example... SELECT * FROM accounts WHERE username="iwalidza" If you were to use dbQuery on this statement in combination with dbPoll/dbFree you could check the existance of accounts prior to creating a double account. I found an accounts system that claims to use MySQL under-the-hood in the MTA resources community: https://community.multitheftauto.com/index.php?p=resources&s=details&id=7263 Please take a look at it and compare it with what you want to implement.
  11. Dear Bartje, welcome to the MTA scripting forums! I am glad to see new faces around here that nicely ask for help. Let me help you by commenting on what you have already scripted: I think you mixed up the clientside definition with the serverside definition of setPlayerMoney. For the clientside definition the first argument is not a player element but just a number with the money that the local player should have. This is because the local player does only know or care about his own money value, not other people's. Thus you can simply remove the first parameter "source" and just pass the money count. The source element that you pass as argument after the event name to triggerEvent-style functions is usually the element that wants to receive or has received a change. In your code you have simply specified "root" which is okay if you want to update the money of all players to the same value. But if you want to update the money of just one player... ... then you have to further adjust this code. The first argument to triggerClientEvent can be a player element that should receive the event. You probably want to limit this to the person that actually logged in. Otherwise even non-logged in players would randomly receive the 1000 gold. - Martin
  12. Hello elian sweed, in order to start the shader resource from your GUI resource you need to change the ACL security configuration of your MTA server as well as adjust your resource into a clientside and serverside component: 1) Did you know about the ACL.xml file inside of your MTA server? Since the startResource function is privileged you need to give your resource the right to use it. As an easy solution you could add the resource to the "Admin" ACL group. 2) The script you posted above is a clientside GUI script. You cannot call serverside resource functions inside of it. What you have to do is create a server.Lua file and start the resource from there. I recommend using the getResourceFromName function in combination with the startResource function. If you have any further questions like about the implementation or the security-critical aspects then feel free to ask. - Martin
  13. I think this ridiculous statement by OP also got me ? I took at look at the source code in question and found the following relevant locations: https://github.com/mabako/mta-paradise/blob/6d4a852e27a276920943827426b9cf88e20a6b7d/resources/players/main.Lua#L297 https://github.com/mabako/mta-paradise/blob/6d4a852e27a276920943827426b9cf88e20a6b7d/resources/sql/layout.Lua#L91 It looks like your MySQL configuration could be faulty. Here are some suggestions of what problem scenarios you could inspect: did you create a new MySQL user for mta-paradise and adjusted the settings.xml file in the resource so that the system can log-in? have you given the MySQL user complete access rights? creating tables? selecting? etc? - Martin
  14. I think you want to take a look at aswell. That topic descibes how to rotate just the head of a ped.
  15. Hello DanielHuynh, could you please use the "<>" to format your code? It would greatly improve the readability.
  16. Dear manif14102, I unfortunately cannot understand what you are trying to do with the getFreeSlot function. But here is my take on how it could be done: local function createInventoryBox(width, height) local box = {}; local rows = {}; for n=1,height,1 do rows[n] = {}; end function box.getItem(x, y) if (y < 1) or (y > height) then return false; end; if (x < 1) or (x > width) then return false; end; local row = rows[y]; return row[x]; end function box.setItem(x, y, item) if (y < 1) or (y > height) then return false; end; if (x < 1) or (x > width) then return false; end; local row = rows[y]; if not (row) then row = {}; rows[y] = row; end row[x] = item; return true; end function box.tryPlaceItem(item, x, y, iwidth, iheight) if (iwidth == 0) or (iheight == 0) then return false; end; -- Only if we do not cross the border. if (x < 1) or (x + iwidth - 1 > width) then return false; end; if (y < 1) or (y + iheight - 1 > height) then return false; end; -- Check if free space. for witer=0,iwidth-1,1 do for hiter=0,iheight-1,1 do local exist_item = box.getItem(x + witer, y + hiter); if (exist_item) then return false; end end end -- Place the item there. for witer=0,iwidth-1,1 do for hiter=0,iheight-1,1 do box.setItem(x + witer, y + hiter, item); end end return true; end function box.clearItem(x, y, iwidth, iheight) for witer=0,iwidth-1,1 do for hiter=0,iheight,1 do box.setItem(x + witer, y + hiter, nil); end end end return box; end (code has not been tested) The above code implements a two-dimensional array with helper functions for placement. Thus one could do... local box = createInventoryBox(3, 3); assert( box.tryPlaceItem(1, 1, 2, 2, "Knife") == true ); assert( box.tryPlaceItem(1, 2, 2, 2, "Key") == false ); Hopefully this does give you an idea
  17. Hello manif14102, since you have trouble implementing the algorithms described in that topic, how about posting your code so that we can assist you? I think that you may have personally overlooked something that we can improve as a community ? - Martin
  18. Glad to be of help. Since you are asking so kindly I want to give you ideas how to continue with your inventory system. I absolutely recommend going with dx because it is more powerful than CEGUI. So these are the functions that should be used: dxDrawImage - drawing inventory icons as well as general GUI images dxDrawText - displaying the item names and descriptions as well as GUI text dxDrawRectangle - styling of the inventory window/grid/whatever bindKey function - opening the inventory with a button onClientRender event - drawing the dx UI each frame onClientClick event - clicking on items in inventory for selection and action onClientMouseMove event - hovering over items to display the description, highlighting, etc triggerServeEvent - asking the server to use an item or update the inventory in some way (throw away item, reordering the inventory, etc) triggerClientEvent - transmitting the inventory to the client Here is how I imagine an inventory to look. Code on requesting the inventory from the server: server.Lua addEvent("onRequestInventory", true); addEventHandler("onRequestInventory", root, function() triggerClientEvent(client, "onClientReceiveInventory", root, player_inventories[client], item_definitions); end ); client.Lua addEvent("onClientReceiveInventory", true); addEventHandler("onClientReceiveInventory", root, function(player_inventory, item_definitions) -- TODO: use the data somehow. end ); local function send_inventory_request() triggerServerEvent("onRequestInventory", root); end Feel free to ask more questions when you have some code done already
  19. Hello iwalidza, since you do not provide any design wishes and I have no experience with inventory system design, I will limit my contribution to the technical side of inventory systems. You may want to create new kinds of items for roleplay such as keys or identity certificates that players have to collect and treasure. An inventory system is defined as a set of items that belong to peds or players. Items can be taken out or put in at wish. Thus we want to attach a table of items for at least each player on the server and synchronize the items with the clients. server.Lua -- We want to create items definitions here. local item_definitions = {}; local function register_item(id, name, description) local def = { ["name"] = name, ["id"] = id, ["description"] = description }; item_definitions[id] = def; end register_item(1, "Knife", "Sharp item to cut things"); register_item(2, "Sword", "Sharp weapon for slashing"); register_item(3, "Key", "Used to access secret areas in the game"); -- Item local player_inventories = {}; addEventHandler("onPlayerQuit", root, function() player_inventories[source] = nil; end ); local function find_existing_player_inv_slot(inv_items, item_id) for m,n in ipairs(inv_items) do if (n.item_id == item_id) then return n; end end return false; end local function give_item_to_player(player, item_id, count) local inv = player_inventories[player]; local item_carry = find_existing_player_inv_slot(inv, item_id); if (item_carry) then item_carry.count = item_carry.count + count; return true; end local new_carry = { ["item_id"] = item_id, ["count"] = count }; table.insert(inv, new_carry); return true; end addEventHandler("onPlayerJoin", root, function() local inventory = {}; player_inventories[source] = {}; give_item_to_player(source, 1, 1); give_item_to_player(source, 2, 1); give_item_to_player(source, 3, 1); end ); (code has not been tested) This is a sample system I just created. There is a knife, sword and key. At join time each player does receive a copy of any item. Now imagine that you have a marker that you can only enter with a key. server.Lua local function does_player_have_item(player, item_id) local inventory = player_inventories[player]; local slot = find_existing_player_inv_slot(inventory, item_id); if (slot) and (slot.count > 0) then return true; end return false; end local function remove_player_item(player, item_id, count) local inventory = player_inventories[player]; for m,n in ipairs(inventories) do if (n.item_id == item_id) and (n.count > 0) then local can_remove = math.min(count, n.count); n.count = n.count - can_remove; count = count - can_remove; if (count == 0) then break; end end end end local marker = createMarker(0, 0, 3, "cylinder"); addEventHandler("onMarkerHit", marker, function(hitElement) if not (getElementType(hitElement) == "player") then return; end; if not (does_player_have_item(hitElement, 3)) then outputChatBox("You cannot enter this zone because you have no key."); return; end outputChatBox("Using key to enter the zone."); remove_player_item(hitElement, 3, 1); end ); This script creates a marker in the middle of the map. If you hit the marker then you use a key. Once you have used your starting key then you cannot successfully hit the marker anymore. The message should change the second time you hit the marker. The marker does only work with players. I hope I could help you with this
  20. https://forum.multitheftauto.com/topic/121753-searching-for-dff-txd-col-compiler/ Please use the search function next time. Asking such questions does not improve the quality of this forum. ?
  21. Do you happen to have many vehicles in this resource?
  22. Hello iwalidza, if you want to have selection support inside edit boxes you need to play around with the text-width. First you have to establish text of a certain font with a certain scale. This gives you the ability to call dxGetTextWidth to obtain metrics about your text. Knowing that you need to search for the text offset into your editbox content at click event. I suggest to set the middle of each character as tipping point. -- THIS IS JUST SAMPLE CODE! It has not been tested using Unicode/UTF-8 so be warned! local strsub = string.sub; local dxGetTextWidth = dxGetTextWidth; function getTextLogicalOffset(text, offset, charScale, charFont) local n = 1; local len = #text; local curOffset = 0; local charWidth; while (n <= len) do charWidth = dxGetTextWidth(strsub(text, n, n), charScale, charFont); curOffset = curOffset + charWidth; n = n + 1; if (curOffset > offset) then break; end end if not (n == 1) and (curOffset - offset > charWidth * 0.5) then return n-1, curOffset - charWidth; end return n, curOffset; end (taken from resedit resource at https://github.com/quiret/resedit/blob/master/utilities_client.Lua#L822) It is very important to establish drag&drop inside of your editbox. This is done by remembering when the player triggered "mouse1" to start the selection and disabling it when he released "mouse1". While the player is pressing down "mouse1" you should update the selection every time the mouse cursor is moved. local select_start = 1 local select_end = 0 local text = "test" local font = "sans" local fontScale = 1.2 local text_pixels_off_x = 2 local is_selecting = false local function has_selection() return ( select_start <= select_end ) end local function mouse_click(x_abs, y_abs) if not (is_selecting) then select_start = getTextLogicalOffset(text, x_abs - text_pixels_off_x, fontScale, font) is_selecting = true end end local function mouse_move(x_abs, y_abs) select_end = getTextLogicalOffset(text, x_abs - text_pixels_off_y, fontScale, font) - 1 end local function mouse_release() if (is_selecting) then is_selecting = false end end (this code has not been tested yet) At render-time you should highlight the text that is selected using a custom rectangle backdrop. This is done by simply remembering start-offset and end-offset of the selection and, if the selection is not empty, using dxDrawRectangle before or after rendering the text at text render offset start-offset to end-offset. I leave it to you as an exercise.
  23. Yes, let me comment on your code line 19: please do not create render targets each frame. you already did create the necessary render target in line 8. line 17: you should not use a path in dxDrawImageSection; I recommend you to use dxCreateTexture to load images into memory; it creates a texture element that you can pass into dxDrawImageSection. line 21: using dxSetRenderTarget at this point is wrong; it should be called at the start of the onClientRender event. then you can clear the render target again and use dxDrawImage at the end of onClientRender to draw your radar. I recommend to play around with render targets to understand how they work (they start from coordinate 0,0 if you draw inside them) That's it for the existing code. After you have successfully improved the code based on the guidelines above I can give you the following advice: try to calculate the coordinate on the map image (from 0 (beginning of image) to 1 (end of image)) that corresponds to the world coordinate x, y from the camera. imagine that the top left of the map image corresponds to -3000,3000 world coordinate and the bottom right to 3000,-3000 world coordinate. you could do this calculation even with school math knowledge plus trial&error. then draw a blip on the radar (location of the player?) - Martin
  24. No problem! I am happy to hear that you could get your Infernus drive faster On certain areas of the map you can find arbitrary vehicle speed limits. A very famous one is the Strip in Las Venturas. To remove these limits please use the setWorldSpecialPropertyEnabled function with the "extraairresistance" property.
  25. Hello slapztea, I think you want to increase the "engineAcceleration" vehicle handling property. Please take a look at this wiki page. Sadly I don't know about boats. Maybe speed limit for boats is not implemented in GTA:SA?
×
×
  • Create New...