Jump to content

Visible nicknames in different dimensions and making code look better


Thorxx

Recommended Posts

Hello,

I have returned to MTA after a really long time and as I have returned I also returned to scripting, so count me as a beginner.
I was a little bit bored of playing gamemodes and stuff, so I decided to script something and give it a try to make something on my own, just for fun and so on...

What I am working on is a simple version of Multigamemode, but I am currently struggling with something easy I suppose (as usual lol).

First of all... I would like someone to take a look at my code and check if there's a way to make things easier or make it not contain the same code twice, which is my problem.
 

function Lobby.arenaDraw()
	-- draw ped/npc names above their head
	if roomDeathmatch then
		local pedX, pedY, pedZ = getElementPosition(roomDeathmatch)
		local sx, sy = getScreenFromWorldPosition(pedX, pedY, pedZ)
		local cameraX, cameraY, cameraZ = getCameraMatrix()
		
		dxDrawTextOnElement(roomDeathmatch, "Deathmatch", 1, 20, 255, 255, 255, 255, 2, "sans")
		dxDrawTextOnElement(roomDeathmatch, "#2980b9Press #ffffff".."F".." #2980b9to join", 0.9, 20, 255, 255, 255, 255, 1.6, "sans")
		
		dxDrawTextOnElement(roomDemolition, "Demolition Derby", 1, 20, 255, 255, 255, 255, 2, "sans")
		dxDrawTextOnElement(roomDemolition, "#2980b9Press #ffffff".."F".." #2980b9to join", 0.9, 20, 255, 255, 255, 255, 1.6, "sans")		
		
		if (isLineOfSightClear(pedX, pedY, pedZ+2, cameraX, cameraY, cameraZ)) then
			if getDistanceBetweenPoints3D(cameraX, cameraY, cameraZ, pedX, pedY, pedZ) <= interactRange then
				if getElementData(localPlayer, "Room") == "Lobby" then
					bindKey("F", "up", Lobby.roomJoinDeathmatch)
				end
			else
				unbindKey("F", "up", Lobby.roomJoinDeathmatch)
			end
		end
	end
	
	if roomDemolition then
		local pedX, pedY, pedZ = getElementPosition(roomDemolition)
		local sx, sy = getScreenFromWorldPosition(pedX, pedY, pedZ)
		local cameraX, cameraY, cameraZ = getCameraMatrix()
		
		dxDrawTextOnElement(roomDemolition, "Demolition Derby", 1, 20, 255, 255, 255, 255, 2, "sans")
		dxDrawTextOnElement(roomDemolition, "#2980b9Press #ffffff".."F".." #2980b9to join", 0.9, 20, 255, 255, 255, 255, 1.6, "sans")		
		
		if (isLineOfSightClear(pedX, pedY, pedZ+2, cameraX, cameraY, cameraZ)) then
			if getDistanceBetweenPoints3D(cameraX, cameraY, cameraZ, pedX, pedY, pedZ) <= interactRange then
				if getElementData(localPlayer, "Room") == "Lobby" then
					bindKey("F", "up", Lobby.roomJoinDemolition)
				end
			else
				unbindKey("F", "up", Lobby.roomJoinDemolition)
			end
		end
	end	
end
addEventHandler("onClientRender", getRootElement(), Lobby.arenaDraw)

The problem is that with every room I create I basically copy the code above and replace some functions and stuff... Which I think is not a really good work as it will only flood my code later on.
I would like to find a solution to make it shorter with only one part of code instead of copying things over and over again.

And one more thing I would like to ask...
I am drawing nicknames above players, but they are not separated by dimension... Basically when you switch the dimension and play DM for example, you can see nicknames from DD (if the map is at the same place or somewhere closer...)

addEventHandler("onClientRender", getRootElement(),
function ()
	for _, player in ipairs(getElementsByType("player")) do
		if getElementData(player, "Room") then
			dxDrawTextOnElement(player, getPlayerName(player), 0.9, 70, 255, 255, 255, 255, 1.5, "sans")
		end
	end
end)

I would like to separate the names by dimension, so players from dimension 1 wont see names of players from dimension 2.

 

Would be really happy for someone to help me out solving these (simple, I guess?) issues.
Thanks in advance.

Link to comment

In second part add an if-statement

addEventHandler("onClientRender", getRootElement(),
function ()
	for _, player in ipairs(getElementsByType("player")) do
		if getElementData(player, "Room") then
        	   if getElementDimension(player)==getElementDimension(localPlayer) then
				 dxDrawTextOnElement(player, getPlayerName(player), 0.9, 70, 255, 255, 255, 255, 1.5, "sans")
                   end
		end
	end
end)

 

Edited by VenomNX
Link to comment
  • Moderators
39 minutes ago, Thorxx said:

I would like to separate the names by dimension, so players from dimension 1 wont see names of players from dimension 2.

Afaik elements in other dimensions are not streamedin, also by enabling the streamedin capture feature, the performance will improve

 

getElementsByType("player", root, true)

 

39 minutes ago, Thorxx said:

I would like to find a solution to make it shorter with only one part of code instead of copying things over and over again.

You can add another function, that makes use of the existing function and does for example: draw an X amount of lines under each other.

dxDrawMultiLineTextOnElement(roomDeathmatch, {"Deathmatch", 1, 20, 255, 255, 255, 255, 2, "sans"}, { "Deathmatch", 1, 20, 255, 255, 255, 255, 2, "sans"})

function dxDrawMultiLineTextOnElement (element, ...)
  local lines = {...}
  -- etc.
end

 

 

 

Edited by IIYAMA
Link to comment

Thank you both guys, managed to do it your way a it works very well and looks a lot better. 

But to not start a new thread I will ask here. 

As you maybe understood I am working on a multigamemode and I would like to ask you, how would you handle file loading? 

Its running as a one big gamemode, where I created folder race with race client and race server. These files are called by function from those peds clicl events... Lets say, you go to an npc, press F and it does this Race.main() and calls function Race.main from my race folder. Then in Race.main I have trigger for client to handle the drawings, but when I leave race to join lobby I need to separately remove all the drawing events and everything included, such as kill list and so on... Is there a way to disable it all at once? For localPlayer only to not kill the mode for other players... 

  • Like 1
Link to comment
  • Moderators
44 minutes ago, Thorxx said:

These files are called by function from those peds clicl events...

 

That is where you need to create wrappers.

It is function overwrite that is executed before the original function, making sure that you can register what has happened (and undo it later).

addEventHandler_ = addEventHandler

local addEventHandler = function (...)
  -- collect the information you need, to remove the addEventHandler for a specific file/mode.
  return addEventHandler_(...)
end

 

Check out other multi gamemodes for inspiration.

 

 

 

Edited by IIYAMA
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...