Dzsozi (h03)

Could somebody help me finishing this?

Recommended Posts

Hey, so, I would like to make a GTA like (it sounds strange) notification system, something like you can see in every singleplayer GTA, the upper left hand corner box notifications:

367630302.jpg

I have the base script, everything renders and works fine, but I would like to make a special "timer" for it, which works like the following way: the longer the text is, the longer the notification lasts. This is one thing I would like to make, the other thing is: how is it possibble to make an export function for this, so I can make notifications from other resources with the text I give in the resource I'm calling it back from. I don't really understand tables and loops, I would be so happy if somebody could help me!

 

I hope you can understand me, and what I am trying to do and explain, thanks for the help in advance!

 

local displayWidth, displayHeight = guiGetScreenSize();
local borderDistance = 20
local tipBox = { string = "asfasfasafaasfasfasafsafsfasfasafsasfasfafsafssafasfsdwadsadwqwdasdasfasasafsaf" } 
local boxX, boxY = borderDistance * displayWidth / displayWidth, borderDistance * displayHeight / displayHeight 
local boxPadding = 10
local lineHeight = dxGetFontHeight( 1, "default-bold" ) 
local minimumWidth = 350
local offsetWidth = 25 
  
addEventHandler( "onClientRender", root, 
    function( )
        local lines = 0 
        local wordbreak = false 
        local lineWidth = dxGetTextWidth( tipBox.string, 1, "default-bold" ) 
         
        while ( lineWidth + offsetWidth > minimumWidth ) do 
            lineWidth = lineWidth - minimumWidth 
            lines = lines + 1 
            wordbreak = true 
        end 
         
        local boxWidth, boxHeight = minimumWidth + ( boxPadding * 3 ), ( lineHeight * ( lines + 1 ) ) + ( boxPadding * 2 ) 
         
        dxDrawRectangle( boxX, boxY, boxWidth, boxHeight, tocolor( 0, 0, 0, 180 ), true )
		dxDrawRectangle( boxX, boxY+boxHeight, boxWidth, 4, tocolor( 200, 0, 100, 255 ), true ) 
         
        local textX, textY = boxX + boxPadding, boxY + boxPadding 
        local textWidth, textHeight = textX + minimumWidth + boxPadding, textY + lineHeight + boxPadding 
         
        dxDrawText( tipBox.string, textX, textY, textWidth, textHeight, tocolor( 255, 255, 255, 255 ), 1, "default-bold", "left", "top", false, wordbreak, true ) 
    end 
) 

 

  • Like 1

Share this post


Link to post

well, i used this on my notification functions and never was troubled: 

timeToFade = getTickCount () + #text * 150;

for exports, there are two ways. one: setting variables on resource start and check if variable is assigned to a value on render and use it if it does. two: creating a local function in your exported function and pass the arguments you need to render (i prefer this one because variables are nasty-looking).

so, the new code should look like this:

local displayWidth, displayHeight = guiGetScreenSize();
local borderDistance = 20
local tipBox = { } 
local boxX, boxY = borderDistance * displayWidth / displayWidth, borderDistance * displayHeight / displayHeight 
local boxPadding = 10
local lineHeight = dxGetFontHeight( 1, "default-bold" ) 
local minimumWidth = 350
local offsetWidth = 25 
local tick = 0
  
addEventHandler( "onClientRender", root, 
    function( )
		if tipBox.string then 
			local lines = 0 
			local wordbreak = false 
			local lineWidth = dxGetTextWidth( tipBox.string, 1, "default-bold" ) 
			 
			while ( lineWidth + offsetWidth > minimumWidth ) do 
				lineWidth = lineWidth - minimumWidth 
				lines = lines + 1 
				wordbreak = true 
			end 
			 
			local boxWidth, boxHeight = minimumWidth + ( boxPadding * 3 ), ( lineHeight * ( lines + 1 ) ) + ( boxPadding * 2 ) 
			 
			dxDrawRectangle( boxX, boxY, boxWidth, boxHeight, tocolor( 0, 0, 0, 180 ), true )
			dxDrawRectangle( boxX, boxY+boxHeight, boxWidth, 4, tocolor( 200, 0, 100, 255 ), true ) 
			 
			local textX, textY = boxX + boxPadding, boxY + boxPadding 
			local textWidth, textHeight = textX + minimumWidth + boxPadding, textY + lineHeight + boxPadding 
			 
			dxDrawText( tipBox.string, textX, textY, textWidth, textHeight, tocolor( 255, 255, 255, 255 ), 1, "default-bold", "left", "top", false, wordbreak, true ) 
			
			if getTickCount () >= tick then 
				alpha = alpha - 25; 
				if alpha <= 0 then 
					alpha = 0;
					tipBox.string = nil;
				end
			end	
		end	
    end 
) 

function notificate (text) --declare your function
	tipBox.string = text;
	tick		  = getTickCount () + (#text * 150);
	alpha		  = 255; --if you want it to fade
end

notificate ("shakalaka boom"); --testing

i haven't tried it

  • Like 1

Share this post


Link to post

It works, thank you!!

But I would have one more question. Is this possibble to use color coded dxText in this script properly? Because if I set colorcoded to true it doesn't break the text, is there any possibble way to fix this? So can I have colored words with the same line breakings?

Edited by Dzsozi

Share this post


Link to post
4 minutes ago, Dzsozi said:

It works, thank you!!

But I would have one more question. Is this possibble to use color coded dxText in this script properly? Because if I set colorcoded to true it doesn't break the text, is there any possibble way to fix this? So can I have colored words with the same line breakings?

yeah sure, you can cut the color coded part when breaking the string and add it on later when rendering. for instance, say, you have a string "stringx3" and you want to cut out the "x3" part, you'd use;

var = var:gsub ("x3", "");  

 

i didn't expand the example to not to get in your way too much, tell me if you need further details though. good luck!

Share this post


Link to post
local lines = 0 
local wordbreak = false 
local str = tipBox.string
while str:find ("#%x%x%x%x%x%x") do 
  str = str:gsub('#%x%x%x%x%x%x', '');
end	
local lineWidth = dxGetTextWidth( str, 1, "default-bold" ) 

while ( lineWidth + offsetWidth > minimumWidth ) do 
  lineWidth = lineWidth - minimumWidth 
  lines = lines + 1 
  wordbreak = true 
end 

try this please

  • Like 1

Share this post


Link to post

The only thing changes is the background's Y size for some reason. If I put these lines inside the script the background acts like there are no colorcodes in the text, but the text displays the color codes, but without changing the color. If I comment these 3 lines out

while str:find ("#%x%x%x%x%x%x") do 
  str = str:gsub('#%x%x%x%x%x%x', '');
end	

then the background works normally, but check the screenshots, maybe you will understand better what I'm trying to say.

 

If these new 3 lines are inside the script:

eFYxKtx.png

 

If not (background is working good now, not being cut down):

yCm5zEm.png

 

But if I set the colorcoded parameter to true then it works as before, no line breaking. Or is it my fault, am I missing something or I did something wrong?

 

Here's the current code:

 

local borderDistance = 20
local tipBox = { } 
local boxX, boxY = borderDistance * displayWidth / displayWidth, borderDistance * displayHeight / displayHeight 
local boxPadding = 10
local lineHeight = dxGetFontHeight( 1, "default-bold" ) 
local minimumWidth = 350
local offsetWidth = 25 
local tick = 0
  
addEventHandler( "onClientRender", root, 
    function( )
		if tipBox.string then 
			local lines = 0 
			local wordbreak = false 
			local str = tipBox.string
			while str:find ("#%x%x%x%x%x%x") do 
			  str = str:gsub('#%x%x%x%x%x%x', '');
			end	
			local lineWidth = dxGetTextWidth( str, 1, "default-bold" ) 

			while ( lineWidth + offsetWidth > minimumWidth ) do 
			  lineWidth = lineWidth - minimumWidth 
			  lines = lines + 1 
			  wordbreak = true 
			end 
			 
			local boxWidth, boxHeight = minimumWidth + ( boxPadding * 3 ), ( lineHeight * ( lines + 1 ) ) + ( boxPadding * 2 ) 
			 
			dxDrawRectangle( boxX, boxY, boxWidth, boxHeight, tocolor( 0, 0, 0, 180 ), true )
			dxDrawRectangle( boxX, boxY+boxHeight, boxWidth, 4, tocolor( 200, 0, 100, 255 ), true ) 
			 
			local textX, textY = boxX + boxPadding, boxY + boxPadding 
			local textWidth, textHeight = textX + minimumWidth + boxPadding, textY + lineHeight + boxPadding 
			 
			dxDrawText( tipBox.string, textX, textY, textWidth, textHeight, tocolor( 255, 255, 255, 255 ), 1, "default-bold", "left", "top", false, wordbreak, true ) 
			
			if getTickCount () >= tick then 
				alpha = alpha - 25; 
				if alpha <= 0 then 
					alpha = 0;
					tipBox.string = nil;
				end
			end	
		end	
    end 
) 

addEvent('addNotificationGTA', true);
function addNotificationGTA (text)
	tipBox.string = text;
	tick		  = getTickCount () + (#text * 100);
	alpha		  = 255;
	playSoundFrontEnd(11);
end
addEventHandler('addNotificationGTA', root, addNotificationGTA);

addNotificationGTA("asdaddNotificat#FF0000ionGTAaddNotificationGTAaddN#FFFFFFotificationGTAaddNotificationGTAaddNotificationGTAaddNotificationGTA")

 

Share this post


Link to post

The wiki says:

colorCoded: Set to true to enable embedded #FFFFFF color codes. Note: clip and wordBreak are forced false if this is set.

I guess you'll have to do it without color codes in order to make your notification system work properly. 

Edited by Gravestone

Share this post


Link to post
10 hours ago, Adolfram said:

i think you could do a custom wordreak with some math magic. but i have no clue how, sadly

Well you don't need to be a math magician for that, all you gotta do is to count the characters in one single line and then insert a line break character, usually \n, not sure if it works on all controls in MTA tho but at least it works on labels like in this example from GTW:

guiSetText(labelInfo, "Enter your friends account name \nto send him/her an invite bonus\nof $4'000 as a reward.")

 

Edited by Urban_West
spelling error

Share this post


Link to post

yeah you're right but still gotta use math to part the string line by line, i think i can do it when i get home

Share this post


Link to post

Try this 

local function splitWords(Lines, limit)
    while #Lines[#Lines] > limit do
        Lines[#Lines+1] = Lines[#Lines]:sub(limit+1)
        Lines[#Lines-1] = Lines[#Lines-1]:sub(1,limit)
    end
end

local function wordWarping(str, limit)
    local Lines, here, limit, found = {}, 1, limit or 72, str:find("(%s+)()(%S+)()")

    if found then
        Lines[1] = string.sub(str,1,found-1)  
    else 
        Lines[1] = str 
    end

    str:gsub("(%s+)()(%S+)()",
        function(sp, st, word, fi)  
            splitWords(Lines, limit)

            if fi-here > limit then
                here = st
                Lines[#Lines+1] = word                                             
            else 
                Lines[#Lines] = Lines[#Lines].." "..word 
            end 
        end)

    splitWords(Lines, limit)

    return Lines
end

local myText = "Yeah you're right but still gotta use math to part the string line by line, i think i can do it when i get home." -- Adolfram reply
local myTable = wordWarping(myText,20)

for k,v in pairs(myTable) do 
    outputChatBox(k.." = "..v) 
end

BtW MTA doesn't handle the word wrapping, It's all done by DirectX
  • Like 1

Share this post


Link to post
11 hours ago, Walid said:

Try this 


local function splitWords(Lines, limit)
    while #Lines[#Lines] > limit do
        Lines[#Lines+1] = Lines[#Lines]:sub(limit+1)
        Lines[#Lines-1] = Lines[#Lines-1]:sub(1,limit)
    end
end

local function wordWarping(str, limit)
    local Lines, here, limit, found = {}, 1, limit or 72, str:find("(%s+)()(%S+)()")

    if found then
        Lines[1] = string.sub(str,1,found-1)  
    else 
        Lines[1] = str 
    end

    str:gsub("(%s+)()(%S+)()",
        function(sp, st, word, fi)  
            splitWords(Lines, limit)

            if fi-here > limit then
                here = st
                Lines[#Lines+1] = word                                             
            else 
                Lines[#Lines] = Lines[#Lines].." "..word 
            end 
        end)

    splitWords(Lines, limit)

    return Lines
end

local myText = "Yeah you're right but still gotta use math to part the string line by line, i think i can do it when i get home." -- Adolfram reply
local myTable = wordWarping(myText,20)

for k,v in pairs(myTable) do 
    outputChatBox(k.." = "..v) 
end

BtW MTA doesn't handle the word wrapping, It's all done by DirectX

I changed the wordWarping limit to 50 instead of 20 and set the outputchatbox colorcodes to true, I added a red colorcode in front of "but" and added back the white colorcode in front of "it". So, the line breaks after the "math" word, and its only red until the math word, so after the line break the color doesn't continue. Is there any way to fix that? If so, that would work perfectly!

Share this post


Link to post

Bump or no bump, if people don't know how it won't make any difference :D

Share this post


Link to post

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.