thund3rbird23
-
Posts
129 -
Joined
-
Last visited
Posts posted by thund3rbird23
-
-
Any help or advice, please? I'm still struggling with it
-
I want to move the sticker which is placed on the vehicle with mouse.
At the moment I use the cursor's x,y position to set the sticker's x,y position inside the onClientRender event:
local cursorX,cursorY = getCursorPosition() stickers[selectedStickerID][1] = cursorX * 1024 -- stickers is a table the first key is the sticker's x position (the 1024 is the UV-Map size which applied to the car) stickers[selectedStickerID][2] = cursorY * 1024 -- the second key is the sticker's y position
but currently the moving is very strange...
if the camera is looking on top of the car then the sticker moves as expected but for example if the camera is looking at the front of the car, if I move the mouse forwards the sticker moves backwards and so on as shown in the video below.
so I think I need to calculate the x,y position from the cursor (getCursorPosition) the camera (getCameraMatrix) and maybe the vehicle position (getElementPosition) together (?) I tried to play a bit in that way too but that was even worse
Here is a video to better understand what the problem is:
https://streamable.com/dssr52 -
On 02/08/2023 at 12:07, #!_A7M8D said:
Hello @thund3rbird23 ,
Can you show us video and we will try to know how they did they
they may be using a custom object for the engine
Cheers !
-
Yeah, I know about these functions. But some server did it already they're just "highlighted" the engine for example when you are a mechanic and you are repair the engine then it's like the engine is "glowing", "highlighted" or I dont know which word can describe
-
Thank you for your reply, but how can I get the vehicle engine's position and such things? I don't think so there is a function for that
-
My goal is draw outline around the vehicle's engine when the hood is open but I don't know it's possible to do or not... of course there are modded vehicles not default ones.
I know I need to open the vehicle's hood with SetVehicleDoorState but how can I draw the outline around the engine? is there any function to get the engine position for each vehicles or I need to calculate it manually? and then I can use the DxDrawLine function or which one?
By outline I mean like this, but around the engine:
-
I'm trying to do if I click on a "left" or "right" button then rotate the created ped, if I click on the left button then rotate the ped -10 if I click on the right button then rotate the ped +10
defPed = createPed(1, pedPosition[1], pedPosition[2], pedPosition[3], pedPosition[4]) function createPed(key, state) local rotX, rotY, rotZ = getElementRotation(defPed) if state then if key == "mouse1" then if isInSlot(sx*0.3 + 275/myX*sx, startY+250, 40/myX*sx, 40/myX*sx) then setElementRotation(defPed, rotX, rotY, rotZ - 10) end if isInSlot(sx*0.3 + 335/myX*sx, startY+250, 40/myX*sx, 40/myX*sx) then setElementRotation(defPed, rotX, rotY, rotZ + 10) end end end end
The problem is that if I click on the "right" button, it turns to the right and then if I click on it once more, it turns back, same situation with the "left" button.
Is it because I don't store rotX, rotY,rotZ after turning the ped to right/left? if so then where I need to store them? -
Yes, I realized it a few hours later after I posted it but thank you
-
My problem is, when I click on the button 2 which is register then it's click twice on the button, but I only click once, why?
function Panel:loginClick(button, state) if self.show and self.hovered == 'buttons' and self.selectedbutton == 1 then for key, value in pairs(self.loginGuis) do if value.text == '' then if clickTick + (5000) > getTickCount() then return end exports.ml_notification:addNotification('All fields are required!', 'warning') destroyAnimation() break else triggerServerEvent('loginaccount', localPlayer, localPlayer, self.loginGuis[1].text, self.loginGuis[2].text) destroyAnimation() end end elseif self.show and self.hovered == 'buttons' and self.selectedbutton == 2 then for key, value in ipairs(self.registerGuis) do if value.text == '' then if clickTick + (5000) > getTickCount() then return end exports.notification:addNotification('All fields are required!', 'warning') break else if self.registerGuis[2].text == self.registerGuis[3].text then if isValidMail(self.registerGuis[4].text) then outputChatBox(self.registerGuis[1].text) triggerServerEvent("registeraccount", localPlayer, localPlayer, self.registerGuis[1].text, self.registerGuis[2].text, self.registerGuis[4].text) break else exports.notification:addNotification('Wrong email!', 'warning') break end else exports.notification:addNotification('The passwords do not match!', 'warning') break end end end end end
The registeraccount server side:
function registerAcc(player, username, password, email) outputChatBox("register clicked") local password = base64Encode(password) local registerQuery = dbPoll(dbQuery(sql, "SELECT * FROM account"), -1) for _, row in ipairs(registerQuery) do if row["username"] == username then exports.notification:addNotification(player, 'This username is already taken!', 'warning') return end if row["serial"] == getPlayerSerial(player) then exports.notification:addNotification(player, 'You already have an account!', 'warning') return end end local registerInsert = dbQuery(sql, "INSERT INTO account SET username = ?, password = ?, email = ?, serial = ?", username, password, email, getPlayerSerial(player)) local result, num, insertID = dbPoll(registerInsert, -1) if insertID then exports.notification:addNotification(player, 'Register success!', 'info') end end addEvent("registeraccount", true) addEventHandler("registeraccount", root, registerAcc)
The problem is because it's clicking on the button twice then always getting a warning notification when I register "You already have an account"
-
12 minutes ago, IIYAMA said:
You can loop through all vehicles and check if their plate is the same as the item in the database. But it is easier and more efficient to set an identifier when you create the vehicle.
What is used as your database primary key per vehicle?
The vehicle ID is the primary key in database. (id column)
-
6 hours ago, IIYAMA said:
I am not sure why you want to pass the plate into that function. But the function requires a player, not a plate.
6 hours ago, Patrick said:Find nearest vehicle by platetext looks unnecessary, if plates are unique.
I'm getting the vehicle plate text from a client-side gui gridlist selection and want to check if the vehicle with the selected plate text is nearby then I can do whatever what I want with the vehicle.
56 minutes ago, Zorgman said:local vehicleplate = result[1]["plate"] local x = result[1]["posX"] local y = result[1]["posY"] local z = result[1]["posZ"] local nearby = 20 if getDistanceBetweenPoints3D(x, y, z, getElementPosition(player)) <= nearby then outputDebugString("Vehicle is nearby") end
Something like this maybe?
I assumed that you store the vehicle position in the dB, I also assumed the keys for thatI had to modify the positions variable the positions debug is working well but I always getting "Vehicle is not nearby" doesn't matter if I'm close to the vehicle or not.
And the vehicle position doesn't change while the player is in-game. That will change after the player is disconnected so I don't think so that's the good way of the vehicle's position?!
function SetVehicleSellingDB(vehPlate) local query = dbQuery(con, "SELECT * FROM vehicle WHERE plate=?", vehPlate) local result = dbPoll(query, -1) if result then local vehicleplate = result[1]["plate"] local pos = fromJSON(result[1]["pos"]) local x = pos[1] local y = pos[2] local z = pos[3] iprint("x: "..x.. " y: "..y.." z: "..z) local nearby = 20 if getDistanceBetweenPoints3D(x, y, z, getElementPosition(source)) <= nearby then outputDebugString("Vehicle is nearby") else outputDebugString("Vehicle is not nearby") end end end
- 1
-
I want to check if the selected vehicle is nearby by the vehicle's plate.
I'm getting the vehicle's plate text from client-side gui (gridlist selection) then I query that plate from mysql in server-side and want to check if that is nearby or not.
function SetVehicleSellingDB(vehPlate) local query = dbQuery(con, "SELECT * FROM vehicle WHERE plate=?", vehPlate) local result = dbPoll(query, -1) if result then local vehicleplate = result[1]["plate"] --- I getting the selected vehicle's plate from client-side gui succesfully local vehicle = getNearestVehicle( vehicleplate ) --- this doesn't work if vehicle then outputChatBox("Vehicle is nearby") end end end addEvent("SetVehSellingDB",true) addEventHandler("SetVehSellingDB",getRootElement(), SetVehicleSellingDB)
It's works until I getting the vehicle's plate text but how can I insert the vehicleplate variable into the getNearestVehicle function?
function getNearestVehicle( player ) local x, y, z = getElementPosition( player ) local prevDistance local nearestVehicle for i, v in ipairs( getElementsByType( "vehicle" ) ) do local distance = getDistanceBetweenPoints3D( x, y, z, getElementPosition( v ) ) if distance <= ( prevDistance or distance + 1 ) then prevDistance = distance nearestVehicle = v end end return nearestVehicle or false end
getNearestVehicle function source:
-
10 minutes ago, IIYAMA said:
Did you actually select something from the list? (and is it still selected when you clicked the button?)
Oh. Okay working fine. You are always right
- 1
-
Now the
local Selected = DGS:dgsGridListGetSelectedItem(gridlist) iprint("Selected is correct:", Selected ~= -1, ">input>", Selected )
Selected returns false. But before that it worked without any problem
-
7 minutes ago, IIYAMA said:
[A] Now debug each condition until you find the one that isn't met:
iprint("function call") if button == "left" and state == "down" then iprint("correct mouse button") if source == gridlist then iprint("source is correct") local Selected = DGS:dgsGridListGetSelectedItem(gridlist) -- keep in mind that this variable starts with a capital S if Selected ~= -1 then iprint("did select something Selected")
You can also do it like this, debugging literally the condition, before doing the condition itself: (which takes more time to set-up, but gives also a lot more information)
iprint("correct mouse button:", button == "left" and state == "down", ">input>", button, state) if button == "left" and state == "down" then iprint("source is correct:", source == gridlist, ">input>", source, gridlist) if source == gridlist then local Selected = DGS:dgsGridListGetSelectedItem(gridlist) -- keep in mind that this variable starts with a capital S iprint("Selected is correct:", Selected ~= -1, ">input>", Selected ) if Selected ~= -1 then
Normally I start with [A], finding out the location of the problem and then do to figure out what is actually going on.
[A],
,
So the problem is the source isn't correct? I'm calling the source (gridlist) from the "onLoadOwnWeapons" event
-
4 minutes ago, IIYAMA said:
Any errors?
Does the function SellBttn... gets called after clicking? (Just the function, not all the condition within)
No errors in debug and if I put only outputChatBox("clicked") inside the SellBttnClick function then displays that... so yes the function gets called after clicking.
-
58 minutes ago, IIYAMA said:
You will have to run this part, when the data is available: (line 7 until 11)
local items = getElementData(localPlayer, "weaponmodel") column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end
local items = getElementData(localPlayer, "weaponmodel")And if you only do this once, you probably do not need elementdata.
addEvent("onLoadOwnWeapons", true) addEventHandler("onLoadOwnWeapons", localPlayer, function (items) column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) -- < this line can be moved back to it's original spot. for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end end, false)
Thank you. Now it seems to work... but I can't get the dgsGridListGetSelectedItem before it's worked when I used onResourceStart event handler.
Do you have any idea?
addEvent("onLoadOwnWeapons", true) addEventHandler("onLoadOwnWeapons", localPlayer, function (items) weapwindow = DGS:dgsCreateWindow(screenW - 278 - 10, (screenH - 237) / 2, 278, 237,"Your Weapons",false) DGS:dgsWindowSetCloseButtonEnabled(weapwindow, false) DGS:dgsWindowSetMovable ( weapwindow, false ) gridlist = DGS:dgsCreateGridList (0.04, 0.01, 0.92, 0.58, true, weapwindow ) local items = getElementData(localPlayer, "weaponmodel") column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end sellbttn = DGS:dgsCreateButton(0.62, 0.62, 0.34, 0.08, "Sell", true, weapwindow) addEventHandler ( "onDgsMouseClick", sellbttn, SellBttnClick, false ) end, false)
--- SellBttnClick function (from Dgs Wiki page)---
function SellBttnClick(button, state) if button == "left" and state == "down" then if source == gridlist then local Selected = DGS:dgsGridListGetSelectedItem(gridlist) if Selected ~= -1 then local output= DGS:dgsGridListGetItemText(gridlist,Selected,column) outputChatBox(""..output.."",255,0,0) end end end end
-
7 minutes ago, IIYAMA said:
When the event onLoadOwnWeapons is fired, your data is ready to be used.
Uh okay I'm totally lost... I need those table when I open the gui window. I set the guivisible true when I click on a button from another window.
This is the main window but I need to set the guivisible false so we can't see the gui always.
The items variable doesn't work here I just left it there to better illustrate what I want to do. (I need to put the table in the gridlist but only after I click on a button)
function test() weapwindow = DGS:dgsCreateWindow(screenW - 278 - 10, (screenH - 237) / 2, 278, 237,"Your Weapons",false) DGS:dgsSetVisible(weapwindow, false) DGS:dgsWindowSetCloseButtonEnabled(weapwindow, false) DGS:dgsWindowSetMovable ( weapwindow, false ) gridlist = DGS:dgsCreateGridList (0.04, 0.01, 0.92, 0.58, true, weapwindow ) local items = getElementData(localPlayer, "weaponmodel") column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end DGS:dgsSetVisible(weapwindow,false) end addEventHandler ( "onClientResourceStart", resourceRoot, test )
This is the another window where I have the button which "opens" the gui window (I set the gui visible to true):
addEventHandler ( "onClientClick", root, function ( button, state ) if ( button == "left" and state == "down" ) then if drawInfo == true and ( isMouseInPosition ( screenW * 0.4195, screenH * 0.6680, screenW * 0.0523, screenH * 0.0166 ) ) then drawInfo = false DGS:dgsSetVisible(weapwindow,true) end if drawInfo == true and ( isMouseInPosition ( screenW * 0.4836, screenH * 0.6670, screenW * 0.0547, screenH * 0.0176 ) ) then drawInfo = false end end end )
How can I put the table in to the gridlist if I click on that button with your solution? Because currently the gridlist is empty and the debug just return an empty table "{}"
-
25 minutes ago, IIYAMA said:
The second situation is obvious, because the data isn't available yet.
The first and third are a little bit strange. Maybe it is for some unknown reason also related to the timing.
Debug code:
-- serverside -- BEFORE line 12 newTable.tickCount = getTickCount() -- verification -- line 12: setElementData(source, "weaponmodel", newTable) -- AFTER line 12 triggerClientEvent(client, "onLoadOwnWeapons", client, newTable)
-- client addEvent("onLoadOwnWeapons", true) addEventHandler("onLoadOwnWeapons", localPlayer, function (items2) local items = getElementData(localPlayer, "weaponmodel") iprint("items:", items, " items2:", items2, "\n\n") end, false)
And compare those values. (+ screenshot)
items debug is false
items2 debug is the table what I need.Screenshot: https://i.imgur.com/33JanAb.png
EDIT: my bad... I misspelled a word in items variable. The items & items2 debug is the table what I want.
-
6 hours ago, IIYAMA said:
It does matter which incorrect value you see, since it can point to the direction of the problem.
I'll try to describe it clearly
I query the weaponmodels here:
--- server.lua ---
addEvent("loadOwnWeapons",true) addEventHandler("loadOwnWeapons",getRootElement(),function(player) local owner = getElementData(source, "acc:id") local query = dbQuery(con,"SELECT * FROM weapons WHERE owner = ?", owner) local weapons = dbPoll(query,-1) if weapons then local newTable = {} for k,v in ipairs(weapons) do newTable[#newTable + 1] = {v["weaponmodel"]} end setElementData(source, "weaponmodel", newTable) end end)
Then I calling this server event in client-side:
--- client.lua ---
function test() triggerServerEvent("loadOwnWeapons", localPlayer) local items = getElementData(localPlayer, "weaponmodel") iprint(items) end addEventHandler ( "onClientResourceStart", resourceRoot, test )
The situation is: When I connect to the server then the items debug is (only one string):
XZG-324
After I restart the resource the items debug is an empty table:
{}
After I restarting the resource twice (a table with the player's weaponmodels which I need without restarting the resource):
{{"XZG-324"},{"YRT-598"},{"OEV-153"},{"EFC-543"},{"LEZ-054"}}
-
3 hours ago, IIYAMA said:
Or use onPlayerJoin serverside, if you are not using triggerClientEvent event directly after that event (, then it doesn't matter if the client has loaded his resource). But if you are planning that in the future, then keep using onClientResourceStart.
I still don't understand what is the problem... look I added a button which is "refresh" the gridlist's items, when I click on that button and debug the items with iprint then I get only one string... for ex.: xyz123 and after I restart the resource and then click on the refresh button then I get the table which I need... But why?
function refreshBttnClick() triggerServerEvent("loadOwnWeapons", localPlayer) DGS:dgsSetVisible(weaponwindow,false) weaponwindow = DGS:dgsCreateWindow(screenW - 278 - 10, (screenH - 237) / 2, 278, 237,"Your Weapons",false) DGS:dgsWindowSetCloseButtonEnabled(weaponwindow, false) DGS:dgsWindowSetMovable ( weaponwindow, false ) gridlist = DGS:dgsCreateGridList (0.04, 0.01, 0.92, 0.58, true, weaponwindow ) column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) local items = getElementData(localPlayer, "weaponmodel") iprint(items) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end refreshbttn = DGS:dgsCreateButton(0.05, 0.62, 0.34, 0.08, "Refresh", true, weaponwindow) addEventHandler ( "onDgsMouseClick", refreshbttn, refreshBttnClick, false ) end
-
Gridlist only load data if I restart the resource... I'm using thisdp's GUI ... I tried to load the weapons from server side when player joins but still the same.
function loadweapons() triggerServerEvent("loadOwnWeapons", localPlayer) end addEventHandler("onClientPlayerJoin", getRootElement(), loadweapons)
I set the window visible to false
function test() weapwindow = DGS:dgsCreateWindow(screenW - 278 - 10, (screenH - 237) / 2, 278, 237,"Your Weapons",false) DGS:dgsSetVisible(weapwindow, false) DGS:dgsWindowSetCloseButtonEnabled(weapwindow, false) DGS:dgsWindowSetMovable ( weapwindow, false ) gridlist = DGS:dgsCreateGridList (0.04, 0.01, 0.92, 0.58, true, weapwindow ) local items = getElementData(localPlayer, "weaponmodel") column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end DGS:dgsSetVisible(weapwindow,false) end addEventHandler ( "onClientResourceStart", resourceRoot, test )
If I debug the items with iprint(items) I get only string instead of table... but if I restart the resource I get the table and everything is working.
And here I set the window visible to true if I click on other button from another window
addEventHandler ( "onClientClick", root, function ( button, state ) if ( button == "left" and state == "down" ) then if drawInfo == true and ( isMouseInPosition ( screenW * 0.4195, screenH * 0.6680, screenW * 0.0523, screenH * 0.0166 ) ) then drawInfo = false DGS:dgsSetVisible(weapwindow,true) end if drawInfo == true and ( isMouseInPosition ( screenW * 0.4836, screenH * 0.6670, screenW * 0.0547, screenH * 0.0176 ) ) then drawInfo = false end end end )
the loadOwnWeapons server-side event is:
addEvent("loadOwnWeapons",true) addEventHandler("loadOwnWeapons",getRootElement(),function(player) local owner = getElementData(source, "acc:id") local query = dbQuery(con,"SELECT * FROM weapons WHERE owner = ?", owner) local weapons = dbPoll(query,-1) if weapons then local newTable = {} for k,v in ipairs(weapons) do newTable[#newTable + 1] = {v["model"]} end setElementData(source, "weaponmodel", newTable) end end)
My question is why I only get the table from the loadOwnWeapons server-side event if I restart the resource?
Maybe because I only get the weaponmmodel elementdata in the onClientResourceStart event handler... but what should I replace it with?
-
5 minutes ago, IIYAMA said:
There is an up and down state. (press/release)
https://wiki.multitheftauto.com/wiki/OnDgsMouseClick
function BttnClick(button, state) -- button: left/right/middle -- state: up/down if button == "left" and state == "down" then end end
Yes.. I wrote the question first then thought about that ... sorry and thank you. You helped me a lot
- 1
-
3 hours ago, IIYAMA said:
I already gave you the components that are in my first post. I don't think I can explain it any better, unless you ask specific questions.
DX is an (after) effect, not an element, therefore those rectangle/text things on your screen are nothing but "AIR". Which means that if you want to check if you clicked on them, you need to check if the cursor position is within the position of the things you are about to draw.
If the concept of DX-UI is unclear, how about you try something that shows DX and but works as a GUI? There is also a whole wiki . @thisdp did a very good job including all features from the original GUI and more.
Thanks. I trying with thisdp's DX GUI System but for some reason it's display "clicked" multiple times in chatbox when I click to the "Sell" button... What do I doing wrong?
I need to check the button left or right & the state of the button?
function test() window = DGS:dgsCreateWindow(screenW - 278 - 10, (screenH - 237) / 2, 278, 237,"Your weapon list",false) gridlist = DGS:dgsCreateGridList (0.04, 0.11, 0.92, 0.78, true, window ) column = DGS:dgsGridListAddColumn(gridlist, "Weapons", 0.5) for k, v in ipairs(items) do row = DGS:dgsGridListAddRow(gridlist, v[1]) DGS:dgsGridListSetItemText ( gridlist, row, column, v[1] ) end button = DGS:dgsCreateButton(0.62, 0.88, 0.34, 0.08, "Sell", true, gridlist) addEventHandler ( "onDgsMouseClick", button, BttnClick, false ) end addEventHandler ( "onClientResourceStart", resourceRoot, test ) function BttnClick() outputChatBox("clicked") end
- 1
Positioning sticker on vehicle with cursor
in Scripting
Posted · Edited by thund3rbird23
What are the 12th and 13th indexes for?
The getCameraMatrix function return only 8 number and you can't index them because they are just numbers. Do you mean the x,y coords given by the getCameraMatrix function?
So, like this?:
I tried that but got the same result, the sticker is moving perfectly forward and backward direction only if the camera is looking at the roof of the car (just like in the video)
I think I need to play with the vehicle's center position too somehow, when I moving the cursor or something like that?! Because if you're looking at the top of the vehicle then the camera is looking exactly at the middle of the vehicle, isn't it?