Jump to content

Citizen

Moderators
  • Posts

    1,803
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Citizen

  1. Alright, after severals hours, I managed to do this (game resolution: 1024x768, used my own images): MP4 (HQ) Maybe we can improve it using vectors I don't know but I'm not confortable with them. Here is the client code (the hard part is done. I left the debug drawings but you can remove everything that has the "-- debug" comment) junkyards = { -- x, y, z, width, length, height, {2164.6706542969, -1504.7607421875, 23.984375, 10, 10, 2} } items = { -- item id, chance (%), amount {13, 20, 1}, -- cigar {25, 60, 1}, -- rope {67, 40, 1}, -- lighter {68, 5, 100}, -- graffiti patron } local sx, sy = guiGetScreenSize() local junkSize = sx/2 local junkImageDistance = 50 local junkPositionX, junkPositionY = sx/2-junkSize/2, sy/2-junkSize/2 local junks = {} -- holds all junks images with position, rotation etc local board = {x = junkPositionX, y = junkPositionY, width = junkSize, height = junkSize} local mouseRadius = 20 -- how big the mouse's hitbox is (higher = easier to move junks) local repulseSpeed = 12 -- how fast the junks go away from mouse's hitbox local junkyardCollision = nil local searchTime = 1000 local searchTimeMultiplier = 1 local minimumSearchTimeMultiplier, maximumSearchTimeMultiplier = 5, 15 function createJunkyards() for k,v in ipairs(junkyards) do junkyardCollision = createColCuboid(v[1], v[2], v[3]-0.85, v[4], v[5], v[6]) end end addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), createJunkyards) local junkImages = { -- image, size, hitradius {"burgershot-bag", 128, 50}, {"cup", 128, 50}, {"boot", 256, 100}, {"bin-bag", 256, 100}, {"apple", 128, 50}, {"paper", 128, 50}, {"bottle", 128, 50}, {"glass", 128, 50}, {"tin-can", 128, 50} } function createJunks() junks = {} for k, v in ipairs(junkImages) do local size = v[2] local rot = math.random(1,360) local midX, midY = getRandomPointInCircle(board.x+board.width/2, board.y+board.width/2, board.width/4) local x, y = midX - size/2, midY - size/2 -- we want the middle of the image to be placed at that point table.insert(junks, {x = x, y = y, size = size, img = v[1], rot = rot, hitradius = v[3]}) end end showCursor(true) -- debug (add it to your command that shows the junk) bindKey("f5", "down", createJunks) -- debug (F5 to (re)create the junk) function renderJunk() dxDrawRectangle(board.x, board.y, board.width, board.height, tocolor(200, 0, 0, 255)) -- debug (junk board) dxDrawCircle(board.x+board.width/2, board.y+board.width/2, board.width/4, 1, 1, 0, 360, tocolor(0, 0, 0, 255)) -- debug (spawn area - black circle) for k, j in ipairs(junks) do local cx, cy = getCursorPosition() cx, cy = cx * sx, cy * sy -- absolute cursor position local imgCenterX, imgCenterY = j.x+j.size/2, j.y+j.size/2 -- center of the junk's image dxDrawImage(j.x, j.y, j.size, j.size, "junkyard/files/" ..j.img..".png", j.rot, 0, 0, tocolor(255,255,255,255), false) dxDrawCircle(imgCenterX, imgCenterY, j.hitradius, 1, 1, 0, 360, tocolor(0, 0, 200, 255)) -- debug (junk's hitbox - blue circle) dxDrawCircle(cx, cy, mouseRadius, 1, 1, 0, 360, tocolor(255, 255, 0, 255)) -- debug (mouse's hitbox) if getKeyState("mouse1") and isCircleInCircle(imgCenterX, imgCenterY, j.hitradius, cx, cy, mouseRadius) then -- move it away if it collides with the cursor's hitbox local angle = findRotation(imgCenterX, imgCenterY, cx, cy) local newX, newY = getPointFromDistanceRotation(imgCenterX, imgCenterY, repulseSpeed, -angle + 180) local offsetX, offsetY = imgCenterX - newX, imgCenterY - newY j.x, j.y = j.x-offsetX, j.y-offsetY -- debug: local newX, newY = getPointFromDistanceRotation(imgCenterX, imgCenterY, 200, -angle + 180) -- debug dxDrawLine(imgCenterX, imgCenterY, newX, newY, tocolor(0, 200, 0, 255)) -- debug (shows direction where the junk is going - green line) end end end addEventHandler("onClientRender", getRootElement(), renderJunk) function startSearching() if junkyardCollision and isElement(junkyardCollision) then if isElementWithinColShape(localPlayer, junkyardCollision) then searchTimeMultiplier = math.random(minimumSearchTimeMultiplier,maximumSearchTimeMultiplier) local finalSearchTime = searchTime*searchTimeMultiplier triggerServerEvent("syncSearchingFromServer", localPlayer, localPlayer, finalSearchTime) setTimer(function() triggerServerEvent("giveFoundJunkItem", localPlayer, localPlayer) end,finalSearchTime,1) else exports["cg_notifications"]:addNotification("Ezt a parancsot csak szeméttelepen tudod használni!", "error") end end end addCommandHandler("turkal", startSearching) ----------------------------------------------------- -- From https://wiki.multitheftauto.com/wiki/DxDrawCircle (was only used for debug drawings) function dxDrawCircle( posX, posY, radius, width, angleAmount, startAngle, stopAngle, color, postGUI ) if ( type( posX ) ~= "number" ) or ( type( posY ) ~= "number" ) then return false end local function clamp( val, lower, upper ) if ( lower > upper ) then lower, upper = upper, lower end return math.max( lower, math.min( upper, val ) ) end radius = type( radius ) == "number" and radius or 50 width = type( width ) == "number" and width or 5 angleAmount = type( angleAmount ) == "number" and angleAmount or 1 startAngle = clamp( type( startAngle ) == "number" and startAngle or 0, 0, 360 ) stopAngle = clamp( type( stopAngle ) == "number" and stopAngle or 360, 0, 360 ) color = color or tocolor( 255, 255, 255, 200 ) postGUI = type( postGUI ) == "boolean" and postGUI or false if ( stopAngle < startAngle ) then local tempAngle = stopAngle stopAngle = startAngle startAngle = tempAngle end for i = startAngle, stopAngle, angleAmount do local startX = math.cos( math.rad( i ) ) * ( radius - width ) local startY = math.sin( math.rad( i ) ) * ( radius - width ) local endX = math.cos( math.rad( i ) ) * ( radius + width ) local endY = math.sin( math.rad( i ) ) * ( radius + width ) dxDrawLine( startX + posX, startY + posY, endX + posX, endY + posY, color, width, postGUI ) end return true end -- From http://cgp.wikidot.com/circle-to-circle-collision-detection function isCircleInCircle(x1, y1, r1, x2, y2, r2) return math.sqrt( ( x2-x1 ) * ( x2-x1 ) + ( y2-y1 ) * ( y2-y1 ) ) < ( r1 + r2 ) end -- From https://wiki.multitheftauto.com/wiki/FindRotation function findRotation( x1, y1, x2, y2 ) local t = -math.deg( math.atan2( x2 - x1, y2 - y1 ) ) return t < 0 and t + 360 or t end -- From https://wiki.multitheftauto.com/wiki/GetPointFromDistanceRotation function getPointFromDistanceRotation(x, y, dist, angle) local a = math.rad(90 - angle); local dx = math.cos(a) * dist; local dy = math.sin(a) * dist; return x+dx, y+dy; end -- From https://gamedev.stackexchange.com/questions/26713/calculate-random-points-pixel-within-a-circle-image/26714 function getRandomPointInCircle(x, y, radius) local angle = math.random() * math.pi * 2 radius = math.random() * radius local x = x + radius * math.cos(angle) local y = y + radius * math.sin(angle) return x, y end How to use: Start the script and then press F5 to test it. Press the left mouse button and start moving the junks away. Then press F5 again to reset the junks positions. You might want to modify the hitradius/hitbox for each junk image for a better interaction with the junks. You might also want to modify the mouseRadius and the repulseSpeed (see comments for what they are meant for). This is a pretty complex script and I don't have time to add more comments in the code for tonight, but feel free to ask what you do not understand and I'll try my best to explain it.
  2. My first guess would be to use source instead of getLocalPlayer() at line 6 and 7 from the client side: local che = getPedOccupiedVehicle(source) x,y,z = getElementPosition(source) Also you probably want to bind the minigun_front_stop function for when you release the mouse1 key: bindKey(source,'mouse1','down',minigun_front) bindKey(source,'mouse1','up',minigun_front_stop) -- changed 'down' for 'up' You also forgot to take this note into consideration: You need to fix that for both miniguns: setWeaponProperty(weapa, "fire_rotation", 0, -30, 0) setWeaponProperty(weapb, "fire_rotation", 0, -30, 0)
  3. The code for admins should have been INSIDE the "if" statement that checks for admin ACL group: function giveblood (thePlayer) local account = getAccountName ( getPlayerAccount ( thePlayer ) ) if isObjectInACLGroup("user." .. account, aclGetGroup("Admin")) then outputChatBox ("#6B8E23 [Owner] #FFFFFF"..getPlayerName(thePlayer).."#1AFF00 Is now onduty NO DM !",root,255,255,255,true) setElementData(thePlayer, "blood", 999999999) end end addCommandHandler("duty", giveblood) function bloodback(thePlayer) local account = getAccountName ( getPlayerAccount ( thePlayer ) ) if isObjectInACLGroup("user." .. account, aclGetGroup("Admin")) then outputChatBox ("#6B8E23 [Owner] #FFFFFF"..getPlayerName(thePlayer).."#FF0000 Is now offduty",root,255,255,255,true) setElementData(thePlayer, "blood", 12000) end end addCommandHandler("offduty", bloodback)
  4. From: https://forum.multitheftauto.com/topic/33519-helphow-to-make-an-movement-gate/?do=findComment&comment=843650 You will need : createObject to create the gate createMarker to create the 2 markers you will need onMarkerHit attached to the created markers (make sure to ignore the "vehicle" hitElement type to prevent triggering it twice if in vehicle) moveObject to open/close the gate setElementData / getElementData on the gate to save and toggle the state of the gate (if it's open or closed)
  5. You will need : createObject to create the gate createMarker to create the 2 markers you will need onMarkerHit attached to the created markers (make sure to ignore the "vehicle" hitElement type to prevent triggering it twice if in vehicle) moveObject to open/close the gate setElementData / getElementData on the gate to save and toggle the state of the gate (if it's open or closed)
  6. Yes exactly. Actually, no. We call this operator a "modulo" which is the remainder of a "Division euclidienne" as you said. You mixed "/" with "%"
  7. Do you have any errors ? (command: /debugscript 3) If not, make sure you have set the chatbubbles.DefaultTime and chatbubbles.PerCharacterAddition settings in meta.xml to a reasonable amount of time (I mean, don't put a huge number). The values are in milliseconds. local showtime = tonumber(get("chatbubbles.DefaultTime")) local characteraddition = tonumber(get("chatbubbles.PerCharacterAddition")) The time for a bubble to stay on screen will be: showtime + (number of letters in the message * characteraddition). So if you set chatbubbles.DefaultTime to 1000 and chatbubbles.PerCharacterAddition to 100 then a message of 15 letters (spaces included) will last on screen for: 1000 + (15 * 100) = 1000 + 1500 = 2500 ms (2,5 secs).
  8. Pas sûr mais peut être Fox Roleplay (fermé) ? Je connais pas leurs stats mais peut être que @Nico62 voudra répondre ? Quelqu'un l'avait proposé y a 3 ans, ça ne s'est jamais fait. Joueurs => certainement ! Développeurs => ça m'étonnerait qu'il y en ait avec suffisamment de temps libre pour faire un serveur RP "from scratch". Je suis totalement d'accord avec tout le reste de ton poste, le projet m'intéresse énormément mais je sais que je n'aurai pas le temps libre nécessaire à la réalisation d'un tel projet. Etant donné que j'ai déjà démarré un projet sur MTA (pas du tout de gamemode, juste une sorte d'outil qui, j'en suis sûr, sera utilisé par la majorité des serveurs MTA). Néanmoins je pourrai participer à la mise en place de la structure de base et délibérer avec les autres devs sur les conventions à utiliser pour ne pas avoir un code source qui part dans tous les sens selon la façon de coder de chacun. Une TODO liste sera indispensable (Trello ?) pour visualiser l'avancement du projet par rapport à un objectif "V1" pour commencer. Je reste dans tous les cas dans les parages sur ce forum pour toute question technique etc. Cordialement, Citizen
  9. Once you have set the element data, you can get it back by using getElementData if clientSyrenaState == 1 then local syrena = playSound3D ( "shrtvaw.ogg" , x, y, z, true ) setElementData(playerOccupiedRadiolka,"radiolka:syrenaClientSyrena",syrena) -- set the element data for syrena attachElements(syrena,playerOccupiedRadiolka) elseif clientSyrenaState == 2 then local syrena = getElementData(playerOccupiedRadiolka,"radiolka:syrenaClientSyrena") -- get the element data for syrena destroyElement(syrena) triggerServerEvent( "usunDateBoPoChujOna" ,localPlayer) syrena = playSound3D ( "lngvaw.ogg" , x, y, z, true ) setElementData(playerOccupiedRadiolka,"radiolka:syrenaClientSyrena",syrena) -- set the element data for syrena attachElements ( syrena, playerOccupiedRadiolka ) elseif clientSyrenaState == 0 then local syrena = getElementData(playerOccupiedRadiolka,"radiolka:syrenaClientSyrena") -- get the element data for syrena destroyElement(syrena) triggerServerEvent( "usunDateBoPoChujOna" ,localPlayer) end
  10. By doing this: scx,scy = guiGetScreenSize() px = scx/1920 You are calculating a ratio for the X axis on the screen for the current resolution. That ratio has to be used to convert a value that is good for a 1920px wide resolution (for example width: 256px) into a value that will be good for another resolution. The ratio on the X axis you calculated will only be good for values on that X axis (so only for posX and width arguments of the dxDrawImage function). As you don't have the same amount of pixels on the Y axis than on the X axis, you have to calculate another ratio but for that Y axis too. And then use that ratio to convert the posY and height arguments that are good for a 1080px tall resolution: scx,scy = guiGetScreenSize() px = scx/1920 -- ratio X py = scy/1080 -- ratio Y function draw() dxDrawImage(300*px,300*py,256*px,256*py,"image.png") end Also, even with that fix, you might still experience some blur according to the wiki page: (We are talking here about the image source file, not the width and height arguments of that function.) So if you still see some small blurs (on the text especially), try to edit your image.png to apply that best practice.
  11. You wanted to use setElementModel instead of setElementData : addEventHandler ( "onElementModelChange", root, function ( oldModel, newModel ) local account = getPlayerAccount ( source ) local accountName = getAccountName ( account ) if ( newModel == 60 and not isObjectInACLGroup ( "user.".. accountName, aclGetGroup ( "Admin" ) ) ) then outputChatBox ( "Bocsi, de ez admin skin. Te nem használhatod! :(", source, r, g, b ) setElementModel ( source, oldModel ) end end )
  12. Citizen

    Sort table

    What do you mean by that ? Can you give us a sample of what you get and an example of what you want to get ?
  13. Je ne saurai pas te dire pour être honnête. Je ne sais pas ce qu'on est capable de faire avec GTA Network, ça m'étonnerait que ça soit des serveurs sur lesquels on peut scripter si ?! C'est pas que des gamemodes que tu mets à dispo sur le network et que du coup c'est juste un mode avec ton nom dessus, sans possibilité de connaître/voir/rencontrer les joueurs de ton mode ?
  14. Attention ! Je n'ai jamais dit qu'il n'y avait pas ou peu de joueur FR, y en a beaucoup je pense mais ça reste de "simple" joueurs si je peux me permettre ce terme et ils ne viennent pas sur ce forum et encore moins sur notre section FR. De plus tu veux faire Français + Anglais, donc même si finalement y a pas autant de français sur MTA que je pense, il te reste encore tous les joueurs anglais ou parlant anglais qui vont trouver ton gamemode cool si bien réalisé. Et si en plus tu gères bien ton système d'internationalisation, avec un fichier de traduction séparé tu peux demander à la communauté MTA de t'aider à traduire dans différentes langues. Tu fournis le fichier de langue, un allemand qui veut bien t'aider télécharge ton fichier, traduit tous les mots et phrases de ton fichier et te le renvoie sur un mail précis ou par MP. Je trouve quand même bizarre d'évaluer la viabilité d'un projet multi-langue en ce basant seulement sur l'activité d'un sous-forum français. En général ceux qui traînent sur ce forum ce sont des devs. A toi de voir de toute façon
  15. Quasiment oui, elle n'a jamais été vraiment vivante non plus dans cette section du forum. Le problème c'est que je sais qu'il y a un certains nombre de français mais ils préfèrent poster dans la section Scritping malheureusement.
  16. Try this (using an element data so it's the vehicle who is in charge to keep a reference to wuwuni instead of a server variable): if policeSigState == 0 then local wuwuni = createObject ( 1845, x , y , z , xr , yr, zr ) setElementData ( playerOccupiedRadiolka ,"radiolka:signalsstate",1) setElementData ( playerOccupiedRadiolka ,"radiolka:signalsobject", wuwuni ) attachElements ( wuwuni , playerOccupiedRadiolka, -0.5 , -0.05 , 0.9 ) elseif policeSigState == 1 then setElementData ( playerOccupiedRadiolka ,"radiolka:signalsstate",0) local wuwni = getElementData ( playerOccupiedRadiolka , "radiolka:signalsobject" ) if wuwni and isElement( wuwni ) then destroyElement ( wuwuni ) end end if policeSigState == 0 then local wuwuni = createObject ( 1845, x , y , z , xr , yr, zr ) setElementData ( playerOccupiedRadiolka ,"radiolka:signalsstate",1) setElementData ( playerOccupiedRadiolka ,"radiolka:signalsobject", wuwuni ) attachElements ( wuwuni , playerOccupiedRadiolka, -0.5 , -0.05 , 0.9 ) elseif policeSigState == 1 then setElementData ( playerOccupiedRadiolka ,"radiolka:signalsstate",0) local wuwni = getElementData ( playerOccupiedRadiolka , "radiolka:signalsobject" ) if wuwni and isElement( wuwni ) then destroyElement ( wuwuni ) end end
  17. By giving a quick look at the source code, I can tell you that setElementData won't send your data through the network even if you set the synchronize parameter to true (line 6) bool CStaticFunctionDefinitions::SetElementData ( CClientEntity& Entity, const char* szName, CLuaArgument& Variable, bool bSynchronize ) { CLuaArgument * pCurrentVariable = Entity.GetCustomData ( szName, false ); if ( !pCurrentVariable || Variable != *pCurrentVariable ) { if ( bSynchronize && !Entity.IsLocalEntity () ) { // Allocate a bitstream NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream (); if ( pBitStream ) { // Send data to sync it with the server [code redacted to keep it short] // Set its custom data Entity.SetCustomData ( szName, Variable ); return true; } } else { // Set its custom data Entity.SetCustomData ( szName, Variable ); return true; } } return false; } Source
  18. What's the purpose of TbPlEmp[hitElement]["marker"] and how do you create it ?
  19. My kinda out of date fork of MTA FairPlay before the shutdown: https://github.com/Citizen01/Lua-mta-fairplay
  20. My kinda out of date fork before the shutdown: https://github.com/Citizen01/lua-mta-fairplay
  21. Downloading scripts from others is a good way to learn MTA scripting by concrete examples but as you should limit yourself to only publicly released scripts/gamemodes you can learn some bad practices. Inspecting how the default resources work is a really good way to learn how to code from simple scripts to more advanced ones. If you are more into RP gamemodes you can check those gamemodes out: MTA Paradise from Mabako: https://github.com/mabako/mta-paradise MTA Fairplay from SocialZ (this is my fork before it got removed): https://github.com/Citizen01/lua-mta-fairplay
  22. Or maybe he is just talking about the freeroam resource ? Check your facts before going into steal accusations Also, as I doubt you are part of the owlgaming dev group, how do you know there is that file in their gamemode ?
  23. Just replace the lines 106 to 123 by this: function onLevelUp(newLevel) outputChatBox("You just leveled up to level "..tostring(newLevel).." !") -- Add code to give items here end function mainRanks() if getElementData(localPlayer, "logedin") == true then if getElementData(localPlayer, "experience") > getPlayerRankExperience() then if getElementData(localPlayer, "level") < 70 then local newLevel = getElementData(localPlayer, "level") + 1 setElementData(localPlayer, "level", newLevel) onLevelUp(newLevel) end end dxDrawImage ( sW/22, sH/2.8, sW/60, sH/60, "images/level/rank"..getElementData(localPlayer, "level")..".jpg" ) dxDrawText ( getPlayerRankName().." ("..getElementData(localPlayer, "level")..")",sW/65, sH/3.6, sW/0, sH/0, tocolor ( 240, 230, 140, 255 ), 1.02, "default-bold" ) dxDrawText ( "Experiência atual: "..getElementData(localPlayer, "experience"), sW/65, sH/3.27, sW/0, sH/0, tocolor ( 70, 130, 180, 255 ), 1.02, "default-bold" ) if getElementData(localPlayer, "level") < 70 then dxDrawText ( "Experiencia necessario: "..getPlayerRankExperience(),sW/65, sH/3, sW/0, sH/0, tocolor ( 70, 130, 180, 255 ), 1.02, "default-bold" ) else dxDrawText ( "O máximo foi alcançado",sW/65, sH/3, sW/0, sH/0, tocolor ( 70, 130, 180, 255 ), 1.02, "default-bold" ) end end end addEventHandler ( "onClientRender", root, mainRanks ) And modify the onLevelUp function to your needs.
  24. Alright, read it too fast, sorry for that.
×
×
  • Create New...