Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 26/09/21 in Posts

  1. Hello MTA community, for quite a while I have been thinking about the Lua language. I think that we can all agree on this fact: that the Lua language is simple and beautiful, especially inside MTA San Andreas. Would any of you be interested in a service that lets you compile Lua directly into machine code, for example into a stand-alone PE executable file? I am not talking about srlua or LuaJIT, rather a completely new application/web service where you could queue your Lua code for compilation. There are major benefits to compiling to machine code rather than Lua bytecode. When I'd finish this project then I would implement a C++ interface and port it into MTA aswell. Benefits of machine code translation Speed boosts during script execution due to native format of the code Code cannot be reversed into Lua anymore Lua code optimizations that the reference Lua compiler does not perform (constant optimizations, function inlining, computation node grouping, loop unrolling, etc) The ability to market your programs I am thinking about a future business partnership with the MTA team where electronically-signed machine code translated from Lua would be securely run on MTA clients. The modernization of the Lua component would bring more freedom in designing the future scripting possibilities too. If you guys voice enough interest for this product then I would be greatly encouraged to create it. There is no such product available yet and it's creation would be both interesting and challenging. What do you think, community member? - Martin
    1 point
  2. @f15 الرجاء عدم إنشاء مواضيع متكررة بنفس الموضوع إذا كنت تحتاج تعدل شي في موضوعك يوجد زر Edit أو يمكنك إنشاء بلاغ على موضوعك وذكر التعديل الذي تريده
    1 point
  3. You're welcome. A big problem in your model is that you link the movement-speed of the spoiler to game FPS. This results in different speeds depending on computer performance. I recommend you to use getTickCount to get elapsed time in milliseconds and then divide it by 1000 to get the elapsed seconds. Then multiply it by a base-velocity to get the distance it should travel per second. Then change the mathematics accordingly inside spoiler_move clientside.lua .
    1 point
  4. Oh, excuse me for misunderstanding. You did not give accurate enough specification of which spoiler should move and whether there was only one vehicle on the server with the spoiler. Here is a better version. I cannot test it because you missed out on giving us your vehicle model. Please tell me if it works for you. ? clientside.lua local spoiler_status = {}; local function getVehicleSpoilerStatus(veh) local status = spoiler_status[veh]; if (status) then return status; end; status = {}; status.move_dir = false; spoiler_status[veh] = status; return status; end addEventHandler("onClientElementDestroy", root, function() if (getElementType(source) == "vehicle") then spoiler_status[source] = nil; end end ); addEvent("onClientSpoilerInformation", true); addEventHandler("onClientSpoilerInformation", root, function(desc) local info = getVehicleSpoilerStatus(source); --outputDebugString("received spoiler information"); info.move_dir = desc.move_dir; info.sX = desc.sX; info.sY = desc.sY; info.sZ = desc.sZ; end ); function spoiler_move() local vehicles = getElementsByType("vehicle"); for _,vehicle in ipairs(vehicles) do local status = getVehicleSpoilerStatus(vehicle) if status.move_dir == 1 then if status.sZ and status.sZ < 1.2 then status.sX = status.sX + 0; status.sY = status.sY - 0.006; status.sZ = status.sZ + 0.005; end --dxDrawRectangle(300, 300, 100, 100, tocolor(255, 0, 0, 255)); elseif status.move_dir == 0 then if status.sZ and status.sZ > 1 then status.sX = status.sX + 0; status.sY = status.sY + 0.012; status.sZ = status.sZ - 0.01; end --dxDrawRectangle(300, 300, 100, 100, tocolor(0, 255, 0, 255)); end if (status.sX) then -- Only works if vehicle is streamed in, but we keep a copy of the component position just in case. setVehicleComponentPosition(vehicle, "movspoiler_23.5_1800", status.sX, status.sY, status.sZ) end end end addEventHandler("onClientRender", root, spoiler_move) -- Cached network table. local net_desc = {}; local function synchronizeSpoilerStatus(veh, info) -- Transmit over the network. net_desc.move_dir = info.move_dir; net_desc.sX = info.sX; net_desc.sY = info.sY; net_desc.sZ = info.sZ; triggerServerEvent("onSpoilerInformation", veh, net_desc); end local function spoiler_control(key, state) local veh = getPedOccupiedVehicle(localPlayer); if (veh) and (getVehicleOccupant(veh, 0) == localPlayer) then local info = getVehicleSpoilerStatus(veh); if not (info.sX) then local sX, sY, sZ = getVehicleComponentPosition(veh, "movspoiler_23.5_1800"); if (sX) then info.sX, info.sY, info.sZ = sX, sY, sZ; end end if (key == "u") and not (info.move_dir == 0) then if (state == "down") then info.move_dir = 1; else info.move_dir = false; end elseif (key == "z") and not (info.move_dir == 1) then if (state == "down") then info.move_dir = 0; else info.move_dir = false; end end synchronizeSpoilerStatus(veh, info); end end bindKey("u", "both", spoiler_control); bindKey("z", "both", spoiler_control); addEventHandler("onClientVehicleExit", root, function(ped, seat) if not (seat == 0) then return; end; local info = getVehicleSpoilerStatus(source); info.move_dir = false; if (ped == localPlayer) then synchronizeSpoilerStatus(source, info); end end ); addEventHandler("onClientResourceStart", resourceRoot, function() triggerServerEvent("onPlayerReady_Spoiler", root); end ); serverside.lua -- TODO: add proper security to this script. local spoiler_status = {}; local ready_players = {}; local function sendSpoilerInformation(player, veh, desc) triggerClientEvent("onClientSpoilerInformation", veh, desc); end addEvent("onSpoilerInformation", true); addEventHandler("onSpoilerInformation", root, function(desc) spoiler_status[source] = desc; for m,n in pairs(ready_players) do if not (n == client) then sendSpoilerInformation(n, source, desc); end end end ); addEvent("onPlayerReady_Spoiler", true); addEventHandler("onPlayerReady_Spoiler", root, function() for veh,desc in pairs(spoiler_status) do sendSpoilerInformation(client, veh, desc); end ready_players[client] = true; end ); addEventHandler("onPlayerQuit", root, function() ready_players[source] = nil; end ); addEventHandler("onElementDestroy", root, function() if (getElementType(source) == "vehicle") then spoiler_status[source] = nil; end end ); Use the "u" and "z" keys to control spoiler movement.
    1 point
  5. # السسلام عليكم ورحمة الله وبركاته ~ فـ بهذي الداتا تقدر تسوي اي شي تبيه Element data set / get حبيت اشرح عن الـ * واشياء تتعلق بها نبدأ بـ الشرح .... : # اول شي نتعرف على السينتكس حق الداتا Syntax bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] ) var getElementData ( element theElement, string key [, inherit = true] ) توضضيح بسيط للارقمنات ... : element theElement = الألمنت اللي تبي تحط عليه الداتا string key = اسم الداتا .. وبأمكانك وضع اي اسم var value = وهي قيمة الداتا نفسها .. وبامكانك تحط قيمة الداتا اي قيمة بـ راسك او قيمة فعلية كـ انك تحط قيمة الداتا اسم اللاعب ولا اللاعب نفسه وتجيب اللاعب عبر الداتا # طيب الحين نتعرف على الداتا وش فاديتها فـ وش تسخدم # الدأتا : هي وظيفة لمساعدتك للتحقق من شرط ما وتسوي كودك + الداتا هي وهمية يعني مجرد ما اللاعب بخرج او يدخل فـ الداتا بتروح والداتا مهمة تفديك فـ اي شي تبغاه local vehicle = createVehicle ( id, x, y, z ) ---# قمنا بـ صنع سيارة جديدة setElementData( vehicle, "Anything", true ) ---# وضعنا الداتا على السيارة وقيمة الداتا ترو addCommandHandler( "GetDataVeh", function ( ) ---# امر جديد بـ الكونسل if ( isElement( vehicle ) ) then ---# نتحقق من وجود السيارة if not ( getElementData ( vehicle, "Anything" ) == true ) then ---# وهذي تعني عكس الشرط اللي مسويه يعني هنا يقول الشرط لو ما كانت الداتا ترو not نلاحظ وجود اول الشرط outputChatBox( "** Data Not Found" ) ---# لو كانت مو ترو يجي لم يتم ايجاد الداتا else ---- لو كانت الداتا قيمتها ترو . outputChatBox( "** Data Found" ) ---# يجي بالشات الداتا موجودة . end end end ) marker = createMarker ( .... ) addEventHandler ( "onMarkerHit", marker, function ( element ) if getElementType ( element ) == 'player' then -- نتحقق إن الشي إللي دخل الماركر الي هو لاعب if getElementData ( element, "ZA7F" ) == "MTA" then --- MTA اذا كانت قيمتها ZA7F نتحقق هنا من الداتا الي هي outputChatBox ( "لقد قمت بالدخول مسبقاً", element ) return else --- # MTA هنا نسوي لو مو مسوين الداتا الي ما ماخذاة قمية setElementData ( element, "ZA7F", "MTA" ) --- # عشان ما يستخدم الماركر مرة ثانية MTA هنا نسوي الداتا قيمتها givePlayerMoney ( element, 100 ) -- نعطي اللاعب 100 end end end ) مثألين بسيطين للتوضيح اكثر مع الشرحح ... : addEventHandler ( "onClientMarkerHit", marker, function( element ) --- حدث دخول الالمنت للماركر if ( element == localPlayer ) then --- نتحقق من الشي اللي دخل هل هو لاعب setElementData ( element, "NamePlayer", getPlayerName( element ) ) --- نحط داتا للالمنت اللي دخلت قيمتها اسم اللاعب end end ) addEventHandler ( "onClientMarkerLeave", marker, function( element ) --- حدث الخروج من الماركر if ( element == localPlayer ) then --- نتحقق من الشي اللي خرج . if ( getElementData( element, "NamePlayer" ) == getPlayerName( element ) ) then --- نتحقق انه قيمة الداتا اللي على اللاعب اللي خرج انها ع اسمه setElementData ( element, "NamePlayer", nil ) --- لا شي , بدون قيمة ذذ nil نحط قيمة الداتا للاعب اللي خرج end end end ) .... true - false طبعأ ملأحظين انه بـ اخر مثالين قيمة الداتا هي اسم اللاعب .. يعني مو ضروري تكون قيمة الداتا . ممكن تكون قيمةة الداتا هي اللاعب نفسه .. فـ بامكانك انك تجيب اللاعب من الداتا _ يعني تقدر تحط قيمة الداتا اي شي تبيه وفي شي مهم حبيت اوضحه .. انه يمديكـ تحفظ اكثر من قيمة بالداتا كيف ؟ بالتيبل يكون قيمة الداتا تيبل مثال بسيط ... : addCommandHandler ( "getPosToData", function ( ) --- # اضافة امر جديد للكونسل if ( getElementData ( localPlayer, "TablePos" ) ) then --- # التحقق من وجود الداتا return outputChatBox ( "Your Position In Data"..unpack ( getElementData ( localPlayer, "TablePos" ) ) ) --- # لو موجودة نسوي مخرج شات ونجيب الاحداثيات --- # طبعا استخدام ان باكـ .. وظيفتها تجيب القيم كلها بالترتيب من الجدول وقيمة الداتا ذي جدول else --- # لو كانت الداتا موب موجودة local x, y, z = getElementPosition ( localPlayer ) --- # جلبنا احداثيات اللاعب setElementData ( localPlayer, "TablePos", { x, y, z } ) --- # سوينا المنت داتا للاعب قيمتها جدول والجدول به احداثيات اللاعب end --- # اغلأق if end ) --- # اغلا الفنكشن واغلاق قوس الحدث موب ضروري استخدم ان باكـ .. بامكانك تسوي لوب بس ملاحظة مهمة وهذا ايضضضا .. : CPU فـ استخدم الداتا ياخذ من الـ .. لا تستخدمها الا للضرورة . ووظيفته بسيطة جدا انه وقت الداتا تتغير onElementDataChange : طبعأ مع الداتا يوجود حدث خاص بها وهو Parameters string theName, var theOldValue نلاحظ انه في عندنا 2 بارتمنت .. الاول هو اسم الداتا اللي تغير _ والثاني قيمة الداتا القديمةة مع هذأ الحدث لجلب القيمة الجديدة للداتا getElementData البعض يسال انه طيب والقيمة الجديدة للداتا ؟ .. تقوم بأستخدام Global parameters source: The source of this event is the element whose element data changed client: The client global variable is set to the client that called setElementData, or nil if it was called on the server. sourceResource: The resource which changed the element data. (Only works in versions above 1.3.4-5937) .. هذي الكتأبات مهمة جدأ .. نشرحها سطر سطر > اول سطر يقول سورس هذا الافنت وش هو ؟ هو الالمنت اللي الداتا عليه وتغيرت _ ممكن يكون لاعب - سيارة الخ : وهذا ليس خاص بـ الحدث هو موجود بـ اي مكان بس له وظيفة بـ لو تستخدمه بـ هذا الحدث وظيفة مختلفة وهي client السطر الثاني وهو ما يسمى بـ لو تقوم بأستخدامه تجيب اللاعب اللي غير الداتا .. او الجهة اللي غيرت الداتا ذذ Only works in versions above 1.3.4-5937 السطر الثالث بسيط جدأ .. هو عبارة عن السكربت اللي فيه الداتا هذي اللي تغيرت > نلاحظ حاط بين قوسين يعني هذي الخاصية تعمل على اصدار 5937-1.3.4 وما فوق Cancelling This event cannot be cancelled using cancelEvent. To reverse the effect, use setElementData with the old value. setElementData بس تقدر تكنسله بـ طريقة مختلفة بـ استخدام cancelEvent وش يقول هنا ؟ .. هنا يقول ما تقدر تكنسل الحدث بـ استخدم مثال بسيط للفهم اكثر .. : addEventHandler( "onElementDataChange", root, function( dataName, OldValue ) ----# اضافة حدث تغير الداتا مع تعريف البارتمنت الاثنين if ( dataName == "Anything" ) then ----# Anything نتحقق من اسم الداتا اللي تغيرت هل هي if ( source and getElementType( source ) == "vehicle" ) then ----# نتحقق من السورس وانه نوع السورس سيارة setElementData( source, dataName, oldValue ) ----# قمنا بوضع قيمة الداتا اللي تغيرت بـ القيمة القديمة يعني ما تغيرت end end end ) متعلق بالمثال اللي بأول الشرح onElementDataChange طبعا نسوي مثال بسيط عن addEventHandler( "onElementDataChange", root, function( dataName, OldValue ) ----# اضافة حدث تغير الداتا مع تعريف البارتمنت الاثنين if ( dataName == "Anything" ) then ----# Anything نتحقق من اسم الداتا اللي تغيرت هل هي if ( source and getElementType( source ) == "vehicle" ) then ----# نتحقق من السورس وانه نوع السورس سيارة local Nv = getElementData( source, dataName ) ----# قمنا بجلب قيمة الداتا الجديدة outputChatBox( data.." ** Has Been Change From "..OldValue.." To "..Nv, root, 255, 0, 0, true ) ----# نقوم بـ اضهار رسالة للكل ب اسسم الداتا والقيمة القديمة والجديدة end end end ) وظيفته ازالة الداتا عن الالمنت : removeElementData طبعا بعد ما انتهينا من الحدث هذا .. في اخر شي فنكشن يتعلق بـ الداتا وهو bool removeElementData ( element theElement, string key ) element theElement, string key = الالمنت اللي بتشيل منه الداتا , اسم الداتا ممثال بسيط .. : addCommandHandler( "RemoveMyData", function( player,_,data ) ---- # اضافة امرة للكونسل وتعريف البلير ونسوي فراغ بين الامر والداتا اللي يكتب اسمها if ( data ) then ---- # نتحقق من كتابته لاسم الداتا if ( getElementData( player, tostring( data ) ) ) then ---- # نتحقق من وجود الداتا على اللاعب اللي كتب الامر if ( getElementData( player, tostring( data ) ) ~= nil ) then ---- # او ما لها وجود او تعني لأ شي nil نتحقق انه الداتا قيمتها مو removeElementData( player, tostring( data ) ) ---- # نسوي ازالة للداتا اللي كتبها end end end end ) معلومة مهمة : اخر حد للاحرف 31 حرف للمفتاح # # واخر شي اقول انه الداتا سهلة جدا .. ومفيدة بـ اشياء كثيرة واكيد بـ تحتاجها يومأ ما . والسسلأم
    1 point
×
×
  • Create New...