Jump to content

IIYAMA

Moderators
  • Posts

    6,061
  • Joined

  • Last visited

  • Days Won

    208

Everything posted by IIYAMA

  1. IIYAMA

    HELP

    You will have to cancel the following event when you are glued. You can for example check if the player is attached to anything and then cancel the event. https://wiki.multitheftauto.com/wiki/OnVehicleStartEnter addEventHandler ( "onVehicleStartEnter", root, function (player) if getElementAttachedTo (player) then -- check here if you are glued or not. cancelEvent() end end )
  2. IIYAMA

    Help ! acl

    @scolen You can give this utility function a try (untested). It is important to know that you can only check this information serverside. --[[ Check if the player is inside of an acl group with a specific name Argument 1: player element Argument 2: aclGroupName string ]] function isPlayerInAclGroupWithName (player, aclGroupName) -- Check if the player argument is filled in correctly if not isElement(player) or getElementType(player) ~= "player" then error("Expected player element at argument 1, got " .. inspect(player), 2) end -- Check if the aclGroupName is filled in correctly if type(aclGroupName) ~= "string" then error("Expected string at argument 2, got " .. inspect(aclGroupName), 2) end -- Get the player account and check if the player is logged in local account = getPlayerAccount ( player ) if isGuestAccount(account) then return false end -- Get the acl group local aclGroup = aclGetGroup ( aclGroupName ) if not aclGroup then return false end -- Check if the account name of the user is inside of the acl group local accountName = getAccountName ( account ) return isObjectInACLGroup ("user." .. accountName, aclGroup) end Usage: if isPlayerInAclGroupWithName(player, "police") then outputChatBox("I am the police", player) end
  3. Please show the JSON, that is the easiest way of checking why the conversion is failing. Also don't use the following array formatting: { [1] = {}, [2] = {} } Keep it clean, no gaps if possible, if you do have gaps add a false value or an empty table: { {}, {} } The conversion between Lua and JSON is rather sensitive if you do not follow the JavaScript Object Notion rules. Another golden rule: Don't mix keys of different key types, it is either strings or integer each (sub)table. If one of them is a string, all of them become strings. There is no such thing as a table in JavaScript, there is only an default object(key strings) or an array(key integers).
  4. A matrix is a mixture of a position and orientation(rotation). With as main purpose able to calculating offset. For example you want to place a ramp in front of a vehicle, a matix helps you with that. But you do NOT need to know how a matrix works, don't waste your time XD. I prefer to use the Matrix class(without oop), instead of getElementMatrix: local x, y, z = getElementPosition(vehicle) local xr, yr, zr = getElementRotation(vehicle) local vehicleMatix = Matrix (Vector3(x, y, z), Vector3(xr, yr, zr)) -- build your matrix with position and rotation local offset = Vector3(0, 0, 0) -- fill in! local newPosition = matrix:transformPosition(offset) iprint(newPosition.x, newPosition.y, newPosition.z) See docs: https://wiki.multitheftauto.com/wiki/Matrix Utility function: function getMatrixFromElement (element) return Matrix (Vector3(getElementPosition(element)), Vector3(getElementRotation(element))) end
  5. Is the error it still at this line? Or a different line? (note the resource has to be restarted) for i, item in pairs(inv) do
  6. Directly after getting the element data:
  7. There is also this serverside function: https://wiki.multitheftauto.com/wiki/GetPlayerIdleTime Or check when the player is pressing a button: https://wiki.multitheftauto.com/wiki/OnClientKey
  8. How validation works? When data comes from an external source, in this case element-data, there is no way of knowing that it is valid. Therefore checking if the data is OK is essential. For example if the script tries to get the element-data under the key "char:items" before it has an value assigned to it, the script without data validation will most likely end up with an warning or error at a certain point. Are you suggesting that it is not good for you? Well this is more or less the format in which you receive help in this forum section. If I misunderstand you, please let me know.
  9. Always validate your element-data before you are going to do something with it: local inv = getElementData(localPlayer, "char:items"); ----------------------------------------------- assert(type(inv) == "table", "inv must be a table") -- hard error -- or if type(inv) != "table" then -- outputChatBox("OH NO, I need a table to put my head on...") return end If element data is not set, the variable inv does not contain a table, but false instead.
  10. Another way would be manually modify the ACL: <right name="command.theCommand" access="false" /> <right name="command.theCommand" access="true" /> And set restricted to true (this is the syntax for addCommandHandler): bool addCommandHandler ( string commandName, function handlerFunction [, bool restricted = false, bool caseSensitive = true ] ) This will restrict specific commands based on the ACL. The choice depends where you want the restriction/validation being placed. During executing the command or in the function of the script.
  11. IIYAMA

    [HELP]DATABSE

    You might consider using another filename. Also stopping the resource on onResourceStart is a good way for error handling, since this resource is not very useful without a databasse. addEventHandler ( "onResourceStart", resourceRoot, function () vehDB = dbConnect( 'sqlite', 'veiculosdatabase.db' ) if not vehDB then return cancelEvent (true, "Unable to connect to database.") end dbExec( vehDB, ' CREATE TABLE IF NOT EXISTS `VehiclesSystem_Players` (pSerial, vehID, vehName, vehPrice, Subscription) ' ) end, false)
  12. For easy and fast management. For looping speed. (complexer management) Note: you can also go for both. Or you could go for this one: https://wiki.multitheftauto.com/wiki/CreateElement (as parent) https://wiki.multitheftauto.com/wiki/SetElementParent Benefits: No need to clean up after a ped is deleted. Able to get specific streamedin peds at clientside. Attach eventHandlers to all your peds and only those. (Whipe all peds with just one destroyElement call > propagation.)
  13. AI thinking is not linear unfortunately. But some tasks are, and yet those probably can be interrupted in some way. Therefore it is important to run some of the checks every cycle. You could give something like this a try: local dataStorage_AI = {} -- Give the ped a brain if it hasn't one yet. function init_AI (ped) if dataStorage_AI[ped] then return end dataStorage_AI[ped] = { controls = {}, -- pressed controls maybe? (since serverside is not aware) element = ped } end -- Run the main update cycle function update_AI(ped) if not dataStorage_AI[ped] then return end -- no storage, no brain... if isPedDead(ped) then return end if isElementInWater(ped) then return runPedInWaterInstructions (ped) end end -- If the ped is in the water, do stuff here function runPedInWaterInstructions (ped) local pedData = dataStorage_AI[ped] -- do something here end
  14. IIYAMA

    Console

    You can inspect resource usage with the performancebrowser: http://SERVER_IP:HTTP_PORT/performancebrowser/ (It will ask you to login with your ingame admin account) Might be, it also depends what is spammed. For example a command (attached to a synced database query) can be more impactful than just a chat message.
  15. I tested your code and it works fine. But keep in mind that in your current setup it is used as an auto complete feature. Typing `Jo` makes auto complete John available. Also when you press your arrow-down key, it should act more as the options tag as @FLUSHBICEPS referring to.
  16. When loading code, you are putting a kind of chunk/function around it. So basically this: function(player) return getPlayerName(player) == 'owner' end Looks more or less like this: -- pcall(loadstringed) is calling this chunk/function: function () function(player) return getPlayerName(player) == 'owner' end end So in order to solve this: return function(player) return getPlayerName(player) == 'owner' end local success, theFunc = pcall(loadstringed) local success2, isOwner = pcall(theFunc, testPlayer) See also xpcall for better error handling: https://www.gammon.com.au/scripts/doc.php?lua=xpcall
  17. The generic answer is, you need to create a resource that serves as manager > and rewrite each gamemode, so that their usage can be scoped(data/elements/events) for specific players. Best is to get inspiration from an already existing Multi Game Mode resource. Since this is really a lot of work and complexity. Explaining the process from A to B would take too much of my time (sorry).
  18. Try this: triggerClientEvent ( (function () local players = getElementsByType("player") for i=1, #players do if players[i] == source then table.remove(players, i) break end end return players end)(), -- IIFE (Immediately Invoked Function Expression) "runOurClientEvent", root )
  19. When the resource starts a new resourceRoot element will be created. This element is destroyed when the resource stops. It is therefore not a good idea to attach eventHandlers to the resourceRoot's of other resources. (Unless you keep track of start/stop resources) In your current example you mentioned the eventName onPlayerFirstSpawn. The player makes it's first spawn. From a semantic perspective, the player is therefore the one activating the event. And I expect it therefore to be used as the source of that event. The element above a player is the root element and should be used for the eventHandler of that event. The root element is not deleted when restarting resources. But never the less, here is how to solve the resource validation issue: addEventHandler("<eventName>", root, function () local resource = getResourceFromName( "<resourceName>" ) if not resource then return end if source == getResourceRootElement(resource) then -- The source is from the correct resource end end) Another way to keep the resource start up in order is to use the tag: <include resource="resourceName"/> https://wiki.multitheftauto.com/wiki/Resources
  20. Looks nice! Just some side notes, feel free to ignore those. I recommend not do these kind of animations serverside. You are basically sending data to the client/player every 20 milliseconds, which might causing network trouble on a not local server. Just set the end-value serverside. And trigger an even clientside + do the animation there. Also the GTA default money animation can be displayed with setPlayerMoney (unless of course you want to use a custom transition): https://wiki.multitheftauto.com/wiki/SetPlayerMoney
  21. Try this one instead: https://wiki.multitheftauto.com/wiki/GetPedTargetEnd Note: The returned values can be nil.
  22. I understand that you want to do the calculations your self. But if you are using a matrix, you really do not have to think about all that complex and brain exploding stuff. https://wiki.multitheftauto.com/wiki/Matrix local x, y, z, rx, ry, rz x, y, z = getElementPosition(getPedOccupiedVehicle(source)) rx, ry, rz = getElementRotation(getPedOccupiedVehicle(source)) local vehicleMatrix = Matrix ( Vector3(x, y, z), Vector3(rx, ry, rz) ) local offsetX, offsetY, offsetZ = 0, 0, 0 local newPosition = vehicleMatrix:transformPosition ( Vector3(offsetX, offsetY, offsetZ) ) SpawnedObject = createObject(987, newPosition.x, newPosition.y, newPosition.z) setElementRotation(SpawnedObject, rx, ry, rz, "ZYX") Note: You can do all of this with less lines.
  23. Just a note. Instead of doing a source validation. -- The source for this event is always 'resourceRoot' if source ~= resourceRoot then reportNaughtyness( eventName, client, "source" ) return end You can also disable propagate: addEvent("onRaiseTheRoof", true) addEventHandler("onRaiseTheRoof", resourceRoot, function(arg1, arg2) end, false -- < disable propagate ) While it does not report naughtiness, it is very easy to add.
  24. It is called a Wrapper function. It is used to add extra functionality too an existing function. For example the setElementPosition function. It's syntax is now: --[[ Syntax: setElementPosition ( element theElement, float x, float y, float z [, bool warp = true ] ) -- https://wiki.multitheftauto.com/wiki/SetElementPosition ]] All arguments except for warp are required. An example wrapper function: local _setElementPosition = setElementPosition -- Re-define original function (so that it is still accessible) function setElementPosition (element, x, y, z, warp) -- Overwrite the existing setElementPosition with your wrapper function (it is overwritten, because the function name is the same) if not x then x = 0 end if not y then y = 0 end if not z then z = 0 end return _setElementPosition(element, x, y, z, warp) -- calling the original function end The x, y, z parameters do not have to be filled in any more. They are by default set to 0. The new syntax would be now: --[[ Syntax: setElementPosition ( element theElement, [ float x = 0 ], [ float y = 0 ], [ float z = 0] [, bool warp = true ] ) -- https://wiki.multitheftauto.com/wiki/SetElementPosition ]] Is this wrapper function useful? Not really. ?
  25. Change isMapVisible() to isPlayerMapVisible(). https://wiki.multitheftauto.com/wiki/IsPlayerMapVisible isMapVisible is an OOP method. Used like this (if OOP is enabled): localPlayer:isMapVisible()
×
×
  • Create New...