-
Posts
822 -
Joined
-
Last visited
-
Days Won
86
Everything posted by The_GTA
-
I recommend using the scene2res tool to convert IPL/IDE maps into MTA .map format: https://osdn.net/projects/scene2res/ Since I am the creator of that tool you can ask any questions about it in this thread. The tool will create a resource for you inside of the "output" folder. You can rename the folder into "my_map", paste it into the server resources folder and type "start my_map" into the server console. I would be very grateful if you could rate my tool on OSDN.net
-
Thank you for this very nice compliment, redditing! ^^ I just happen to have a lot of experience with game design and MTA scripting. Remember to ask any questions if you are stuck making the resource. I will be there to help you.
-
To draw the radar on screen you should use: dxDrawRectangle - for outline, style, etc dxDrawImageSection - putting the actual radar on screen with zooming support addEventHandler using the onClientRender event dxCreateRenderTarget and dxSetRenderTarget for drawing map information inside of a rectangle only (scissor rectangle) To prevent the original radar from rendering you should use: setPlayerHUDComponentVisible To query radar center and other relevant information map information you should use: getCamera getElementRotation getElementsByType using "radararea", "blip", "player", etc getElementPosition the radararea functions But I have to inform you that those functions alone will not make you a radar. You need to have a good understanding of how your radar should work, including the math behind it as well as the conventions to integrate it seamlessly into the Rockstar vision (north is into x=0,y=1 direction, etc). For advanced effects you should use: dxDrawImage using shaders Here are neat references for already implemented radars or map scripts: https://forum.multitheftauto.com/topic/122958-getworldfrommapposition/?do=findComment&comment=974403 https://forum.multitheftauto.com/topic/122507-help-dxradar-blip-problem/?tab=comments#comment-972908 https://forum.multitheftauto.com/topic/122303-help-why-this-doesnt-draw/?tab=comments#comment-972209 Since there are many threads on MTA forums about radar-logic that went unanswered feel free to post questions here. Maybe we can get this radar done together
-
No problem. I am happy to hear about your thankfulness
-
Thank you for sharing your resource with us. I admit that I had to get my head around that zooming logic, because it is math that I was quite unfamiliar with, but here is your function: local map_world_units_width = 6000; function getWorldFromMapPosition(mapX, mapY, posx, posy, x, y, w, h, range) local zoomFactor = ( 180 / range ); local render_pixel_side_distance = 3000 * zoomFactor; -- actual size of the map in pixels inside the render-target. local world_render_distance_w = w / render_pixel_side_distance * map_world_units_width; local world_render_distance_h = h / render_pixel_side_distance * map_world_units_width; local world_tl_start_x = ( posx - world_render_distance_w / 2 ); local world_tl_start_y = ( posy + world_render_distance_h / 2 ); local absCursorX = ( mapX * sx ); local absCursorY = ( mapY * sy ); local real_map_off_x = ( absCursorX - x ); local real_map_off_y = ( absCursorY - y ); -- Cursor outside of the map image? if ( real_map_off_x < 0 ) or ( real_map_off_x >= w ) or ( real_map_off_y < 0 ) or ( real_map_off_y >= h ) then return false; end local relative_map_off_x = ( real_map_off_x / w ); local relative_map_off_y = ( real_map_off_y / h ); local worldX = world_tl_start_x + relative_map_off_x * world_render_distance_w; local worldY = world_tl_start_y - relative_map_off_y * world_render_distance_h; return worldX, worldY; end The clue was to calculate the size of the map that you draw inside the render target, then calculate the fraction of the width and height of how much you draw of the actual map image. So if you draw only a third of the map image, then you can expect the render to cover about 2000 game units. Then we can just linearly interpolate the world position with the relative cursor position on the map render. I noticed that your map does not render using same width and height thus I added further adjustments. Have fun with the code!
-
Dear raynner, since I have no map image to test with, no mathematical model of your map rendering other than the code I am just gonna assume some things. 1) your map starts from world coordinate x=-3000,y=-3000 (bottom-left) to x=3000,y=3000 (top-right). 2) mapX, mapY are relative coordinates into the map starting from top-left; posx, posy, x, y, w, h describe absolute coordinates Thus your function should look like this: --[[ mapX = CursorX mapY = CursorY PosX = playerX PosY = playerY x = bigmap render x y = bigmap render y w = bigmap render w h = bigmap render h range = zoom --]] local screenW, screenH = guiGetScreenSize() function getWorldFromMapPosition(mapX, mapY, posx, posy, x, y, w, h, range) local zoomFactor = ( 180 / range ); local render_side_distance = 3000 * zoomFactor; local world_tl_start_x = ( posx - render_side_distance ); local world_tl_start_y = ( posy + render_side_distance ); local absCursorX = ( mapX * screenW ); local absCursorY = ( mapY * screenH ); local real_map_off_x = ( absCursorX - x ); local real_map_off_y = ( absCursorY - y ); -- Cursor outside of the map image? if ( real_map_off_x < 0 ) or ( real_map_off_x >= w ) or ( real_map_off_y < 0 ) or ( real_map_off_y >= h ) then return false; end local relative_map_off_x = ( real_map_off_x / w ); local relative_map_off_y = ( real_map_off_y / h ); local worldX = world_tl_start_x + relative_map_off_x * render_side_distance; local worldY = world_tl_start_y - relative_map_off_y * render_side_distance; return worldX, worldY; end If this function above should not work (I am unable to test without a working resource!), please do not shy away from providing a working resource if you want us to help you further.
-
You don't need metatables for the self keyword. Take a look at this small sample: local police = {} -- Take a look: we use the "self" keyword here! function police:setName(name) self.name = name end function police:getName() return self.name end police:setName("Las Venturas Police Department") outputDebugString("Name of Police HQ: " .. police:getName()) Formal description: if you specify a "method" of a table in Lua, then inside the function body you can access the hidden local variable "self" which points to the table itself. This self variable is the first argument to the function specification of the method. Thus an equivalent way of writing above script is: local police = {} -- Here we explicitly specify the self. function police.setName(self, name) self.name = name end function police.getName(self) return self.name end police:setName("Las Venturas Police Department") outputDebugString("Name of Police HQ: " .. police:getName()) Hope this helps!
-
Dear Mike269, please format your code using the "<>" button so that it is not difficult to read. If the list of skins is known beforehand, then you can create a table with all the skins (29, etc) and use getElementModel to check each player or ped that entered against entries in said table. local safe_ped_skins = { [29] = true -- add more entries here }
-
No, majqq's code is perfect. He wanted to show you how it is done properly, basically what the words inside the parenthesis mean. If you look into the chatbox and compare the output to the script (line 3) you will see that "player" and "cmd" have a different string representation. Just let that sink in. If you get this right then you have possibly solved a big knot in the brain.
-
Because putting 'p' at the right spot into the parantheses of the command-handlers is the only way to request the player that executed said command handler. If you don't specify the p then you tell Lua that you don't care about p and then you cannot possibly expect p to be defined in any way. What majqq said is 100% correct. Let me clarify by adding that getPlayerAccount does never return "true", it is only possible that it returns "false" in certain conditions. And you never want it to return "false" so check the argument before calling getPlayerAccount with invalid things!
-
I looked at your error log and saw that the getPlayerAccount function did receive a nil as first argument. Then after checking your script I realized that p was nil. Finally I tried to search for p in your script and could not find it's definition, thus the error. Now that the error was known, I tried to repair your script. Since I know that Warning1 is a command-handler in my experience a typical error is forgetting to allocate or misnaming the function parameters in the command-handler signature, like the player. This repair was confirmed by the getPlayerAccount function, which expects a player as first argument. What majqq has described is very similar to what I'd do. He did check the wiki to find that getPlayerAccount returns false because the first argument was invalid. I think this is a good idea. Obviously the "anything can go there" assumption is wrong. A command-handler has this very specific signature: void commandHandler(player, cmdName, arg1, arg2, ...) But looking at your first script where you wrote... local function loopVehicles(p) I am pretty sure that you knew that, but you still ... forgot to write it correctly for the "Warning1" function. No idea where this error came from
-
Dear Moony, I assume that your script is serverside, thus the signature of a command handler function looks like: local function commandHandler(player, commandName, args...) In your script above you wrote for the Warning1 command handler: function Warning1() but you should have written... function Warning1(p) to receive the player that executed the command. I have not inspected further errors in the script so please tell us if you have further questions.
-
I suggest that you tell the client whenever he enters a vehicle whether it is a job car or not from serverside. Then you start drawing the HUD after you received that server event. Your script seems pretty big but it should not be too hard.
-
Some generic TXD files are located in the MTA files as part of the network module streaming system hook, to protect against mods. Those cannot be replaced without tamper of MTA files (bad idea). But you are saying more than half are not compressed? Sounds like you are trying to use an ASI mod in combination with MTA.
-
Are you calling the function "collectgarbage" as XaskeL has suggested? I am not seeing it in your code that you posted above.
-
There is no automatic solution because GTA:SA vehicles are only synced when streamed in thus world simulation always stops if they are too far away. Also your train system has to work even if no client is connected to the server? Maybe think about simulating the travel speed of the train server-side and using that to respawn trains. EDIT: there is a train system resource by a MTA forums moderator which does what you want.
- 1 reply
-
- 1
-
-
Oh god. Let me help you seeing that you are not completely familiar with the "local" keyword in Lua. If you create a local variable in Lua then it overshadows any previous local variable definition without modifying variables with same names. Thus from the Lua compiler's perspective local var1 = 1; local var1 = 2; There are two different variables with the same name but you can only access the last variable in subsequent code (the first one remains silently on the Lua stack). THUS, to fix your code, replace line 37 local string1 = nil with string1 = nil Please repair line 42 in the same way. - Martin
-
I created this shader to create a HUE color circle a few years ago: static const float PI = 3.14159265f; uniform float brightness = 1; // Docu: http://chilliant.blogspot.de/2010/11/rgbhsv-in-hlsl.html float3 HUEtoRGB(in float H) { float R = abs(H * 6 - 3) - 1; float G = 2 - abs(H * 6 - 2); float B = 2 - abs(H * 6 - 4); return saturate(float3(R,G,B)); } float4 circleMain( float2 coord : TEXCOORD0 ) : COLOR0 { float2 off = float2(0.5, 0.5) - coord; // Draw a circle clip(0.25 - (off.x * off.x + off.y * off.y)); float angle = atan2(off.y, off.x) / PI / 2; return float4(brightness - HUEtoRGB(angle < 0 ? angle + 1 : angle) * length(off) * 2 * brightness, 1); } technique colorCircle { pass main { PixelShader = compile ps_2_0 circleMain(); } } You can use the dxDrawImage function in combination with a modified HLSL pixel-shader like above and the dxSetShaderValue function to draw a circle-cropped image. The advantage above masking is that the mask has infinite resolution instead of a fixed PNG file. But you need more knowledge about math for this method.
-
Hello xXGhostXx, why can you not use the getSlotFromWeapon function? I see no problem in your code. If you could share all of your code maybe we can detect it together - Martin
-
Please just remember for the next time, then it's no problem I tried out your script and I have the following question: 1) if a player locks a car and leaves it, how does he unlock the car? if I test the script then the player cannot re-enter the car. So I implemented a job car system into your script. You can register vehicle model IDs as fixed job cars and spawn individual jobcars using the /sjc command. client.Lua addCommandHandler("lock", function() triggerServerEvent("TS:LockVehicle", root); end ); addCommandHandler("sjc", function(cmdname, id) if not (id) then return; end; outputChatBox("spawning: " .. id); triggerServerEvent("TS:SpawnJobCar", root, tonumber(id)); end ); server.Lua local always_job_car_ids = { [420] = true }; local spawned_job_cars = {}; local function isjobcar(vehicle) local veh_id = getElementModel(vehicle); if (always_job_car_ids[veh_id]) then return true; end if (spawned_job_cars[vehicle]) then return true; end return false; end local function spawn_job_car(model, x, y, z) local veh = createVehicle(model, x, y, z); spawned_job_cars[veh] = true; addEventHandler("onClientElementDestroy", veh, function() spawned_job_vars[veh] = nil; end ); return veh; end addEvent("TS:SpawnJobCar", true); addEventHandler("TS:SpawnJobCar", root, function(id) if not (id) then return; end; local px, py, pz = getElementPosition(client); spawn_job_car(id, px, py + 5, pz + 2); end ); function lockvehicle() local Vehicle= getPedOccupiedVehicle(client) if not Vehicle then outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffVocê não está em nenhum vehicle!",client,255,0,0,true) return end if (isjobcar(Vehicle)) then outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffCannot lock job car.", client, 255, 0, 0, true); return; end local Seat = getPedOccupiedVehicleSeat(client) --local PlayerID = getElementData(client, "ID") --if not PlayerID then return end local PlayerID = getPlayerName(client); if Seat == 0 then if not getElementData(Vehicle, "TS:Locked") == true then setElementData(Vehicle, "TS:Locked", true) setElementData(Vehicle, "TS:VehicleOwner", PlayerID) outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffVehicle Locked!",client,255,0,0,true) else setElementData(Vehicle, "TS:Locked", false) setElementData(Vehicle, "TS:VehicleOwner", false) outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffVehicle Unlocked!",client,255,0,0,true) end else outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffYou are not the vehicle driver!",client,255,0,0,true) end end addEvent("TS:LockVehicle", true) addEventHandler("TS:LockVehicle", root, lockvehicle) function VehicleLocked(player) local PlayerID = getElementData(player, "ID") if getElementData(source, "TS:Locked") == true then if getElementData(source, "TS:VehicleOwner") == PlayerID then return end outputChatBox("#0040ff?#ffffffBVM#0040ff?? #ffffffThe Vehicle is Locked!",player,255,0,0,true) cancelEvent() end end addEventHandler("onVehicleStartEnter", root, VehicleLocked) The always_job_car_ids table holds model numbers that will always be job cars. An example is the taxi car which has been added to the list by me. You can dynamically or remove a model number using: -- Add the Landstalker. always_job_car_ids[400] = true; -- Remove the Landstalker. always_job_car_ids[400] = nil; If you call the spawn_job_car function then you can create a single unique job car (for example cars used during a mission/raid) that cannot be locked. Feel free to use this concept if you like it I have to mention a very important change to your script about your usage of source in the "TS:LockVehicle" event. Did you know that hackers can put the source element at their own wish, possibly locking the car of an admin player? Please use the global variable "client" to fix this problem. This way the player can only lock or unlock his own car. - Martin
-
Hello lockdw, could you please use the "<>" button to format your Lua code properly? Otherwise you make it hard for people to read your code. - Martin
-
Hello MaRcell, you can improve this script by only firing if the attacker is an enemy player or ped or the vehicle that damaged the ped was controlled by an enemy entity. How about implementing a check for damage of the attack-target aswell? If the attack target has exploded or died then you can make the ped stop firing it's weapon. If you want to implement shooting-on-sight then I recommend client-side (mind trust/security risks of client-side logic) range and line-of-sight checking using "onClientRender" event handler, getDistanceBetweenPoints3D and processLineOfSight functions. Just loop through all the enemy peds, check that they in close proximity of the AI ped, check the line from center of AI ped to the enemy ped. If the processLightOfSight returns the enemy ped as hitElement then the AI ped can start shooting into it's direction. Would also be cool if you continued checking the line of sight to disable shooting if a wall is between shooter and target. The last thing you could improve is a movement navigation system for the peds. But this would be pretty advanced stuff.
-
Dear lockdw, please format your post properly next time using the "<>" backets button in the richtext editor But now on to your request. In the other thread you wanted to know how to stop the player from sprinting. Did you know about the toggleControl function? You can look up control names on the wiki and one of them happens to be "sprint". So during the tired-out phase of the player I recommend you to do (clientside): toggleControl("sprint", false) EDIT: a couple years ago another person did implement a stamina system in another thread. he did share his code. it was made with the help of experienced MTA community members. maybe you want to compare yours with his?
-
Hello iPollo, I remember that I helped you synchronize the serverside arrays with all clients using events. You remember those events, right? I think you have to be aware of a big problem if you want to remove items on the clientside: do all clients still have the same items defined? or does one client have more items than another? For that reason I would recommend deleting the items on the server and resynchronizing the arrays using that event that we have discovered earlier this week.
-
Nice video! I think that you have made it really entertaining. I especially liked that crazy cross-roads driving at 0:40 and that wicked "save" at 0:55. Personally, I did not know that MTA could be such a competetive gaming platform