Interactive menu
<div class="IPBDescription">Asking for help</div>Ok, I am coding a little gamemode for ns2, but I really suck at gui, so I would like some help.
First of all, if I got it right, gui's in ns2 is made using swf files huh?
If so, how do I make them (do I need flash proffessional? if so, I got it on my laptop, but I would prefer not to make flash there and usb to my computer)?
Second, if it is only possible with .swf files, could anyone explain to me how I incorporate them into lua right (do I controll the timeline with lua functions, or is it like a normal flashprogram except it also tells lua when certain events happen)?
If it is not .swf files, how is it done? In gmod you use a set of "derma" functions, is there something similar in ns2, or do I have to draw shapes on the screen, unlock mouse and keep track of pos and buttons?
How do I make the interface grab thumbnails of models/materials like spark does? except working ofcourse (spark doesnt show images to me, just white picture with blue recycle image on it).
Any other information that might be relevant would be appreciated.
EDIT: If someone "experienced" to coding for the ns2 engine test would like to befriend me on steam to help, just pm me.
First of all, if I got it right, gui's in ns2 is made using swf files huh?
If so, how do I make them (do I need flash proffessional? if so, I got it on my laptop, but I would prefer not to make flash there and usb to my computer)?
Second, if it is only possible with .swf files, could anyone explain to me how I incorporate them into lua right (do I controll the timeline with lua functions, or is it like a normal flashprogram except it also tells lua when certain events happen)?
If it is not .swf files, how is it done? In gmod you use a set of "derma" functions, is there something similar in ns2, or do I have to draw shapes on the screen, unlock mouse and keep track of pos and buttons?
How do I make the interface grab thumbnails of models/materials like spark does? except working ofcourse (spark doesnt show images to me, just white picture with blue recycle image on it).
Any other information that might be relevant would be appreciated.
EDIT: If someone "experienced" to coding for the ns2 engine test would like to befriend me on steam to help, just pm me.
Comments
This interface needs the thumbnails as I said, and obviously I need the path to them, so I have been trying to find how you get the contents of a directory.
I am not sure, but this seems like exactly what I need (file.FindDir(string)): <a href="http://wiki.garrysmod.com/?title=File.FindDir" target="_blank">http://wiki.garrysmod.com/?title=File.FindDir</a>
However, it is gmod lua, in ns2 there is no such thing as the file library. So it does not work.
So I got another question, how do I get the content of a directory?
Wow :) slow down :) you only gave us three hours to answer you
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->First of all, if I got it right, gui's in ns2 is made using swf files huh?<!--QuoteEnd--></div><!--QuoteEEnd-->
Yep, everything, including head's up display, all menus, and even that little display on the back of your gun showing how many bullets you have left. That is also a swf file.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->If so, how do I make them (do I need flash proffessional? if so, I got it on my laptop, but I would prefer not to make flash there and usb to my computer)?<!--QuoteEnd--></div><!--QuoteEEnd-->
The bad news is... you won't have the choice... or maybe you want to script from scratch (try an AS2 builder + FlashDevelop + swfmill). But I strongly warn you : you gonna suffer !
going through Flash, even if you don't know how to use for now might be far less painful than scripting your gui with pure dev
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->could anyone explain to me how I incorporate them into lua right (do I controll the timeline with lua functions, or is it like a normal flashprogram except it also tells lua when certain events happen)?<!--QuoteEnd--></div><!--QuoteEEnd-->
The later is right. Whenever you want to call any lua script, you use a global function lua() in your action script. Since it's AS2 (oh crap) it won't crash when building into flash even if that lua() function doesn't exist in AS language... but it will try to run it anyway (pukes). But that's what save us in our case :)
Example :
You have a lua command that returns coordinates of any enemy in front of the player which name is "getEnemyPosition". You want to show it on the player's screen on some kind of minimap. So in your flash script, you call that sort of thing :
var currentEnemyPosition = lua( "getEnemyPosition") ;
... et voilà !
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->So I got another question, how do I get the content of a directory?<!--QuoteEnd--></div><!--QuoteEEnd-->
As far as i know, you won't get anywhere with AS2. LUA might help you but don't count n flash for that sort of things.
NOTE : if you want to check exactly what is done in flash and what isn't, check your installation folder, and goto ns2/ui/. Try to run "main_menu.swf" and compare to what you get inside the pre alpha build. You might notice that nearly everything visual is made with flash, and that even some submenus are there. "Exit" button doesn't work because it only calls a lua command that close the app, adn since you're watching that swf file with the basic flash player, it won't understand the "lua()" call.
Everything you see when running that main_menu.swf alone is done in flash. you know what it means :) 'got to learn how to make that Flash dance
And yeah, I have been messing with this for about 3 hours (+ before I posted), so I already tried the .swf files (used firefox), noticed flash can call lua functions (MainMenu.lua and PlayerUI.lua showed signs, and I even found some VERY usefull comments ("Called by Flash to get the number of bullets in the active weapon.")), altough that lua cant trigger the flash doesnt sound as good (thnx for that info).
But thnx for clarifying that flash is only way (didnt like that fact :P), explaining everything further, your examples, all your answers, and that you answered at all!
I know I only gave you about 3 hours, but I am going to bed now, so I wanted a quick response :P.
Also, I did not even get the thought that flash would be capable of getting content of a folder, but good that you explained that to as I might have got it later. To bad you did not know a lua way though :(.
Also, other people, dont be afraid of answering my questions while I sleep, its a great risc (heh) that I will still be alive to read them tomorrow!
And yeah, I make very bad jokes.
I don't know whether lua can trigger flash or not, but what I do know is that you can trigger events in flash with lua and vice versa. You do it this way :
Say you want to flash a red icon on the gui when you player doesn't have any ammo left. That icon will be a flash MovieClip with it's own timeline. You animated it so it blinks and it's red, showing an ammunition icon. You called it "flashingRedAmmo". Now you have a bunch of lua commands that manage ammo count through out the game. Say you have a command that checks if you have any munition left and that it return true or false (false as long as you have munition). That command would be "getAmmoAlert". Then what you have to do is put into your flash script the following :
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->ammoAlertSignal = lua( "getAmmoAlert" );
if ( ammoAlertSignal )
{
_root.flashingRedAmmo._visible = true;
lua( "sound_playRedAlert" );
} else {
_root.flashingRedAmmo._visible = false;
}<!--c2--></div><!--ec2-->
When building up a gui for ns2, you have to check your script at every frame or it won't update your visual elements. So that script over there is evaluated at every frame, and each time, it checks if you have ammo left by calling the lua command. If there's no ammo left, it shows the flashing icon AND ask lua to play a sound (which is just an example. You shouldn't call sound from your gui since flash is totally asynchronous. Yet, you might need to call for sounds from flash but ONLY if those sounds have to be played with user interaction, in rhythm with some gui animation, or any case where sound only depends on what's happening in the gui)
Is that nice and clear for you ?
I guess I start trying to make a gui now, all its going to be is a menu with scroll bar, and get a table of file paths (get it from lua) to images, loop it and display buttons with those images
I assume that even though flash cant get contents of a directory, it can still acess images it already have the filepath to (.dds files).
Or will I have to find another way for that part?
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->all its going to be is a menu with scroll bar<!--QuoteEnd--></div><!--QuoteEEnd-->
O_o Good luck. For someone who has never tried flash before, you begin hard.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->I assume that even though flash cant get contents of a directory, it can still acess images it already have the filepath to (.dds files).
Or will I have to find another way for that part?<!--QuoteEnd--></div><!--QuoteEEnd-->
It seems that the classic approach used in AS2 to load bitmaps from a URL or filepath won't work in NS2 with gameswf. If you check on the other thread talking about flash, where HenryJK posts sometimes, you'll find that it's the very point I'd like him to clarify. AS2 normally use MovieClip.loadMovie( bitmap_url ) to load bitmaps and use them, but it seems to me that the swf file doesn't have direct access to hard drive. HernyJK talked about <a href="http://www.unknownworlds.com/ns2/forums/index.php?s=&showtopic=109401&view=findpost&p=1771225" target="_blank">binding variables with bitmaps resources</a> on hard drive in lua. You might want to check it out.
But anyway, I don't know if the swf would accept a .dds bitmap. It might need some conversion (jpg png or gif) before handling. Who knows, maybe UWE did implement some .dds decoder in their gameswf lib.
Thank for that link, I had read it before but did not really get what he said (now that it got put in a context I understand though :P). Basiclly, you make a placeholder in flash, then runs code which check what file you bound to that placeholder via lua, and replaces.
So what I would have to do, is make a lua function named CountImages() or something, which flash calls, then loops code to create that amount of placeholders. Then it use the replace function to replace image "1", "2" and so on, until all of them is replaced. Having numerical id will let lua easily loop the table and do Client.BindFlashTexture( toString(i), table[i] ).
Anything I misunderstood?
I also got a new question, not really relevant, but something I need to know to debug some lua systems before I made the flash system. How do I print stuff to console? Msg(string) returns error, print(string) does not do anything at all, and I cant find any other code making debug messages. I am sure the code runs, cause as I said, Msg() gives an error msg that there is no such thing.
EDIT: Ah, I solved debugging, apparently ns2 lua want Print(), while I used gmod lua, which is print(). The difference is capital "p".
When HenryJK tells us to put on placeholder in a movieclip, he talks about flash. You need to prepare 1 movieclip for each bitmap you need, apart from the button around it and the thumbnail itself that use that bitmap. You can create a generic movieclip for receiving a bitmap src from lua in your library and attachMovie it to your scene.
The problem is... AS2 smells ###### :)
The most usefull element in a gui in flash is the MovieClip (at least in AS2), and the least practical class you have in the whole language is... the MovieClip !
There is no var myMC = new MovieClip( params ); in AS2. The ONLY class that cannot be instanced with the new command is the MovieClip class (ok, there's also the TextField class but it extends MovieClip, so...). The only way to create an instance of MovieClip is to give one existing MovieClip a child that is a MovieClip with one of the two following methods :
.createEmptyMovieClip( name, depth );
.attachMovie( id, name, depth );
Both might lead you to what you want. If you use the first one, all you'll have is a standard MovieClip with nothing at all in it. You'll have to place a placeholder bitmap in it at runtime and call lua by yourself ton load the binded bitmap. If you use the attachMovie method, then you might tweak that MovieClip a lot more, extend its class, put something in it, even scripts, and all that at the very moment you add it to the scene... which cause a terrible pain : how the heck are we supposed to send values to the constructor ?
Well... AS2 being crap, there IS a solution, but it's ugly :) You have to prepare and specify an Object as the last (optional) parameter of the .attachMovie() call. That object would contain props and values that the constructor might demand.
Say you've done a button that can be red or blue, with a class that extends MovieClip (named "redOrBlueButton"). In its constructor it only needs that very information "red or blue ?". You get the value of the prop "buttonColour" and check whether it is "red" or "blue". Alright. Then what you have to write is :
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->var myInitObject = new Object();
myInitObject.buttonColour = "red";
myContainer.attachMovie( "redOrBlueButton" , "myButton" , 1 , myInitObject );<!--c2--></div><!--ec2-->
... and then your button is red :) Remember when using attachMovie, you need a symbol in your library that's exported for actionscript and that's class is "redOrBlueButton".
Does it make sense to you ?
Also, if I had understood all right, the flash would be something like this (also, please dont go rage on me failing in as2 :P).
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->lua( "SpawnUI_GetSpawnIcons()" ); //Prepares the lua
amount = lua( "SpawnUI_GetIconAmount()" );
for ( i=1 , amount ) do
myContainer.attachMovie( "placeholder" , ""+i , 1); //Do I really need the "initObject"?
replaceBitmap(""+i); //Replace it with spawnicon
end<!--c2--></div><!--ec2-->
Where my current lua code is (remember it is untested due to me lacking a file library):
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->//==============================
//
// sandbox/lua/ui/SpawnUI.lua
//
// Created by Feha
//
//==================================
local dir
/**
* Called by Flash to get the spawnicons.
*/
function SpawnUI_GetSpawnIcons()
/*
dir = file.FindDir("models/*")
Whatever way to get content of a folder
*/
//Loop the content, key is hopefulyl a number, and v would be the path to spawnicon.
for k, v in pairs(dir) do
Client.BindFlashTexture( toString(k), v )
end
end
/**
* Called by Flash to get the amount of spawnicons.
*/
function SpawnUI_GetIconAmount()
return dir:table.count()
end
/**
* Called by Flash to spawn a prop with selected model.
*/
function SpawnUI_SpawnProp(PropModel)
local player = Client.GetLocalPlayer()
// Filter ourself out of the trace so that we don't hit the weapon or the player using it.
local filter = EntityFilterTwo(player, self)
local viewCoords = player:GetCameraViewCoords()
local startPoint = viewCoords.origin
local endPoint = startPoint + viewCoords.zAxis * 50
local trace = Shared.TraceRay(startPoint, endPoint, filter)
//Retrieve trace data
local hitPos = trace.endPoint
//Create prop
local entity = Server.CreateEntity( "prop_dynamic", hitPos )
entity:SetAngles( player:GetAngles() )
entity:SetModel( PropModel )
return entity
end<!--c2--></div><!--ec2-->
EDIT:
And ofcourse I will have to add code to detect if I click on a spawnicon which will clsoe down ui and run lua( "SpawnUI_SpawnProp(" + model + ")" );
Flash seems to dislike infinite loop, so I am not sure how to make it stay at a single frame and run its code over and over. Anyone know how to do that?
Edit: Figured it out, gotoAndPlay(2).
Edit2: Ok, that was not very good either. The scrollbar seems to flash quickly between the pos it has at frames start, and the pos it should have.
Edit3: And I fixed it, apparently there was a built in function :P. startDrag(); I use stop() to make the sliders pos not reset all the time (flicker I described earlyer), as gotoandplay isnt needed with this function.
Now I will just make lua have a demo table of file paths (still no file library), and make my spawn function get the path from there using the number it got from flash (figured that would be better then sending table to flash and letting flash read it and send back to lua). Lets hope it work!
I tried doing like PlayerUI has, and Script.Load() it into the client.lua, but al lthat did was help me find minor errors in my code (1 " to much, other typos), but I still got errors that the flash used nonexisting functions...
Gnight ppl.
You really should check out action script 2 syntax basics, else you won't get far.
And ALWAYS keep in mind you make two completely different systems work together, and one of them is asynchronous (flash). How could you care ? Let's see...
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->lua( "SpawnUI_GetSpawnIcons()" ); //Prepares the lua
amount = lua( "SpawnUI_GetIconAmount()" );
for ( i=1 , amount ) do
myContainer.attachMovie( "placeholder" , ""+i , 1); //Do I really need the "initObject"?
replaceBitmap(""+i); //Replace it with spawnicon
end<!--c2--></div><!--ec2-->
Set aside that syntax that's not really AS2, what makes you think, when you run the second line of your script (amount = ...), that lua command DID finished to compute ? When you call that lua command, it does its job on its side and just don't care what flash gui is doing. THe gui itself don't give a ###### abotu what lua does, it jut sent a call for thatcommand, so what ?
It's ASYNCHRONOUS :) both lua and flash just DON'T KNOW each other. Yeah, that sounds tricky, because it is.
I wasn't wabbling around stupid things when I was saying you had to check some lua command at every frame to communicate between flash and lua. That's the thing :)
No language loves infinte loops, but they do use some really cool stuff in flash that do that particular job : events. And there's a very prticular event that's dispatched at the beginning of every frame flash plays : onEnterFrame. You react on that event with the following script :
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->_root.onEnterFrame = myCallback;
function myCallback()
{
// things to do at every frame
// like updating things on screen
// like communicating with lua in anyway
}<!--c2--></div><!--ec2-->
You can go much nastier that way :
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->_root.onEnterFrame = function() {
// things to do at every frame
}<!--c2--></div><!--ec2-->
That's the shorter (and uglier) way to do it
So your script up there should have been something like that :
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// INIT
lua( "SpawnUI_GetSpawnIcons" ); //Don't need "()", it's just a callback
var amount; //You might want to type your var, but I'm not sure what's the value type lua sends to flash.
var lastAmount;
// do other stuff once and for all
// ON ENTER FRAME
_root.onEnterFrame = update;
// FUNCTIONS
// Main update function, at every frame
function update()
{
// Init vars
amount = Number( lua( "SpawnUI_GetIconAmount" ); ) // Might want to be sure it's a number :)
if ( lastAmount == amount )
{
// Nothing to do
} else {
lastAmount = amount;
updateIcons( amount );
}
}
// updates icons in thumbnails, only if icon amount changed
function updateIcons( iconNumber :Number )
{
var i = 1;
var currentIcon;
for ( i; i > iconNumber; i++ )
{
currentIcon = myContainer.attachMovie( "placeholder" , ""+i , 1+i );
currentIcon.replaceBitmap(""+i); //Replace it with spawnicon
}
}<!--c2--></div><!--ec2-->
It might still mess up if amount returns NaN or undefined. That could happen if lua isn't ready when you call "SpawnUI_GetIconAmount". It might also mess up if icons changed but not their amount. You'll have to write two lua commands :
- one that returns true if changes occurred about icons.
- another that tells lua "it's okay, I took care of those icons" so that the next time you call the top one, it will return false... until there's some news.
You also might want to put everything I wrote in the update function into a single function that "checks on updates about icons", say "function checkIcons( lastAmount );" or something...
And to answer your comment, no, you only need initObject when you have to give variables as parameters to the constructor of any class that extends MovieClip while using attachMovie method. So in most of cases, you won't need it.
... ah and Depth is very important. Flash draws things on screen following a certain order. In AS2 that order is sort by depth. Every visual element is, or controlled by, a MovieClip. And every MovieClip that exists is a child of another MovieClip. Every flash comes with a basic MovieClip that cannot be deleted and exists before anything else visual : the ROOT ! aka _root or _level0. Not to be confused with Stage, that's the "static" class managing generic options about how your flash is displayed by its player (NS2's gameswf, in our case).
So, depth. Every MovieClip knows alarge array of depth levels, from 1 to... 65334, I guess. If you pick any of those, you can put something in it. Something on depth N will display on top of something on N-1, but behind something on N+1. And every single MovieClip has its own depth levels. Every child displays according to the level of its parent. So if ParentA is under Parent B, every child of ParentA will display under every child of ParentB, whatever depth they're located inside ParentA.
Warning : you can only put ONE element in each depth level. An "efficient" way to remove something is to overwrite its depth level.
There's more to know about it, but keep cool. You should only need that much info for now.
... and read that Flash manual !! :)
So far my flash script got dynamic adding of movieclips (I just give it number I need), assing an onpress functionto the movieclip to call a lua function with the id, aswell as a slider I plan on making able to move the movieclips when you drag it, and not just be pure graphics.
Also, that was just an example script of how I figured it would work, the finished script IS as2, and works if played in firefox or flash proffessional. Just not in ns2.
Usefull to know that even though flash can call lua functions, it wont wait for the lua function to finish (if I understood what you said right). How exactly do you retrieve a value from the lua function then (the part where lua prepares a table can be done in lua before I call flash), if the flash continues before the function returned the value?
However, my problem is nothing in the flash, and nothing in if the functino get time to finish. The problem is that when flash call the functions, ns2 console prints that said function does not exist.
I skipped coding this today though, and might be busy whole week with school. I can paste both the flash and lua code here though, incase you still believe the problem is in it. Myself I believe its something else though, maybe how I start the flash, or that I need to do Script.Load() somewhere.
Gnight ;)
Note you shouldn't test it on flashplayer. Gameswf behaves realy differently than flashplayer.
My current Lua
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->//=================================
//
// sandbox/lua/ui/SpawnUI.lua
//
// Created by Feha
//
//=================================
dir = {}
iconAmount = 0
function SpawnUI_Startup()
//Prepare lua
SpawnUI_GetSpawnIcons()
//Enable mouse
Client.SetMouseVisible(true)
Client.SetMouseCaptured(false)
//Start flash
Shared.SetMenu("ui/SpawnUI.swf")
end
/**
* Called by Flash to get the spawnicons.
*/
function SpawnUI_GetSpawnIcons()
/*
dir = file.FindDir("models/*")
Whatever way to get content of a folder
*/
//table for debugging purposes
dir = {
"models/props/refinerymining_cart.model",
"models/props/refinerymining_computer_01.model",
"models/props/refinerymining_conveyor_64.model",
"models/misc/target/target.model"
}
/*Commented away as I dont know what filetype this thing likes.
//Loop the content, key is hopefully a number, and v would be the path to spawnicon.
for k, v in pairs(dir) do
Client.BindFlashTexture( Shared.GetString(k-1), v )
end
*/
//Apparently flash does not wait for lua, so its better to store this as a variable
iconAmount = table.count(dir)-1
end
/**
* Called by Flash to get the amount of spawnicons.
*/
function SpawnUI_GetIconAmount()
return iconAmount
end
/**
* Called by Flash to spawn a prop with selected model.
*/
function SpawnUI_SpawnProp(index)
local player = Client.GetLocalPlayer()
local PropModel = dir[index+1]
// Filter ourself out of the trace so that we don't hit the weapon or the player using it.
local filter = EntityFilterTwo(player, self)
local viewCoords = player:GetCameraViewCoords()
local startPoint = viewCoords.origin
local endPoint = startPoint + viewCoords.zAxis * 50
local trace = Shared.TraceRay(startPoint, endPoint, filter)
//Retrieve trace data
local hitPos = trace.endPoint
//Create prop
local entity = Server.CreateEntity( "prop_dynamic", hitPos )
entity:SetAngles( player:GetAngles() )
entity:SetModel( PropModel )
//Exit UI
SpawnUI_Exit()
return entity
end
function SpawnUI_Exit()
Client.SetMouseVisible(false)
Client.SetMouseCaptured(true)
Shared.SetMenu("")
end<!--c2--></div><!--ec2-->
Will add my current flash here, just gonna edit post via my laptop.
Edit:
My current flash
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->//The spawnicons
xOffset = 25;
yOffset = 25;
boxPerRow = 3;
amount = lua( "SpawnUI_GetIconAmount()" );
for ( i = 0; i < amount; i++ ) {
//numerical id
id = i;
//Add a placeholder
placeholder = _root.attachMovie("Icon",id,i);
//Position the thumbnail
row = Math.floor(i/boxPerRow);
column = i-(row*boxPerRow);
posX = xOffset + column * (xOffset + placeholder._width);
posY = yOffset + row * (yOffset + placeholder._height);
placeholder._x = posX;
placeholder._y = posY;
//OnPress
placeholder.onPress = function() {
lua( "SpawnUI_SpawnProp(" + this._name + ")" );
}
//Replace bitmap with spawnicon
replaceBitmap(id);
}
//Scrollbar
scrollBar.onPress = function() {
startDrag("scrollBall", true, 465, 30, 465, 370);
}
scrollBar.onRelease = function() {
stopDrag()
}
scrollBar.onReleaseOutside = function() {
stopDrag()
}
stop();<!--c2--></div><!--ec2-->
NB : don't know anything about lua, won't help you there :)
EDIT: I heard something about flash 6 from you earlyer tho, and I just noticed I got flash 9. Wonder if that is my problem, going to try changing.
EDIT2: Did not help at all.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->[icon] Attachments [right aligned] Manage Current Attachments (0)
[icon] Site Message
(Message will auto close in 2 seconds)
[right aligned] [white bar]
[icon] Attachment system ready<!--QuoteEnd--></div><!--QuoteEEnd-->
lua( "SpawnUI_GetIconAmount" );
instead of
lua( "SpawnUI_GetIconAmount()" );
But I guess I try without ().