-
Posts
6,062 -
Joined
-
Last visited
-
Days Won
208
Everything posted by IIYAMA
-
I would suggest this format: ID (auto incremented) INT | playerSerial TEXT | itemType TEXT | amount INT This allows you lot more flexibility. (based on your current structure) SELECT `Player`.*, `Item`.Bandage FROM `Player` LEFT JOIN `Item` ON `Player`.serial = `Item`.serial Getting all the info of the player and the bandage quantity. The keyword JOIN allows you to join another table. LEFT means that: `Player`.serial = `Item`.serial It will get all the data from the table on the left side. (MAX all the rows of the leftside) Attach data from the table on the right side where possible.
-
There is 1 important reduction, which is in my opinion the most important one. "Don't tell the otherside what it already knows." So if you reply to my previous post with a confused reaction. Then I know you did that, but also you know that you did that yourself. Now we both know that it was a confused reaction and you do not have to tell me that again, because I already know. If we apply that same concept on a smart ped system. Ped move forwards. Ped move forwards -- do not repeat Ped move forwards -- do not repeat Ped move backwards Ped stop Ped stop -- do not repeat Ped stop -- do not repeat Ped stop -- do not repeat ---‐–––––————— If we want to fake something, we have to approach that a bit differently. For example we have a ped which we want to bounce his head up and down. And yes like this: Up and down while the car his driving. If you program this, the only data that should be used, is the on and off state. When ever the head is up or down, that is irrelevant. The data for the head orientation (up/down) is faked.
- 7 replies
-
- 1
-
- element data
- synchronization
-
(and 1 more)
Tagged with:
-
It is oke, but a lot patience is required. You need to make up your mind before resume. First of all, you are not dealing with just 2 types of sides. Serverside and clientside. This is what you are dealing with: Your servercode is only running on the server application. But your clientcode is running PER player. (MTA game application) So if there are 3 players in your server. The the same client-code will be running on each machine. > And the important thing about this is, is that each machine is running a copy of the code. Those copies can't communicate directly with each other and do not share data directly with each other. As you can see in the image, the server is always in between. There is no line between client 1 and client 2. So: 1 serverside 3x clientside (with a copy of the code) "Jeff" is not a player. This is a string value, with other words TEXT. If you want to have access to a player called "Jeff", you can use the function getPlayerFromName. This function will search in the server for a player with this name and sends back a value which you could consider a value that helps to identify a specific player. If the player is not in the server, the value will be false, which you could consider as NO to keep it simple. local player = getPlayerFromName("Jeff") if player then -- did we find a player with the name "Jeff" ? end if something then do something if NO then do this not Need a random player for testing? (serverside) local randomPlayer = getRandomPlayer ( )
-
A specific player. localPlayer is yourself as element. So if I would join your server, then the player that I control is the localPlayer. And the same goes for the player that you control, which is the localPlayer for you.
-
iprint(thePlayer) is thePlayer defined? The same goes for the player from this function: function AKalap(thePlayer)
-
And what do you have to do when there is no error and still figure out what is going on? Answer can be found here if you do not know what to do
-
That's why I wrapped functions around it, so that you do not even have to worry about it. Note: for the event removealapAK you also must specify the player. function AKalap(thePlayer) local x, y, z = getElementPosition(thePlayer) local alapak = createObject(1254, x, y, z) setAttachedWeaponForPlayer (thePlayer, alapak) -- here exports['bone_attach']:attachElementToBone(alapak, thePlayer, 12, 0, 0, 0, 0, -90, 0) end addEvent("alapAK", true) addEventHandler("alapAK", resourceRoot, AKalap) function removeAKalap(thePlayer) -- send also the player here. local alapak = getAttachedWeaponForPlayer (thePlayer) -- here if alapak then if isElement(alapak) then exports.bone_attach:detachElementFromBone(alapak) moveObject(alapak, 1 ,0 ,0 ,0) else destroyAttachedWeaponForPlayer (thePlayer) -- here end end end addEvent("removealapAK", true) addEventHandler("removealapAK", getRootElement(), removeAKalap)
-
That is good. We replied at the same time, so I missed your update. (I updated my previous post)
-
Clientside elements are not shared with the server. They simply do not exist there, only at a specific player his MTA application: MTA San Andreas 1.5\Multi Theft Auto.exe How about you start at serverside tell all players in the server, that a weapon has to be attached to a specific player-element? You already solved that. Because you share the same variable for your friend his weapon as for your own. A table is required for this kind of situation. local attachedWeapons = {} If you combine that with some functions, it makes it a lot easier to maintain. function getAttachedWeaponForPlayer (player) return attachedWeapons[player] end function setAttachedWeaponForPlayer (player, weapon) attachedWeapons[player] = weapon return true end function destroyAttachedWeaponForPlayer (player) local weapon = attachedWeapons[player] if weapon then attachedWeapons[player] = nil if isElement(weapon) then return destroyElement(weapon) end end return false end
-
By sending it back Serverside local something = "something" triggerClientEvent(player, "sending-something-back" resourceRoot, something) player = sending it specific to that player. Clientside addEvent("sending-something-back", true) addEventHandler("sending-something-back", resourceRoot, function (something) outputChatBox(something) end, false) If you want to work with callbacks instead, you need an enchantment of the feature.
-
I can't judge this very well, the best moment of debugging this, is when the query is concatenated. iprint(table.concat(query_table))) Also a query string is something you can put in to a validator: https://www.eversql.com/sql-syntax-check-validator/ You might want to add spaces, just in case some values are wrongly concatenated. table.concat(query_table, " "))
-
Not really, I do not look at community resources that much. But there is a book called SQL in 10 minutes, which has tons of good examples in it. Try to find yourself a copy of it on the internet.
-
Hmm I don't think that is possible. Not because SQL can't do it, but the dbExec function clearly says "query" and not "queries". If it is supported, then it would look a bit like this: https://stackoverflow.com/questions/19239743/create-multiple-tables-using-single-sql-script-file Also keep in mind that combining arguments (Lua) for multiple tables (SQL) have a potential risk of applying variables to the wrong table. (That is if you use variables + ?) {ARGUMENT LIST + ARGUMENT LIST} = unpack(TABLE) = NEW ARGUMENT LIST
-
Is the file you called from clientside? Did you make your call after the s_phone resource has been started? Try also this function, it might be character related: call
-
To be honest, I am trying to avoid using that site. It is most of the time missing critical information, especially for semantic HTML. There is only 1 thing that I like of it, and that is the simplicity of the information. I normally use MDN(Mozilla Developer Network) for everything, but they do not have SQL docs. But it seems like they recommend these sites on their website: https://sqlzoo.net/wiki/SQL_Tutorial http://www.tutorialspoint.com/sql/
-
@Einheit-101 If we keep looping out of it and only talk about indexing. This below is just an assumption: If this is the userdata key: (which is at the very end just a complex and unique identifier.) "userdata-324ftfdbgfd" And this is the data: table = { ["userdata-424ftfsdgsf"] = true, ["userdata-3sd3524ftfd"] = true, ["userdata-325524ftfdb"] = true, ["userdata-324ftfdbgfd"] = true } Depending on which algorithm is used, the search time variates. (algorithm < which I have no knowledge of) But if I would program this search, I might do it like this in my first try: I know already the type, so my start would be: "userdata-" >>> userdata-424ftfsdgsf userdata-3sd3524ftfd userdata-325524ftfdb userdata-324ftfdbgfd Collect all items with userdata. steps * items >>> userdata-424ftfsdgsf userdata-3sd3524ftfd userdata-325524ftfdb userdata-324ftfdbgfd print(string.byte("3")) -- 51 + update position * 4 + 4 steps >>> userdata-3sd3524ftfd userdata-325524ftfdb userdata-324ftfdbgfd print(string.byte("s")) -- 115 print(string.byte("2")) -- 50 + update position * 3 + 3 steps >>> print(string.byte("4")) -- 52 userdata-325524ftfdb userdata-324ftfdbgfd < found item in table + update position * 2 + 2 steps Lua would probably be better in this then I do. But this has multiple search steps in it, no matter what kind of algorithm you use. table = { true, -- 1 true, -- 2 true, -- 3 true -- 4 } table = { [1] = true, [2] = true, [3] = true, [4] = true } Finding the index in this kind of table should be technically be faster based on two ways. Position of the characters do not matter. It is a single value, the cpu knows very well how to work with that. As with user-data's/strings, not only the position matters, the value is also different: print(string.byte("a")) -- 97 Much complexer values X position. Everything is already placed in order if you keep the table as an clean array. Just as with cleaning your room. After the cleaning, you do not have to look everywhere in your room. You more or less know where to find what and how many things you have of it. Searching for item 4? no, no, no, yes (4 steps) Note: looping to find an item VS using a custom key to find an item is a different subject. If somebody knows how this really works, then that would be nice fun facts.
-
Something like that: dbExec (db, "UPDATE accounts SET serial = ? WHERE username = ?", u_serial, username)
-
Does that player already has an account?
-
Add data to a database? INSERT INTO table_name (column1, column2 ) VALUES (?, ?) OR Get data from a database? SELECT * FROM table_name OR Import data to a database from another database.
-
True is true. It means just, yes go add it. It has probably been added to not have to add another Lua IF statement for the AND sql keyword. "true" .. " and serial = 3442" Or if the table is empty. Anyway, the example is correct, the query on the other hand doesn't looks like it is correct: true and serial = 3442 and serial = 3663 and serial = 4532 Shouldn't this be more logic? serial = 2332 or serial = 3442 or serial = 2324 It can be my imagination...
-
Get the correct table index depending on other values
IIYAMA replied to Dzsozi (h03)'s topic in Scripting
That table structure will not work well. Back to basic: local list = { {value = 25, id = "a"}, {value = 50, id = "b"}, {value = 75, id = "c"}, {value = 100} } function findSomething(value) for i = 1, #list - 1 do if value >= list[i].value and value < list[i + 1].value then return list[i] end end end local result = findSomething(27) if result then print(result.id) end -
That is normally not recommend, because you put a limit on your database. Your database will consider your data as text. (Or blob) But sure it is fine if you are not going to use your db to do stuff with the data. Columns should be used for properties and properties only. So if a player has multiple items. We need two tables, and not more columns. Each new item should a row in the second table. This page has a good example of how you would bind items/orders to a person: https://www.w3schools.com/sql/sql_foreignkey.asp
-
You are only setting it ON, even when you are trying to set it OFF. engineSetModelLODDistance(elementID, eventName == "onClientResourceStart" and 1000 or 150) 1000 is ON. Something below 170 is OFF. ( probably each object has an unique LOD distance value )
-
I copied the first from the wiki page: serialsToUse = { "111", "222", "333" } local queryString = dbPrepareString( connection, "SELECT * FROM `player_info` WHERE true" ) for _,serial in ipairs(serialsToUse) do queryString = queryString .. dbPrepareString( connection, " AND `serial`=?", serial ) end local handle = dbQuery( connection, queryString ) And changed it a bit serialsToUse = { "111", "222", "333" } local queryTable = {} queryTable[#queryTable + 1] = dbPrepareString( connection, "SELECT * FROM `player_info` WHERE true" ) for _,serial in ipairs(serialsToUse) do queryTable[#queryTable + 1] = dbPrepareString( connection, " AND `serial`=?", serial ) end local handle = dbQuery( connection, table.concat(queryTable) ) The performance increasement is exponential. Which depends on the content. With just 2 strings, the performance will probably not getting any better. (worse) String concatenate * strings VS (table index: .concat) + function call
-
dbExec should be fine, your server might experience performance impact, but shouldn't freeze in a badly way. dbQuery is a different story. This is where you should use the callback function. You do not want your resource to wait for the database [doing something ...] > while starting up. The callback function will inform you when the player is ready to play.