Random lua/GC questions

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
User avatar
Anakin
Master of the Force
Master of the Force
Posts: 4817
Joined: Sat Sep 19, 2009 11:37 am
Projects :: RC Side Mod - Remastered - SWBF3 Legacy
Location: Mos Espa (germany)

Random lua/GC questions

Post by Anakin »

Hi,

i just thought it is time to start a new big project i have no knowledge about :mrgreen:

So i want to make a new custom GC, but it looks like it is not working.

Actually i just took the example codes, changed a little bit here and a little bit there, but it never worked. As you can see in the error log the script doesn't know that i pressed the right button. But i pressed on the button that says Republic Commando. I hope someone of you can help me.
An other question is there a more detailed tutorial on how to add maps/planets to the gc, and how to set up the mission you are playing on these planets? How to set up own fleet icons, how to change the units you can buy, the bonus things,...??


custom_gc_5.lua
Hidden/Spoiler:
[code]--This is the main setup script for a custom Galactic Conquest
print("custom_gc_5: RCM GC Entered")

-------------------------------------------------------------------------------
-- Those 7 steps are in this section
-------------------------------------------------------------------------------
--Modders, for basic custom Galactic Conquest support
-- you only need to change the variables in this section.
-- If you want to do advanced things, you will need to
-- learn how the real game does it.
-- If you need to change something else in the game, it is
-- best to 'take control' of the function as done
-- a few times below this section. This allows you to
-- change parts of the shell without replacing shell.lvl.

--To use this script in your own custom Galactic Conquest,
-- 1) you need to search/replace: cgc1/cgc#
-- 2) you need to search/replace: gc_1/cg_#
-- where '#' is the number of this custom Galactic Conquest

-- 3) this button tag must be unique for each button in the Galactic Conquest screen
local gcTag = "RC"

-- 4) this is the string your Galactic Conquest button will use
-- if the game cannot find the a localization version of the string,
-- it will directly display the text on the button
local gcString = "Republic Commando" --"mods.custom_gc.tht.name"

-- 5) load any other scripts from your custom_gc_1.lvl
ScriptCB_DoFile("ifs_freeform_init_rc")
ScriptCB_DoFile("ifs_freeform_start_rc")

-- 6) this is your script that starts your Galactic Conquest game
local start_gc = ifs_freeform_start_rc

-- 7) read in any strings you need
--ReadDataFile("..\\..\\addon\\XXX\\core.lvl")

-------------------------------------------------------------------------------
-- The end of the 7 step section
-------------------------------------------------------------------------------

--add a button to the shell for our custom Galactic Conquest
if custom_GetGCButtonList then
print("custom_gc_5: Taking control of custom_GetGCButtonList()...")

--check for possible loading errors
if cgc5_custom_GetGCButtonList then
print("custom_gc_5: Warning: Someone else is using our cgc5_custom_GetGCButtonList variable!")
print("custom_gc_5: Exited")
return
end

--backup the current custom_GetGCButtonList function
cgc5_custom_GetGCButtonList = custom_GetGCButtonList

--this is our new custom_GetGCButtonList function
custom_GetGCButtonList = function()
print("custom_gc_5: custom_GetGCButtonList(): Entered")

--get the button table from the real function
local list = cgc5_custom_GetGCButtonList()

--add in the button for our Galactic Conqust
local ourButton = { tag = gcTag, string = gcString, }
table.insert( list, 1, ourButton )

print("custom_gc_5: custom_GetGCButtonList(): Exited")
return list
end
else
print("custom_gc_5: Warning: No custom_GetGCButtonList() to take over")
print("custom_gc_5: Exited")
return
end

--Note: if you want your Galactic Conquest to only be visible at certain times (like when some other GC is completed), you will need to take over the ifs_sp_campaign_fnUpdateButtonVis() and/or ifs_sp_gc_fnUpdateButtonVis() functions (like you did with custom_GetGCButtonList()). Both of these functions can be found in Common\scripts\PC\ifs_sp_campaign.lua

--listen for when our Galactic Conquest button is clicked
if custom_PressedGCButton then
print("custom_gc_5: Taking control of custom_PressedGCButton()...")

--check for possible loading errors
if cgc5_custom_PressedGCButton then
print("custom_gc_5: Warning: Someone else is using our cgc5_custom_PressedGCButton variable!")
print("custom_gc_5: Exited")
return
end

--backup the current custom_GetGCButtonList function
cgc5_custom_PressedGCButton = custom_PressedGCButton

--this is our new custom_GetGCButtonList function
custom_PressedGCButton = function( tag )
print("custom_gc_5: custom_PressedGCButton(): Entered")

--not our conquest, so let the game process it normally
if tag ~= gcTag then
print("looks like it's not me")
return cgc5_custom_PressedGCButton()
end

print("i'm here but i don't know what i'm doing")

--it is our Galactic Conquest button, so get our game going
start_gc(ifs_freeform_main)

print("custom_gc_5: custom_PressedGCButton(): Exited")
return true
end
else
print("custom_gc_5: Warning: No custom_PressedGCButton() to take over")
print("custom_gc_5: Exited")
return
end

print("custom_gc_5: Exited")
[/code]
error log:
Hidden/Spoiler:
[code]Opened logfile BFront2.log 2015-01-24 1438
shell_interface: Entered
shell_interface: gPlatformStr, gOnlineServiceStr, gLangStr, gLangEnum: PC GameSpy german 4
ifs_era_handler - Entered
ifs_era_handler - Exited
shell_interface: No custom_gc_0.lvl
shell_interface: No custom_gc_1.lvl
shell_interface: No custom_gc_2.lvl
shell_interface: No custom_gc_3.lvl
shell_interface: No custom_gc_4.lvl
shell_interface: Found custom_gc_5.lvl
custom_gc_5: RCM GC Entered
ifs_freeform_init_rc.lua
ifs_freeform_start_rc.lua
custom_gc_5: Taking control of custom_GetGCButtonList()...
custom_gc_5: Taking control of custom_PressedGCButton()...
custom_gc_5: Exited
shell_interface: No custom_gc_6.lvl
shell_interface: No custom_gc_7.lvl
shell_interface: No custom_gc_8.lvl
shell_interface: No custom_gc_9.lvl
shell_interface: Found custom_gc_10.lvl
custom_gc_10: Entered
custom_gc_10: Found custom_gc_11.lvl
custom_gc_11: Entered
ifs_freeform_init_dt.lua
ifs_freeform_start_dt.lua
custom_gc_11: Taking control of custom_GetGCButtonList()...
custom_gc_11: Taking control of custom_PressedGCButton()...
custom_gc_11: Exited
custom_gc_10: No custom_gc_12.lvl. Will stop searching for any more cGC scripts.
custom_gc_10: Exited
custom_EraButtonList(): Finished building era button table Known eras buttons: 28
custom_GetGMapEras(): Finished building era table Known eras: 28
custom_GetGMapModes(): Finished building game mode table Known Modes: 39
custom_GetMPGameModeList(): Finished building game mode list table List Length: 40
custom_SetMovieLocation()
custom_gc_11: custom_GetGCButtonList(): Entered
custom_gc_5: custom_GetGCButtonList(): Entered
custom_GetGCButtonList()
custom_gc_5: custom_GetGCButtonList(): Exited
custom_gc_11: custom_GetGCButtonList(): Exited
custom_SetMovieLocation()
custom_GetFreeformBattleModeList(): Finished building freeform battle mode list Known Modes: 39
ingame stream movies\crawlgr.mvs
shell_interface: Opening movie: movies\shellgr.mvs
shell_interface: Leaving
Mission Checker: Entered addme
Mission Checker: addme: Now listening in on AddDownloadableContent() calls
Mission Checker: Exited addme
Found ..\..\addon\BDT\data\_LVL_PC\SIDE\lead.lvl. Adding ETR's extra Dark Times missions
Cannot find ..\..\addon\BF1\data\_LVL_PC\SIDE\sen.lvl. Skipping ETR's extra Dark Times + Conversion Pack missions
prev = none iLastPage = nil
prev = texture iLastPage = 2
prev = texture iLastPage = 3
ifs_legal.Exit

Message Severity: 2
C:\Battlefront2\main\Battlefront2\Source\GameMovie.cpp(399)
Unable to find open movie segment shell_main

ifs_saveop_DoOps LoadFileList
ifs_saveop_DoOps LoadFileList
ifs_saveop_DoOps LoadProfile
ifs_saveop_DoOps LoadProfile
ifs_sp_campaign: Input_Accept(): Entered: _tab_gc
custom_gc_11: custom_PressedGCButton(): Entered
custom_gc_5: custom_PressedGCButton(): Entered
looks like it's not me
custom_PressedGCButton()
[/code]
==EDIT==

just an idea i had ;)
print(tag)
print(gcTag)

result:
nil
RC

so it looks like the tag isn't setup right for the button. Any Idea why??

==EDIT2==

An other question: How can i check if there are special files somewhere in the addon directory??
(I saw that dt is looking for ETR and made an output like i found ... so i add bla bla bla.)
I'd like to search for my custom era mod before i add the button to the gc list. So is there a function, how to check this??
Last edited by Anakin on Wed Jan 28, 2015 1:03 pm, edited 1 time in total.
Marth8880
Resistance Leader
Posts: 5042
Joined: Tue Feb 09, 2010 8:43 pm
Projects :: DI2 + Psychosis
Games I'm Playing :: Silent Hill 2
xbox live or psn: Marth8880
Location: Edinburgh, UK
Contact:

Re: Custom GC tag not working

Post by Marth8880 »

Anakin wrote:An other question: How can i check if there are special files somewhere in the addon directory??
(I saw that dt is looking for ETR and made an output like i found ... so i add bla bla bla.)
I'd like to search for my custom era mod before i add the button to the gc list. So is there a function, how to check this??

Code: Select all

if ScriptCB_IsFileExist("filedirectory") == 1 then
    ...
end
'filedirectory' should be formatted the same way as ReadDataFile.
User avatar
Anakin
Master of the Force
Master of the Force
Posts: 4817
Joined: Sat Sep 19, 2009 11:37 am
Projects :: RC Side Mod - Remastered - SWBF3 Legacy
Location: Mos Espa (germany)

Re: Custom GC tag not working

Post by Anakin »

Thank you. Do you know where the executable path from the gc custom script is??

Someone an idea why "tag" is "nil" instead of "RC"??


==EDIT==

Ok i got it working now. The problem was custom_gc_11.lvl
So is there a way to make my button/custom GC compatible with the other one??

==EDIT2==

Maybe you can have a look at this too:
Hidden/Spoiler:
[code]this.planetDestination = {
["cor"] = { "myg", "star17", "star18", "star20" },
["dag"] = { "star05", "star06", "nab" },
["end_star"] = { "star01", "star19", "star20" },
["fel"] = { "star13", "yav", "star14" },
["geo"] = { "star07", "star08", "star09", "star10", "tat" },
["hot"] = { "star01", "star02", "star03" },
["kas"] = { "star12", "star13", "star15", "star17" },
["kam"] = { "star11", "star12", "star13", "tat" },
["mus"] = { "star02", "star04", "star05" },
["myg"] = { "star15", "star16", "star17", "star18", "cor" },
["nab"] = { "star07", "star12", "star17", "dag" },
["pol"] = { "star02", "star03", "star04" },
["tat"] = { "star09", "star10", "star11", "geo", "kam" },
["uta"] = { "star04", "star05", "star06" },
["yav"] = { "star14", "star15", "star16", "fel" },
["star01"] = { "hot", "end_star", "star02" },
["star02"] = { "star01", "mus", "star20", "pol", "hot" },
["star03"] = { "hot", "pol" },
["star04"] = { "mus", "pol", "uta" },
["star05"] = { "mus", "uta", "dag" },
["star06"] = { "uta", "dag", "star07", "star08" },
["star07"] = { "nab", "geo", "star06" },
["star08"] = { "star06", "geo" },
["star09"] = { "tat", "geo" },
["star10"] = { "star12", "geo", "tat" },
["star11"] = { "tat", "kam" },
["star12"] = { "star10", "kam", "nab", "kas" },
["star13"] = { "kas", "kam", "fel" },
["star14"] = { "fel", "yav" },
["star15"] = { "kas", "yav", "myg" },
["star16"] = { "yav", "myg" },
["star17"] = { "cor", "myg", "kas", "nab" },
["star18"] = { "cor", "myg", "star19" },
["star19"] = { "end_star", "star18" },
["star20"] = { "star02", "cor", "end_star" }
}[/code]
there is no connection from and to polis massa. is there maybe a limit of conections??
hunpeter12
Command Sergeant Major
Command Sergeant Major
Posts: 260
Joined: Mon Apr 18, 2011 2:53 pm
Projects :: Underground City The Complex [WIP]
Games I'm Playing :: SWBF2

Re: Custom GC tag not working

Post by hunpeter12 »

Jaspo wrote:New one I discovered making Extended Galactic Conquest, unless there's a memory pool that I don't know about:
Only 50 lanes can be drawn between planets in galactic conquest. More can be scripted, but no more than 50 will appear.
User avatar
Anakin
Master of the Force
Master of the Force
Posts: 4817
Joined: Sat Sep 19, 2009 11:37 am
Projects :: RC Side Mod - Remastered - SWBF3 Legacy
Location: Mos Espa (germany)

Re: Random lua/GC questions

Post by Anakin »

Thank you. Now i set up my custom galactic conquest, but there are still things left. I hope you can help me.

1. How to change the small fleet prop? i haven't found it in any folder
2. How to handle bonus
3. How to add my own units to the unit menu


About 2:
I found the ifs_freeform_purchase_tech.lua. I only want to disable the hero bonus, because there is no hero for my sides. If i'm right i only have to modify this part to have a false at the last entries
Hidden/Spoiler:
[code]
ifs_purchase_tech_cards = {
[1] = {
true,
true,
true,
true,
true,
true,
true,
true,
true,
true
},
[2] = {
true,
true,
true,
true,
true,
true,
true,
true,
true,
true
}
}
[/code]
But how should i do? do i need to include the whole script in my custom gc lvl and only change this small part, or is there an easier way, maybe just at the part above to my custom ifs_freeform_init_rc.lua?? I don't know how lua is working, so maybe someone can point me the right way.

About 3:
There are two problems. First i want my own sides displayed in the list. I think i need to modify the ifs_freeform_purchase_unit.lua. to load my own rep.shell file and so the units are displayed. So the only question here is the same as for 2. How to make the changes (include the modifyed stock lua to my custom gc file, or make a new custom file, or only add the changed functions to my custom init lua?)
The second problem is that i need to add some more troopers, because i don't have only the 6 stock units, i have right 8. And the additinal two are not a pilot and marine class, they are custom. So how can i do that.
hunpeter12
Command Sergeant Major
Command Sergeant Major
Posts: 260
Joined: Mon Apr 18, 2011 2:53 pm
Projects :: Underground City The Complex [WIP]
Games I'm Playing :: SWBF2

Re: Random lua/GC questions

Post by hunpeter12 »

I have absolutely no knowledge about making custom a galactic conquest, sorry. I just remembered there was a hardcoded limitation concerning GC connections.
BTW here is what you an and can't do in a custom GC.

For the last issue: You can add them as the marine and pilot class couldn't you? As long as you change everything it works the same as AddUnitClass. I believe Fierfek's tutorial (if you know it) covers this type of unit adding.
Don't take anything I say as true though. I'm not really good at BF2 modding. :cry:
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: Custom GC tag not working

Post by [RDH]Zerted »

Anakin wrote:Someone an idea why "tag" is "nil" instead of "RC"??
Because there's a bug in the cGC template code :cry: I'll work on a generic fix for everyone.
How to make the changes (include the modifyed stock lua to my custom gc file, or make a new custom file, or only add the changed functions to my custom init lua?)
One of those. Pick whichever one you think is easier and won't hamper you in the future. For example, if there's another mod that changes part of the AI but you decide to replace the full stock lua with a renamed version of your own, then that mod won't be compatible with your mod. I try to make the smallest change possible, but that's sometimes very difficult.

Trace through the code and function calls from your script until whatever it is you want to change is defined (which might actually be before your script is loaded) then along to where it's actually used. If you don't replace the entire file, then you need to modify it anywhere between when it's defined and when it's used. That could be as simple as ifs_purchase_tech_cards[1][10] = false or injecting code before/after a function call.

By inject code I mean like:

Code: Select all

if fn then
    myFn = fn
    fn = function(...) --"..." is actual code and not a placeholder
        local returnValue = myFn(unpack(arg))
        --do my custom changes to something myFn (originally the fn function) defined
    return returnValue
end
User avatar
Anakin
Master of the Force
Master of the Force
Posts: 4817
Joined: Sat Sep 19, 2009 11:37 am
Projects :: RC Side Mod - Remastered - SWBF3 Legacy
Location: Mos Espa (germany)

Re: Random lua/GC questions

Post by Anakin »

What do you mean with unpack(arg)??




I have some more question about the lua basics.
There are function definitions:

Code: Select all

function myFunction(parameter1, parameter2)
    print("you gave me these parameters:")
    print(parameter1)
    print(parameter2)
end
I can call this function that way:

Code: Select all

myFunction("Gametoast", "SWBFII")
This will cause these lines in the log:
you gave me these parameters:
Gametoast
SWBFII
Question:
How can i define return values and how can i intercept them??

Ok than there are these

Code: Select all

ScriptCB_DoFile("my_lua_file_name")
I know c/c++, and i think this is simular to #include, but i don't know how it exactly works.

Question:
Does this run my lua script from the beginning to the end, or does this only load the function from the script, or does this run everything that is not under a function and loads the function??

Next i saw often these lines

Code: Select all

variable = function(parameters)
I found it in the custom_gc_#.lua script, too:

Code: Select all

custom_PressedGCButton = function( tag )
	    print("custom_gc_5: custom_PressedGCButton(): Entered")
	    
	    --not our conquest, so let the game process it normally
	    if tag ~= gcTag then
			print("looks like it's not me")
		    return cgc5_custom_PressedGCButton()
	    end
	    
	    --it is our Galactic Conquest button, so get our game going
	    start_gc(ifs_freeform_main)
	    
	    print("custom_gc_5: custom_PressedGCButton(): Exited")
	    return true
	end

Question:
What does this mean i realy have no idea.

In c++ there are global and local variables. global variables can be used everywhere, locals only in the function/class,... where it is defined. When there are one global and one local variable with the same name, the local is used.
Question:
Is there something simular for lua??

In c++ you can give a function the parameter in two ways:
1. directly as a copy of your variable. So if the function change something, and goes back to the calling function, the varaible has the same value as before

Code: Select all

#include <iostream>

void myFunc(int a)
{
    a = 0;
}

int main(int argc, char** argv)
{
    int a = 5;
    std::cout << a << std::endl;
    myFunc(a)
    std::cout << a << std::endl;
    return 0;
}
The resutl will look like this:
5
5
2. as pointer. You give the function just the adress of the variable. everything you change in the function will affect your variable in the calling function, too.

Code: Select all

#include <iostream>

void myFunc(int* a)
{
    a* = 0;
}

int main(int argc, char** argv)
{
    int a = 5;
    std::cout << a << std::endl;
    myFunc(&a)
    std::cout << a << std::endl;
    return 0;
}
The resutl will look like this:
5
0
Question
How does it work in lua?? does the changes did in the function affect my variable in the main function (calling function)
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: Random lua/GC questions

Post by [RDH]Zerted »

The unpack function expands a list as if it were a bunch of separate items. You could have done myFunction(unpack({"Gametoast", "SWBFII"})) which is different from myFunction({"Gametoast", "SWBFII"}, s2nd-param-missing). "..." and unpack() are commonly used for variable argument lengths. It's a way to grab all the function parameters without know how many there are. See documentation on Lua for more info. I use them when injecting code into a function because you never know if someone else also 'took over' that function and added additional parameters. You don't want to actually cut off someone else's parameters. The two bugs in v1.3 were due to forgetting to return the value of an injected function (which stopped Leia from spawning) and from cutting off a parameter to a deeper inject function (the issue with custom_PressedGCButton()). So I highly recommend everyone doing any type of code injection to always use ... and unpack even if you think you know the proper function parameters. Another modder in the past or future might change them and then your non-unpack code will break it.
How can i define return values and how can i intercept them??
See exactly how cgc5_custom_PressedGCButton became the original custom_PressedGCButton and your modified function is now the new custom_PressedGCButton which still directs some calls (and returns resulting return value) to the original custom_PressedGCButton function (which was renamed to cgc5_custom_PressedGCButton). That is what I mean when I say injecting code into a function. Technically your code isn't in the function, but surrounds it. I don't know the proper technical term for it. It's like aspect oriented programming, but I expect most modders won't have a clue what that is. It is the decorator design pattern... Hmm, maybe I should start calling it a wrapper. A.k.a putting a wrapping around a function. Does that term make more sense to people?

Yes, ScriptCB_DoFile is like an include. Lua has at least two different 'include' methods. One way turns the entire into a function and you can call that function as many times as you one. The other way runs the file just as if it were embedded at that location (I don't think it has access to locally scoped variables, but I never check that). Because it's a ScriptCB_ function and not a normal Lua include function, I don't know what the SWBF2 devs changed. If you can put a return statement as the first line of a file you include, then it's safe to assume ScriptCB_DoFile() loads the file into a function then calls that function. If not, then assume it runs the file like a script: one line after the next (a return could work in this context too). But it's not too important exactly how the files get included.

Functions are stored in variables just like everything else in Lua. function myFun() ........ end is shorthand for myFun = function() ......... end. I tend to use the varName = function format when I'm changing an existing function or creating local functions. I use function varName when defining a function I don't expect to be replaced (but it still could be).

In Lua, basically everything is global (put in table _G) expect when you specify the local keyword. Since SWBF2 reloads everything on each map switch, it doesn't matter that most of the modders never use local even though they should almost always be using it.

Expect for primitive types (nil, boolean, number, string, light userdata), everything in Lua is pass by reference. Lua doesn't duplicate the tables and functions you move around unless you specifically duplicate them. If you change what a variable is pointing to inside a function (a ={'new table'}) it doesn't change it outside the function. If you change the contents/field of what a variable is pointing to (a[1]='new table') then it changes it outside the function.

Since you know C++, you probably know enough programming to just read the Lua documentation...

*I did not proofread this post.
User avatar
Anakin
Master of the Force
Master of the Force
Posts: 4817
Joined: Sat Sep 19, 2009 11:37 am
Projects :: RC Side Mod - Remastered - SWBF3 Legacy
Location: Mos Espa (germany)

Re: Random lua/GC questions

Post by Anakin »

[RDH]Zerted wrote:[...]
How can i define return values and how can i intercept them??
See exactly how cgc5_custom_PressedGCButton became the original custom_PressedGCButton and your modified function is now the new custom_PressedGCButton which still directs some calls (and returns resulting return value) to the original custom_PressedGCButton function (which was renamed to cgc5_custom_PressedGCButton). That is what I mean when I say injecting code into a function. Technically your code isn't in the function, but surrounds it. I don't know the proper technical term for it. It's like aspect oriented programming, but I expect most modders won't have a clue what that is. It is the decorator design pattern... Hmm, maybe I should start calling it a wrapper. A.k.a putting a wrapping around a function. Does that term make more sense to people?
[...]
Ah ok i understand. Sounds a bit like inheritance for me. So let's take your example with the wrapping. I think it's a good example.
It would look a bit like that:
((stock function) my function)
So let's say the stock function generates an button List and returns it. And i'm generating in my function an button list, too with the same name and returns it. Which variable will be used as return?? Of cause in best case i'd get the stock variable and modify it in my function, but which return is stronger(?)? Will be started with the stock function and my function will overwrite it?? So the wrapper will be opend from inside to outside, or will it be the other way the stock function will overwrite my function, the wrapper will be opend from outside to inside.

[RDH]Zerted wrote: Yes, ScriptCB_DoFile is like an include. Lua has at least two different 'include' methods. One way turns the entire into a function and you can call that function as many times as you one. The other way runs the file just as if it were embedded at that location (I don't think it has access to locally scoped variables, but I never check that). Because it's a ScriptCB_ function and not a normal Lua include function, I don't know what the SWBF2 devs changed. If you can put a return statement as the first line of a file you include, then it's safe to assume ScriptCB_DoFile() loads the file into a function then calls that function. If not, then assume it runs the file like a script: one line after the next (a return could work in this context too). But it's not too important exactly how the files get included.
What is the other include called??
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: Random lua/GC questions

Post by [RDH]Zerted »

Technically you can't put your function after the stock one because you can't modify the stock function to call your function. One return doesn't overpower the other. Both functions have to return (assuming both are called). Trace through the code line by line to see which one returns when. Examples:

This example injects code 'before' the original stock() function.

Code: Select all

originalStock = stock
stock = function(tag, ...)
    if tag == 'myButton' then
        changeSomeSettings()
        runMyMap()
        return --originalStock is never called because we handled this button that we added.  stock() ends here.  There's no reason to call the original stock function because we know it won't do anything with this tag.  We did everything.
    end

    --tag wasn't the button we were looking for, so let the original stock() function handle it like normal.  Whatever the original stock() function returns we will also return.  This is the same as doing: local var = fn(); return var;  We're returning the return value from originalStock()
    return originalStock(tag, unpack(arg))
end
This example injects code 'after' the original stock() function.

Code: Select all

originalStock = stock
stock = function(characters, ...)
    local selectedMap = originalStock(characters, unpack(arg))  --this calls the original stock() function and stores its return value in the variable selectedPlayer.

    --force players to always select the first map in the mission sequence until it has been completed
    if not missionSequence[1].completed then
        return missionSequence[1].name --our new stock() ends here and returns its 'own' return value
    end
    
    return selectedMap  --returns the results of the original stock() function, because we had no reason to change those results
end
You can also inject code both before and after, but normally you only need to do it one way. Do it before if you want to catch something before the original function see it. Do it after when you need to change the result of the original function, like when sometimes modifying IFScreens. You need the original IFScreen data structures to exist before you can start modifying them.


We don't use Lua's normal import functions so they don't matter. http://www.lua.org/pil/8.html
Post Reply