Jump to content

DiSaMe

Helpers
  • Posts

    1,447
  • Joined

  • Last visited

  • Days Won

    32

Everything posted by DiSaMe

  1. You're getting the text of the selected item of giveWindowGridlist and using that text as row index of gridlistPlayers1 to get the text from. Which won't work unless the grid list actually contains values like 0, 1, 2, ... I think you meant to get the player name the same way you get item? Like using guiGridListGetSelectedItem on gridlistPlayers1 and then passing the result to guiGridListGetItemText?
  2. 1) To make the sound play for other players, you should make all the controlling code server-side, and use triggerClientEvent on nearby players to trigger a client-side event which would call playSound3D. To reset the timer when the player exits the bus: instead of having a timer run all the time, call setTimer in onPlayerVehicleEnter to start the timer and killTimer in onPlayerVehicleExit to stop the timer. 2) You have a variable player for the first parameter in sendTexturesToPlayer, but onPlayerJoin has no parameters and uses source for the player who joined - so you need to pass source instead of player to triggerClientEvent. But even then, there's another problem: when the player joins, the resource hasn't loaded on the client side yet so it hasn't had time to call addEvent yet, which will cause triggerClientEvent to fail. Instead, you need to use onPlayerResourceStart for this. Because this event will be triggered on each resource start, you also need to check if its first parameter (loadedResource in the wiki) equals the return value of getThisResource.
  3. From your description it's not really clear if you use all needed functions. You mentioned engineLoadTXD/DFF, but do you also call destroyElement? Those are elements so they remain in the memory until you destroy them. I tried making loading on demand once (I ran into some bugs so it didn't work at all, but that was in 2010), and realizing that destroyElement needs to be called is one of the things I've had in mind since then. I had no trouble figuring it out, but it felt unintuitive. On one hand, it's the same as destroying objects, vehicles, markers and other elements, you destroy them when they're no longer needed. On the other hand, unlike those elements, TXD and DFF are not physical entities on their own that exist inside GTA world, so the need to destroy them is easy to miss. It's like destroying objects/vehicles/markers is a part of gameplay (the element is visible and interacts with other elements and the game world, then it disappears), while destroying TXD/DFF is a part of memory management (nothing changes gameplay-wise, it's just needed for technical reasons).
  4. You're welcome, I'm glad that was helpful.
  5. I disagree. I needed to understand matrices, figuring out how they work (examples in getElementMatrix wiki page were an important part of that) was one of my major achievements because it enabled me to do calculations in 3D that I hadn't been able to before then. It's up to each person to decide if they need it or not. It was definitely not a waste of time for me so I wouldn't make such strong assumptions. As you have noticed, the 4th table represents the position. As for the others - they represent rotation and scale. More specifically, the 3x3 part of the matrix (that is, from matrix[1][1] to matrix[3][3]) is what you would call a "rotation matrix", which tells the directions of the object's coordinate system with respect to the world's coordinate system. matrix[1] tells where the object's X direction is pointing to, matrix[2] tells Y and matrix[3] tells Z. This allows you to do transformation of points from one coordinate system to another, using addition/subtraction and multiplication operations. For example, if you want to calculate the absolute coordinates of a point that's 0.5 units to the right (X) and 2 units to the front (Y) from the car, the calculations would go like this: absolute_position = 0.5*car_x_direction + 2*car_y_direction + car_position Or, by including the Z direction for completeness, we can also express it like this: absolute_position = 0.5*car_x_direction + 2*car_y_direction + 0*car_z_direction + car_position Basically the relative coordinates are (0.5, 2, 0), and by multiplying each component by vector of respective direction of the car and putting them together, you get the offset from the car in world's coordinate system, then by adding the car's position you get the absolute position. Written in plain Lua, with calculations done separately on each component, it would look like this: local absolute_position = { 0.5*matrix[1][1] + 2*matrix[2][1] + 0*matrix[3][1] + matrix[4][1], 0.5*matrix[1][2] + 2*matrix[2][2] + 0*matrix[3][2] + matrix[4][2], 0.5*matrix[1][3] + 2*matrix[2][3] + 0*matrix[3][3] + matrix[4][3] } That's the kind of calculation that happens inside matrix:transformPosition when using MTA's Matrix and Vector3 classes. It's up to you which one you use. Using MTA's classes helps you keep your code concise, while doing the calculations yourself allows you to reuse the math code anywhere else you use Lua, not just in MTA. As for your specific case - getElementBoundingBox returns the bounds relative to the element. So you can use them to choose a point in car's coordinate system and then transform it using the matrix. To elaborate a bit more regarding the matrix values in your example - notice how, if we round the small values to zero (they are non-zero because of some numerical inaccuracies to begin with), the 3x3 part looks like this: matrix[1] = {1, 0, 0} -- X axis (the right side), matches the world's X direction (east) matrix[2] = {0, 1, 0} -- Y axis (the front), matches the world's Y direction (north) matrix[3] = {0, 0, 1} -- Z axis (the top), matches the world's Z direction (top) Which demonstrates that since your car is not rotated, each of your car's X, Y and Z direction points to the respective direction in the world's coordinates. If you rotated the car clockwise by 90 degrees, the values would be different: matrix[1] = {0, -1, 0} -- X axis (the right side), matches the world's -Y direction (south) matrix[2] = {1, 0, 0} -- Y axis (the front), matches the world's X direction (east) matrix[3] = {0, 0, 1} -- Z axis (the top), matches the world's Z direction (top) I hope this explanation helps you in case you want to understand better how matrices work. And if you don't care what happens under the hood, then it's okay too, you can just use Matrix and Vector3 classes with transformPosition method.
  6. DiSaMe

    Ped Saving

    If you want something to happen at a specific time, you can call getTime (for in-game time) or getRealTime (for real time) to retrieve the current time and use it to calculate the interval from the current moment to that specific time. Then call setTimer with that interval. To make a ped reappear after death, you would do all of that in setPedWasted event, destroying the old ped and creating a new one from within the function passed to setTimer.
  7. There's no functionality for creating water emitters, but I just had an idea for a workaround: you can create a fire truck, make it invisible (using setElementAlpha) and collisionless (setElementCollisionsEnabled), create a ped (createPed), put it into the fire truck (warpPedIntoVehicle) and have it use the water cannon (setPedControlState with vehicle_fire control). If you want to attach it to a vehicle, you can attach the fire truck itself with attachElements. To move/rotate the water cannon around, you can change the position/rotation of the fire truck and/or use setVehicleTurretPosition. You may have to take some further measures to hide the fact that it's a separate vehicle, like disabling the damage (setVehicleDamageProof), preventing players from entering it (cancelEvent in onVehicleEnter event) and whatever else you can think of.
  8. From what I understand, the time setting is a part of the map, used by mapmanager resource to change the time. Nothing to do with your script, it's just that they both call setTime, and each call overrides whatever the time was set to previously. If you want to override it from your script, you can try using mapmanager's event onGamemodeMapStart for that - so whenever a map starts and the mapmanager changes the time, your script would change it back. According to the code of mapmanager, the map settings are applied after onGamemodeMapStart is triggered so your overriding code should have a delay in order to set time after the map's time setting is applied, not before. setTimer with 0 milliseconds will probably do the thing. I'm not familiar with manager resources so I don't know if there's a cleaner way to do it.
  9. If you take a closer look at the first line, the part that retrieves the name looks like this: getAccountName(getPlayerAccount(player)) While in the new line, it looks like this: getPlayerAccount(player) getPlayerAccount function returns an account, which is a separate MTA data type, so comparing it to a string will always evaluate to false. You need to use getAccountName like the original line does, but to avoid retrieving the name multiple times, it's better to store it in a variable: local name = getAccountName(getPlayerAccount(player)) if name == "SomeStaffName" or name == "SomeOtherStaffName" or name == "YetAnotherStaffName" then -- code to execute if the name matches end Even better, you can put the names as keys into the table and do the lookup: -- outside the function local StaffNames = { SomeStaffName = true, ["Some Other Staff Name"] = true, -- both forms are valid but this one allows spaces and other symbols that cannot be used with the other form YetAnotherStaffName = true } -- inside the function local name = getAccountName(getPlayerAccount(player)) if StaffNames[name] then -- code to execute if the name matches end But a script that bans someone for attempting to ban someone else looks like a script that may have unintended consequences.
  10. Let me guess, you're calling triggerClientEvent from onPlayerJoin. But onPlayerJoin is triggered before the client scripts have been downloaded and started so it won't work. You have to call triggerClientEvent when you know the client-side script has started. In the older days, we would use triggerServerEvent from the client-side script to let the server know. Now there's onPlayerResourceStart event for that.
  11. If you know for sure the problem is not in your code, then yes, resources that come with MTA could be another place to look. I would try replacing kickPlayer with a wrapper that calls debug.traceback and outputs it to the log in all running resources, so whenever a player gets kicked by a script, the server log would tell where the call came from. Then, if the traceback doesn't show up in the log, most likely it was done directly using /kick command. Which either means they somehow managed to gain access or there's actually a vulnerability in MTA server. I'm not ruling out any possibilities, but I assume user mistakes first.
  12. Good way to make what? If you always pass localPlayer as source and the first argument when triggering from client to server, you may as well not have the first argument, ignore the value of source and just use client variable. Doing comparison of values may help you detect some of the faked calls (if the values don't match, it's obviously faked), but unless you do something different in those cases (such as logging/kicking/banning), I don't see any use in that - if you rely on equality of received values to silently ignore the obviously-faked calls, the hackers will pass equal values to avoid the calls getting detected as faked.
  13. I don't understand what you're saying. Do you mean the hacker triggers events on behalf of other players? So it appears as if a different player triggered it? I've seen enough poorly written scripts to expect that to happen. People tend to pass localPlayer as source element to triggerServerEvent and then use the source variable on the server to identify the caller. But like any data passed to triggerServerEvent, the source element can be faked so the hackers do exactly that to make the events appear to originate from other players. The variable client is the correct way to identify the client that triggered the event. If it is possible to write a client-side script to do something, then that something can be done by hackers. The anti-cheat is there to keep the hackers from doing it but it cannot in principle solve the problem "once and for all" and shouldn't be relied upon for script security.
  14. Improving the anti-cheat can make it harder for malicious users, but it can never solve the problem, because one way or another, it has to rely on things being checked on the client side. It's just impossible to make sure that whatever runs on the client is authentic - what is possible, is to make it harder to replicate the appearance of authentic. But there will always be ways around that. However, These don't sound like anti-cheat problems at all - more like problems in the server. Unless they are MTA server bugs (which would be a huge security issue, very worrying indeed, but I find that very unlikely), they must be caused by scripts you run on the server. Like a server-side script that receives events from the client side and processes them without performing any validation. It's definitely not up to the anti-cheat to take care of that. Just because the anti-cheat makes it harder for hackers to exploit the server's script security holes, that doesn't mean those security holes should be there in the first place. Likewise, compiling the client scripts increases the amount of effort the hackers need to put in, but that's not going to make much difference for someone who can overcome the anti-cheat.
  15. What an opportunity for me to join the rant! I feel your pain. I'm another person who's tired of how you "have" to buy newer and newer and more powerful stuff so that you could continue doing the same thing you have been doing all along with no problems. My most powerful computer is a laptop that I bought 10 years ago, plus I still have my Pentium 4 that I got in 2005. I could easily buy a new computer, much more powerful and all, but what's the point? I've had lots of fun on these two, and the possibilities are far from exhausted, therefore there is nothing wrong with them, and I absolutely refuse to believe otherwise. Not powerful enough to run some software? Guess what, it is software that is wrong. I'm not going to change my opinion about hardware just because someone developed some piece of bloatware. Funnily enough, the people who expect me to accept someone's arbitrary requirements as objective facts without questioning, are the same kind of people who would try to tell me how to stand up for myself and not be a pushover. Hahaha. What a bunch of nonsense. But MTA has hardly ever been a part of this problem for me, so it looks like I'm better off than you in this regard. I'd say it's more Microsoft's fault for making more and more demanding Windows. As for MTA, it just supports the versions of Windows that are supported by Microsoft, which makes sense - although it depends on how you look at it, which I guess is the point of this topic. But I wonder what's wrong with your graphics drivers on Linux. Does MTA not work at all or does it just run poorly? Yesterday I managed to start MTA SA 1.5.9 on that Pentium 4 under Arch Linux 32. It supports OpenGL 1.4 using Mesa i915 driver (or OpenGL 2.1 with some non-default settings, but it may be bad for performance). It was far from playable and had some visual glitches, but it ran. Perhaps could be improved with some settings, because I think I had GTA SA in general run faster in 2011-2013 than it does now - not sure if I can trust my memories, but it doesn't look believable that I could develop the NPC traffic resource and record some MTA videos while lagging that much. As for my laptop, it has Intel HD 2000 (supports OpenGL 3.3) and runs well enough. So it would be surprising to me if your Intel HD from 2010 couldn't run MTA on Linux at all. Without knowing the details, I would expect it to run and be playable at least. Or almost playable, depending on your threshold of "playable" and the server. That said, I do like the idea of MTA keeping support for systems it currently supports, or even supporting XP again. It sounds attractive to be able to run MTA under the same configuration I did in 2008. But as far as OS is concerned, this wouldn't make a practical difference for me because I switched to Linux long ago. So while I do more or less support your position on this matter, I can't personally request the same thing from MTA developers. I mean it doesn't make much sense for me to ask for something that I know I'm very unlikely to make use of. I agree with your notion of universal code that just does what it's supposed to do regardless of environment where it's running. When I write code, I try to make it do its own thing correctly, and depend as little as possible on platform or library specific stuff. But I can't speak for MTA because MTA is not a standalone program, it inherently depends on GTA. Meaning there's lots interaction with some particular executable, in ways defined by Windows and inherently less room for just doing its own thing. In the end, it's nice to know I'm not the only one dissatisfied with this trend of more and more demanding software and thinks there needs to be some resistance. I've just kept MTA out of this because it has been "good enough" for me.
  16. It looks like my post is irrelevant then. I was assuming you wanted to make new dimension IDs so that it would be easier to avoid such mistakes like accidentally using same dimension ID for things that should be in separate dimensions. But from what I understand, that's not the problem, so you can just pick some ID and use it for your island. Dimensions don't have weathers, all they have is elements. However, if you set weather in the client-side script, it only changes for that player. If you change the weather for the player alongside putting that player in the dimension, from their perspective it will appear as if that dimension has a different weather. To achieve this, whenever you call setElementDimension, you can also call triggerClientEvent to trigger a custom event, which then you would use to call setWeather on the client-side script. For customizing weather-related properties, in addition to links that @FlorinSzasz posted, there are several other functions, such as setColorFilter and setFogDistance, that you would call on the client side.
  17. You can do that using setWeaponProperty function. I haven't used it myself so I'm not familiar with it, but according to that page, you need to modify anim_loop_stop to increase the firing rate.
  18. That's a low level of detail object, which appears when the original one isn't showing. It's a separate object with a different model ID, so you need to add another removeWorldModel call with that other model ID.
  19. onClientElementColShapeHit event doesn't trigger for vehicles, only colshapes. You must be looking for onClientVehicleCollision.
  20. You can't "create" new dimensions. But the element limit is 2^16 = 65536. And there are also 65536 dimensions - just enough to store each element into its own separate dimension. This allows you to create your own dimension system, based on the built-in one. In fact, I tried something like that a long time ago. A dimension system that used arbitrary values as dimension IDs, with each value being assigned a unique integer from 0 to 65535. You can use tables to track things like which elements each dimension contains and which custom dimension system ID corresponds to which built-in dimension system ID.
  21. The proper way in Lua to use arguments in a function created using loadstring is vararg expression, written as three dots. local argument1, argument2, argument3 = ... In your case, the function body would look like this: local player = ... return getPlayerName(player) == 'owner' An example with loadstring: local func_str = "local player = ... return getPlayerName(player) == 'owner'" local loadstringed = loadstring(func_str) local testPlayer = getPlayerFromName("player1") local success, info = pcall(loadstringed, testPlayer)
  22. Resources do not run "for specific players". Each resource runs for all players and on both server and the client. Nothing to start/stop/restart on player join - you do it when starting up the server, just like with ordinary gamemodes. It's just that the gamemodes have to be modified so that instead of doing stuff on the global level, they would do it in their own scopes. For example, if the gamemode executes some code in onPlayerJoin event, you have to modify it to execute that code when the player enters that gamemode instead. Likewise, if the gamemode does something in onPlayerQuit, it has to be done when the player leaves the gamemode - which could be when the player quits, or when they switch to a different gamemode. If the gamemode calls getElementsByType to retrieve all elements of a particular type in the server, it has to pick out its own elements only, to avoid acting on another gamemode's elements.
  23. I guess motorcycles and bicycles have some tilt property that is separate from rotation and changes as you steer. Maybe it's just visual. Maybe it's not even a property on its own, but rather one of the effects of steering state. And I also assume that setElementFrozen only locks position, rotation and velocity - in which case that tilting property would remain unaffected. A long time ago, I tried making a CLEO script that records the player's driving route by writing the vehicle's position, rotation and velocity to a file in short intervals, and then plays it. I wasn't able to get it to look properly on bikes, because the bike wasn't tilting to the side it was steering during the playback - to the contrary, it was slightly steering to the opposite side. I did realize it was because of lack of control states, but didn't know how to overcome that problem. Now that you pointed out the behavior of setElementFrozen, it looks related. Interesting to find out many years later
  24. Oh, hey there Slothman! Long time no see. Although I do not tend to know people well (since I'm not a very social person), you're one of the people I remember when I think of the old days. For this reason, when I returned to this forum a couple of years ago, after not visiting for several years, it was sad to find that some of the people I could recognize, including you, were no longer here. So happy to see you again! Because peds are my favorite MTA feature, I consider your creation of Zday and Slothbot an important step towards getting the community to use this feature (although I'm not sure if I have even seen Slothbot in action). But I can still remember feeling disappointed when peds remained criminally underused. My NPC HLC resource that I made in 2012, was supposed to serve as a library for people who want to control peds from their scripts without having to take care of low level stuff like individual control states - thought it would make ped scripting more popular. But even though I based my traffic resource on it, in the end it hardly got anywhere, because of all things I wanted to implement, it only had the most basic tasks. From what I know, there have been more people making use of peds in the recent years. But I still want to do what I was trying to do many years ago. To turn ped scripting into an easy task that even beginners could do.
  25. The purpose is to alter the behavior of functions - or so it appears. It's all just assignment to variables. local _triggerClientEvent = triggerClientEvent This line creates a local variable _triggerClientEvent and assigns the value from triggerClientEvent - which usually means that _triggerClientEvent now refers to the MTA-defined function that triggers the client events from the server. function triggerClientEvent( triggerFor, name, theElement, ... ) ... end This one creates a function and assigns it to the global variable triggerClientEvent, meaning that calls to triggerClientEvent from other scripts in the same resource will call this function instead of the original one. This new function probably contains _triggerClientEvent calls, which are calls to the MTA-defined function.
×
×
  • Create New...