Scaleform Wrapper - Use scaleforms neater and simpler!

#1

This is a release specifically for developers, which should help out drastically when using scaleforms.
It is similar to the C# wrapper for scaleforms, but in Lua!

Example code with wrapper (Results in the same image on my scaleform documentation):

Citizen.CreateThread(function()
    local s = Scaleform.Request("mp_big_message_freemode")
    s:CallFunction("SHOW_SHARD_WASTED_MP_MESSAGE", "SOME TEXT", "SOME MORE TEXT", 5)
    while true do
        Citizen.Wait(0)
        s:Draw2D()
    end
end)

Without Wrapper:

Citizen.CreateThread(function()
    local scaleform = RequestScaleformMovie("mp_big_message_freemode")
    while not HasScaleformMovieLoaded(scaleform) do
        Citizen.Wait(0)
    end
    
    BeginScaleformMovieMethod(scaleform, "SHOW_SHARD_WASTED_MP_MESSAGE")
    PushScaleformMovieMethodParameterString("SOME TEXT")
    PushScaleformMovieMethodParameterString("SOME MORE TEXT")
    PushScaleformMovieMethodParameterInt(5)
    EndScaleformMovieMethod()

    while true do
        Citizen.Wait(0)
        DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255)
    end
end)

Result:

Download it here (comes with an example in the resource, howver can be implemented into any script you wish, or just yoinked into some sort of helper resource):

Happy scaleforming!

16 Likes
#2

Nice dude im going to test around a bit

2 Likes
#3

Another great release tea. Great work.

1 Like
#4

EPIC - Well done dad, awesome release.

1 Like
#5

Great! Been waiting for you to release this, this will definetly speed up and simplify my shitty Scaleform methods! Hopefully we’ll also see more implementations of Scaleform in other releases.

1 Like
#6

Thanks, a shame really, how little people use them at times, because they can be handy if you for example, arent too good at design, or infact, if you just want to go with that nice native look :stuck_out_tongue:

1 Like
#7

I have a similar solution (also based on the clrcore), and I think this would simplify/improve your codebase (note: I had to make some modifications to what I’ve pasted for readability so I apologize for bugs/typos).

function Scaleform.__PushScaleformValue(value)
    if type(value) == "boolean" then
        PushScaleformMovieMethodParameterBool(value) 
    elseif type(value) == "number" then
        if math.type(value) == "integer" then
            PushScaleformMovieMethodParameterInt(value) 
        else -- float
            PushScaleformMovieMethodParameterFloat(value)
        end
    elseif type(value) == "string" then
        BeginTextCommandScaleformString("STRING")
        AddTextComponentSubstringPlayerName(value)
        EndTextCommandScaleformString()

    --[[
        @NOTES: Technically requires an additional table to ensure no cycles
        occur (i.e., table A ==> table B ==> .. ==> table A).
    --]]
    elseif type(value) == "table" then
        if value.name == "texture" then
            PushScaleformMovieMethodParameterString(value.value)
        elseif value.name == "button" then
            PushScaleformMovieMethodParameterButtonName(value.value)
        else
            for _,tableValue in pairs(value) do
                Scaleform.__PushScaleformValue(tableValue)
            end
        end
    else
        Scaleform.logger:Severe("Unknown argument passed to scaleform: " .. tostring(value))
    end
end

CallFunction/CallFunctionReturn can then use the same function, for example:

function Scaleform:CallFunction(functionName, ...)
    BeginScaleformMovieMethod(self.handle, functionName)
    for i=1,select('#', ...) do
        Scaleform.__PushScaleformValue(select(i, ...))
    end
    EndScaleformMovieMethod()
    return self
end

So when working with DUI Scaleforms you can mimic inheritance:

    self:CallFunction("SET_TEXTURE",
        { name = "texture", value = self.txdString },
        { name = "texture", value = self.txnString },
        0, 0, self.width, self.height 
    )
#8

Every server needs to use the instructional buttons scaleform.

2 Likes
#9

this is the main reason i use scaleforms all the time ahahah, nice release :heart:

2 Likes
#10

Great, when I saw it, I remembered that I had something like this.

In my code scaleform functions are dynamically called(?) based on the type of variable

Is old and not complete because I don’t check if the numbertype is float or int. Maybe someone will find that useful too

function Initialize(scaleform, sub, params)
	local scaleform = RequestScaleformMovie(scaleform)
	
    while not HasScaleformMovieLoaded(scaleform) do
        Citizen.Wait(0)
	end
	PushScaleformMovieFunction(scaleform, sub)
	for i = 1, #params do
		tp = type(params[i])
		_G["PushScaleformMovieFunctionParameter" .. tp:sub(1,1):upper()..tp:sub(2)](params[i])
	end
	PopScaleformMovieFunctionVoid()
	
    return scaleform
end
Usage example
Citizen.CreateThread(function()
    params = {"<i>~p~"..'HELLO'.."</i>", 'anither text', ":)"}
	scaleform = Initialize("MP_BIG_MESSAGE_FREEMODE", "SHOW_TERRITORY_CHANGE_MP_MESSAGE", params)

	while true do
		Citizen.Wait(0)
		DrawScaleformMovie(scaleform, 0.5, 0.5, 0.8, 0.8, 255, 255, 255, 255, 0)
	end
end)
1 Like
#11

Heyo peoples! Im now going to start putting all of my neat discoveries onto This GitHub page, starting with mp_mission_name_freemode
which looks like:

have fun!

2 Likes
#12

For anyone who is unsure how to discover this type of stuff :stuck_out_tongue:

#13

Added a quick change which will allow you to do scaleform:CallHudFunction and Scaleform.RequestHud to now start using hud component scaleforms too!