Zuher Laith Posted November 3, 2017 Share Posted November 3, 2017 Hi everyone, So recently I have been working on some scripting with the famous bone_attach script and I've noticed something important, when I attach object to the client and the client teleports to another interior/dimension, the objects gets invisible but when I go back to the 0 dimension&interior, It gets visible ! plus, even If I created and attached the object in dimension/interior other than 0, its Invisible, I teleport to 0 it gets visible . In this case, how should I make the object that attached to the client visible when he goes to another dimension & interior ? Any help is appreciated . Link to comment
Moderators IIYAMA Posted November 3, 2017 Moderators Share Posted November 3, 2017 You could try: setElementParent(object, player) Not sure if it works, because I haven't tested it with dimension change before. Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 9 minutes ago, IIYAMA said: You could try: setElementParent(object, player) Not sure if it works, because I haven't tested it with dimension change before. unfortunately, it didn't work on dimension change .. function attachToPedHandler () PepsiCan = createObject(1487,0,0,0) exports.bone_attach:attachElementToBone(PepsiCan, client, 12,0,0,0,0,-130,20) setElementParent(PepsiCan, client) end but I thought about using SetElementDimension & SetElementInterior , but how do I check for dimension/interior player change ? Link to comment
Moderators IIYAMA Posted November 3, 2017 Moderators Share Posted November 3, 2017 There is no event for that. What you need to do is either find the player where the dimension/interior changes. Or use a timer to detect if it has changed. The attached elements can be retrieved like this: (if setElementParent is used) local attachedObjects = getElementChildren ( player, "object") -- this one might work as well, not tested. local attachedObjects = getElementsByType ("object", player ) Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 You could also make it an event yourself: local DIM_REFRESH_FREQ = 1000 addEvent("onClientDimensionChange") local lastDimension = getElementDimension( localPlayer ) function CheckPlayerDimension() local curDim = getElementDimension( localPlayer ) if curDim ~= lastDimension then triggerEvent( "onClientDimensionChange", localPlayer, lastDimension, curDim) lastDimension = curDim end end setTimer( CheckPlayerDimension, DIM_REFRESH_FREQ, 0 ) it does check if player dimension changed every second, and if it happened it triggers event, it passes last dimension and new one as event arguments. Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 24 minutes ago, IIYAMA said: There is no event for that. What you need to do is either find the player where the dimension/interior changes. Or use a timer to detect if it has changed. The attached elements can be retrieved like this: (if setElementParent is used) local attachedObjects = getElementChildren ( player, "object") -- this one might work as well, not tested. local attachedObjects = getElementsByType ("object", player ) well, this was the result and it worked without a timer : function attachPepsiHandler () PepsiCan = createObject(1487,0,0,0) setElementParent(PepsiCan, client) exports.bone_attach:attachElementToBone(PepsiCan, client, 12,0,0,0,0,-130,20) -- the code works like this (with uncomment): --setTimer(function() --local attachedObjects = getElementChildren ( client, PepsiCan) -- problem here if not ( getElementDimension ( client ) == 0 ) then -- And here --if attachedObjects then playerdim = getElementDimension ( client ) setElementDimension ( PepsiCan, playerdim ) --end end --end, 1000, 0) -- if I uncomment them, here are the errors: [15:22:59] WARNING: vend\server.lua:22: Bad argument @ 'getElementChildren' [Expected element at argument 1, got nil] [DUP x4] [15:22:59] WARNING: vend\server.lua:23: Bad argument @ 'getElementDimension [Expected element at argument 1, got nil] [DUP x4] end Link to comment
Moderators IIYAMA Posted November 3, 2017 Moderators Share Posted November 3, 2017 (edited) It looks like you are trying to use the predefined variable `client` within a function that is not called by an addEventHandler. Also you can't fill in PepsiCan as second argument, only an elementType in the form of a string is acceptable. So use the type "object", because that is what PepsiCan is. Edited November 3, 2017 by IIYAMA Link to comment
Enargy, Posted November 3, 2017 Share Posted November 3, 2017 why don not you edit attach's resources? You can add setElementDimension/Interior in the render event. 1 Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 (edited) There is now many different replays and ideas in the topic, lets make them one. I've created a function in the bone_attach (idea by Enargy,) and used isElementAttachedToBone to check if object is destroyed later instead of attachedObjects Spoiler -- Server side: function attachPepsiHandler ( thePlayer ) PepsiCan = createObject(1487,0,0,0) exports.bone_attach:attachElementToBone(PepsiCan, thePlayer, 12,0,0,0,0,-130,20) -- this point here, it takes a second to attach the element to player in a dimension other than 0 playerdim = getElementDimension ( thePlayer ) playerint = getElementInterior ( thePlayer ) exports.bone_attach:setElementDimInt(PepsiCan, thePlayer, playerdim, playerint) -- so I wrote this to attach it instantly setTimer(function() if exports.bone_attach:isElementAttachedToBone(PepsiCan) then playerdim = getElementDimension ( thePlayer ) playerint = getElementInterior ( thePlayer ) exports.bone_attach:setElementDimInt(PepsiCan, thePlayer, playerdim, playerint) else return end end, 1000, 0) end addEvent( "AttachPepsi", true ) addEventHandler( "AttachPepsi", resourceRoot, attachPepsiHandler ) and the attach_func.lua in bone_attach resource: function setElementDimInt(element,ped,dim,int) if not (isElement(element) and isElement(ped)) then return false end if not dim then return false end if not int then return false end if getElementType(ped) ~= "ped" and getElementType(ped) ~= "player" then return false end dim,int = tonumber(dim) or 0,tonumber(int) or 0 setElementDimension(element, dim) setElementInterior(element, int) return true end Everything works as suppose to be, but I'm afraid of timers, is this going to be a cause of server usage if I change the timer interval to "100" ? .. because this is on server side . Edited November 3, 2017 by Zuher Laith Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 4 hours ago, quindo said: it does check if player dimension changed every second, and if it happened it triggers event, it passes last dimension and new one as event arguments. let me be honest with you, it became confusing to me since I have a problem with understanding events, client, server .. As I saw your code, I thought this is a client and I didn't understand how should I correctly use it . would you please explain to me how can I change the element dimension based on the code you provide on server side ? Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 Ah, my code is client sided, and it only detects if local player changed dimension, if you need something that can update each player server sided i don't think something like that would be a good choice. Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 3 minutes ago, quindo said: Ah, my code is client sided, and it only detects if local player changed dimension, if you need something that can update each player server sided i don't think something like that would be a good choice. Didn't expect that, but anyways I appreciate your help .. Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 Actually, can you check if it works? local DIM_REFRESH_FREQ = 1000 addEvent("onPlayerDimIntChange") local lastDimIntTable = {} function CheckPlayerDimension() local players = getElementsByType("player", root) for _,player in ipairs(players) do local curDim = getElementDimension( player ) local curInt = getElementInterior( player ) if not lastDimIntTable[player] then lastDimIntTable[player] = {dim = curDim, int = curInt} if (curDim ~= lastDimIntTable[player].dim) or (curInt ~= lastDimIntTable[player].int) then triggerEvent( "onPlayerDimIntChange", player, lastDimensionPlayer[player].int, lastDimensionPlayer[player].dim, curInt, curDim) lastDimensionTable[player].dim = curDim lastDimensionTable[player].int = curInt end end setTimer( CheckPlayerDimension, DIM_REFRESH_FREQ, 0 ) function updatePlayerAttachedElements(lastInt, lastDim, curInt, curDim) local attachedObjects = getElementChildren ( source, "object") for _,elem in pairs(attachedObjects) setElementDimension( elem, curDim ) setElementInterior( elem, curInt ) end end addEventHandler( "onPlayerDimIntChange", root, updatePlayerAttachedElements ) function AttachElementToBone(element, player, ...) if isElement(element) and isElement(player) then setElementParent(element, player) end return exports.bone_attach:attachElementToBone(element, player, ...) end It's not optimised at all, but it should automatically detect if player has changed dimension or interior, and update attached elements too. use AttachElementToBone function instead of exports.bone_attach:attachElementToBone I haven't tested it, so if there are any errors post it here Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 32 minutes ago, quindo said: Actually, can you check if it works? I got one error here: function updatePlayerAttachedElements(lastInt, lastDim, curInt, curDim) local attachedObjects = getElementChildren ( source, "object") for _,elem in pairs(attachedObjects) setElementDimension( elem, curDim ) -- here setElementInterior( elem, curInt ) end end addEventHandler( "onPlayerDimIntChange", root, updatePlayerAttachedElements ) -- errors: [21:21:15] ERROR: Loading script failed: vend\server.lua:52: 'do' expected n ear 'setElementDimension' [21:21:24] ERROR: Client (NiGht) triggered serverside event AttachPepsi, but eve nt is not added serverside [21:21:24] ERROR: Client (NiGht) triggered serverside event takeCash, but event Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 function updatePlayerAttachedElements(lastInt, lastDim, curInt, curDim) local attachedObjects = getElementChildren ( source, "object") for _,elem in pairs(attachedObjects) do setElementDimension( elem, curDim ) setElementInterior( elem, curInt ) end end addEventHandler( "onPlayerDimIntChange", root, updatePlayerAttachedElements ) Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 (edited) @quindo I feel so stupid after that small edit... I didn't notice .. After testing it gives no errors at start and no specific error line at debugscript 3 . but basically the code you provided made the whole server.lua like it doesn't exist and each event called from client gives the following error: Quote [21:51:06] ERROR: Client (NiGht) triggered serverside event AttachPepsi, but event is not added serverside [21:51:06] ERROR: Client (NiGht) triggered serverside event takeCash, but eventis not added serverside [21:51:08] ERROR: Client (NiGht) triggered serverside event OnDrink, but event is not added serverside and more ... Edited November 3, 2017 by Zuher Laith Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 (edited) Where are those events defined? I mean the AttachPepsi, takeCash, OnDrink ones? Edited November 3, 2017 by quindo Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 3 minutes ago, quindo said: Where are those event's defined? I mean the AttachPepsi, takeCash, OnDrink ones? -- server side: function takeCashHandler ( thePlayer, amount ) takePlayerMoney ( thePlayer, tonumber(amount) ) end addEvent( "takeCash", true ) addEventHandler( "takeCash", resourceRoot, takeCashHandler ) -- client side: triggerServerEvent ( "takeCash", resourceRoot, localPlayer, 3 ) same for the rest of those events . Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 Aren't there any other errors from the script i gave you? It seems that rest of the script fails to load. Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 (edited) 16 minutes ago, quindo said: Aren't there any other errors from the script i gave you? It seems that rest of the script fails to load. I think you forgot a lot of end if here.. Spoiler local DIM_REFRESH_FREQ = 1000 addEvent("onPlayerDimIntChange") local lastDimIntTable = {} function CheckPlayerDimension() local players = getElementsByType("player", root) for _,player in ipairs(players) do outputDebugString ( "We passed Check #1", 3) local curDim = getElementDimension( player ) local curInt = getElementInterior( player ) if not lastDimIntTable[player] then lastDimIntTable[player] = {dim = curDim, int = curInt} if (curDim ~= lastDimIntTable[player].dim) or (curInt ~= lastDimIntTable[player].int) then outputDebugString ( "We passed Check #2", 3) triggerEvent( "onPlayerDimIntChange", player, lastDimensionPlayer[player].int, lastDimensionPlayer[player].dim, curInt, curDim) -- error here lastDimensionTable[player].dim = curDim lastDimensionTable[player].int = curInt end end end end setTimer( CheckPlayerDimension, DIM_REFRESH_FREQ, 0 ) ---- Log : ---- [22:34:18] INFO: We passed Check #1 [DUP x5] [22:34:18] INFO: We passed Check #2 [DUP x5] [22:34:18] ERROR: vend\server.lua:44: attempt to index global 'lastDimensionPlayer' (a nil value) [DUP x5] Alright, everything works fine, but it doesn't change element dim/int on player change dim/int , and there is one error I found, you may want to look at the code .. Edited November 3, 2017 by Zuher Laith Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 (edited) local DIM_REFRESH_FREQ = 1000 addEvent("onPlayerDimIntChange") local lastDimIntTable = {} function CheckPlayerDimension() local players = getElementsByType("player", root) for _,player in ipairs(players) do outputDebugString ( "We passed Check #1", 3) local curDim = getElementDimension( player ) local curInt = getElementInterior( player ) if not lastDimIntTable[player] then lastDimIntTable[player] = {dim = curDim, int = curInt} end if (curDim ~= lastDimIntTable[player].dim) or (curInt ~= lastDimIntTable[player].int) then outputDebugString ( "We passed Check #2", 3) triggerEvent( "onPlayerDimIntChange", player, lastDimIntTable[player].int, lastDimIntTable[player].dim, curInt, curDim) -- error here lastDimensionTable[player].dim = curDim lastDimensionTable[player].int = curInt end end end setTimer( CheckPlayerDimension, DIM_REFRESH_FREQ, 0 ) Edited November 3, 2017 by quindo Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 4 minutes ago, quindo said: local DIM_REFRESH_FREQ = 1000 addEvent("onPlayerDimIntChange") local lastDimIntTable = {} function CheckPlayerDimension() local players = getElementsByType("player", root) for _,player in ipairs(players) do outputDebugString ( "We passed Check #1", 3) local curDim = getElementDimension( player ) local curInt = getElementInterior( player ) if not lastDimIntTable[player] then lastDimIntTable[player] = {dim = curDim, int = curInt} end if (curDim ~= lastDimIntTable[player].dim) or (curInt ~= lastDimIntTable[player].int) then outputDebugString ( "We passed Check #2", 3) triggerEvent( "onPlayerDimIntChange", player, lastDimIntTable[player].int, lastDimIntTable[player].dim, curInt, curDim) -- error here lastDimensionTable[player].dim = curDim lastDimensionTable[player].int = curInt end end end setTimer( CheckPlayerDimension, DIM_REFRESH_FREQ, 0 ) triggerEvent( "onPlayerDimIntChange", player, lastDimIntTable[player].int, lastDimIntTable[player].dim, curInt, curDim) lastDimensionTable[player].dim = curDim lastDimensionTable[player].int = curInt -- edit: lastDimIntTable[player].dim = curDim lastDimIntTable[player].int = curInt Well, now no error given & no result on changing dim/int .. Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 How are you attaching the Element now? using the orignial export function, or by the one i wrote earlier? Link to comment
Zuher Laith Posted November 3, 2017 Author Share Posted November 3, 2017 1 minute ago, quindo said: How are you attaching the Element now? using the orignial export function, or by the one i wrote earlier? the one you recommended, PepsiCan = createObject(1487,0,0,0) AttachElementToBone(PepsiCan, thePlayer, 12,0,0,0,0,-130,20) -- it works fine . Link to comment
quindo Posted November 3, 2017 Share Posted November 3, 2017 Looks like it fails to refresh, maybe something wrong with event triggering, can you check what shows in debugscript when you change this: function updatePlayerAttachedElements(lastInt, lastDim, curInt, curDim) outputDebugString ( "Sanity check: "..tostring(source).." - "..tostring(lastInt).." - "..tostring(lastDim).." - "..tostring(curInt).." - "..tostring(curDim) ) local attachedObjects = getElementChildren ( source, "object") outputDebugString( "Number of attached objects: "..tostring(#attachedObjects) ) for _,elem in pairs(attachedObjects) do setElementDimension( elem, curDim ) setElementInterior( elem, curInt ) end end addEventHandler( "onPlayerDimIntChange", root, updatePlayerAttachedElements ) Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now