[TOTPP] Prof. Garfield's Lua Code Thread

Code:
-- gen.limitedExecutions(key,maxTimes,limitedFunction)--> void
-- if the value at key is less than maxTimes, limitedFunction will execute,
-- and the value at key will increment by 1
-- Otherwise, don't execute limitedFunction
-- Note: limitedFunction()-->void
function gen.limitedExecutions(key,maxTimes,limitedFunction)
    genStateTable.limitedExecutions[key] = genStateTable.limitedExecutions[key] or 0
    if genStateTable.limitedExecutions[key] < maxTimes then
        genStateTable.limitedExecutions[key] = genStateTable.limitedExecutions[key]+1
        limitedFunction()
    end
end

-- gen.justOnce(key,limitedFunction) --> void
-- wrapper for gen.limitedExecutions with maxTimes being 1
function gen.justOnce(key,limitedFunction)
    gen.limitedExecutions(key,1,limitedFunction)
end

Seems the error keeps going back to these lines from GenLibrary.
 
1687711667486.png
[/URL]
This error is caused because of a mistake I made in triggerEvents.lua a long time ago. The modern version of the Lua Template does not have this particular file.
Change these lines (starting at line 12)
Code:
--When designing with lua using this template, you're essentially "weaving a web" between different modules.
--Any given lua file that references any other needs to have the connection linked.  You do that with the 
--following lines:
local legacy = require("legacyEventEngine")
local delayedAction = require("delayedAction") 
local object = require("object")
local func = require("functions")
local civlua = require("civluaModified")
local param = require("parameters")
local gen = require("generalLibrary")
local civlua = require("civluaModified")
local flag = require("flag")
local text = require("text")
local diplomacy = require("diplomacy")
local delayedAction = require("delayedAction")
local triggerEvents = {}

to
Code:
--When designing with lua using this template, you're essentially "weaving a web" between different modules.
--Any given lua file that references any other needs to have the connection linked.  You do that with the 
--following lines:
local legacy = require("legacyEventEngine")
local delay = require("delayedAction") 
local object = require("object")
local func = require("functions")
local civlua = require("civluaModified")
local param = require("parameters")
local gen = require("generalLibrary")
local civlua = require("civluaModified")
local flag = require("flag")
local text = require("text")
local diplomacy = require("diplomacy")

local triggerEvents = {}

Exact changes:
line 16:
Code:
local delayedAction = require("delayedAction")
becomes
Code:
local delay = require("delayedAction")
line 26 (a mistaken duplicate):
Code:
local delayedAction = require("delayedAction")
is deleted.

Explanation of your first bug shortly.
 
@Prof. Garfield
@JPetroski
Hello, guys!
Been making strides with overlords max, but hit a little bug - !
The problem is that your event isn't part of an execution point (I make no guarantee that this link will stay good for very long -- I've been re-working this website).

The idea of Lua is that you register functions that will be called during an appropriate execution point, in order to do things. Here's the "code roadmap":

1. Choose to load a game.
2. The game executes the code in events.lua and all required files. The goal is to build all the functions to be registered to execution points, and to register them. As part of this, any other "helper functions" and data tables must also be built.
3. Perform the Game Loaded execution point. In this section, the state table is re-created and a whole bunch of files (including the general library) "link" their state to the state table.
4. Perform the Scenario Loaded execution point.
5. Start playing the game.
6. Execute functions registered to execution points as appropriate.

Basically, this code (starting at line 1424 of your triggerEvents.lua)
Code:
--If the British civ researches "African Invasion", the event will spawn British Empire forces to attack North Africa...
if civ.hasTech(object.tBritish, object.aBritAfricanInvasion) and object.tBritish.isHuman == false then 
gen.justOnce("Britain Attacks Africa",function()
    --British Empire North African Forces
    civlua.createUnit(object.uInfantry, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=30, randomize=true, veteran=true})
    civlua.createUnit(object.uAnzacs, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uCanadianArmy, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uQF25Pdr, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=20, randomize=true, veteran=true})
    civlua.createUnit(object.uMatildaII, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uHurricane, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uLiner, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=2, randomize=false, veteran=true})
    civlua.createUnit(object.uDestroyer, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=4, randomize=false, veteran=true})
    civlua.createUnit(object.uBattleship, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=2, randomize=false, veteran=true})
    civlua.createUnit(object.uAircraftCarrier, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=1, randomize=false, veteran=true})
    civ.ui.text("Axis commanders radio Rome and Berlin, warning that British forces are landing in North Africa...")
    civ.playSound("ALLIED.wav")
    civ.ui.text("The British Empire lands in Africa! With the Soviets urging for a new theatre in the West, Commonwealth forces launch an invasion of North Africa...")
    end)
end
Is being executed in step 2 above, while it should be executed in step 6. This particular error happens because justOnce doesn't work until after step 3. However, the current state of the code means that the British wouldn't invade North Africa until after a save and load happened. If you want the code to happen the same turn they discover the tech, you would move the above code into this section of code:

Code:
function triggerEvents.afterProduction(turn,tribe)
    context[getContext()]["afterProduction"](turn,tribe)
    universal["afterProduction"](turn,tribe)
    delay.doAfterProduction(turn,tribe)

end

To get
Code:
function triggerEvents.afterProduction(turn,tribe)
    context[getContext()]["afterProduction"](turn,tribe)
    universal["afterProduction"](turn,tribe)
    delay.doAfterProduction(turn,tribe)

--If the British civ researches "African Invasion", the event will spawn British Empire forces to attack North Africa...
if civ.hasTech(object.tBritish, object.aBritAfricanInvasion) and object.tBritish.isHuman == false then 
gen.justOnce("Britain Attacks Africa",function()
    --British Empire North African Forces
    civlua.createUnit(object.uInfantry, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=30, randomize=true, veteran=true})
    civlua.createUnit(object.uAnzacs, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uCanadianArmy, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uQF25Pdr, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=20, randomize=true, veteran=true})
    civlua.createUnit(object.uMatildaII, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uHurricane, object.tBritish, {{283,67,0},{286,68,0},{2,66,0}}, {count=10, randomize=true, veteran=true})
    civlua.createUnit(object.uLiner, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=2, randomize=false, veteran=true})
    civlua.createUnit(object.uDestroyer, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=4, randomize=false, veteran=true})
    civlua.createUnit(object.uBattleship, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=2, randomize=false, veteran=true})
    civlua.createUnit(object.uAircraftCarrier, object.tBritish, {{279,71,0},{282,68,0},{285,67,0}}, {count=1, randomize=false, veteran=true})
    civ.ui.text("Axis commanders radio Rome and Berlin, warning that British forces are landing in North Africa...")
    civ.playSound("ALLIED.wav")
    civ.ui.text("The British Empire lands in Africa! With the Soviets urging for a new theatre in the West, Commonwealth forces launch an invasion of North Africa...")
    end)
end

end

Let me know if anything is still unclear.
 
I'm now understanding why the event doesn't work. I had basically put them under the wrong section...I will learn and improve. :D
 
1687723831270.png

@Prof. Garfield
Got another one popping up - I'm investigating it.

Just wondering if there is a specific function area in triggerevents where these type of events should go?

Code:
--SOVIET PARTISAN ATTACKS

--If the Soviet civ has the "Great Patriotic War" tech, the event will randomly spawn Soviet partisan forces...
if civ.hasTech(object.tRussians, object.aGreatPatrioticWar) and math.random(3) == 1 and object.tRussians.isHuman == false then
        --Soviet partisans behind enemy lines
        civlua.createUnit(object.uPartisans, object.tRussians, {{21,37,0},{24,24,0},{27,27,0},{27,43,0}}, {count=2, randomize=true, veteran=false})
    civlua.createUnit(object.uPartisans, object.tRussians, {{28,36,0},{29,19,0},{34,32,0},{35,19,0}}, {count=2, randomize=true, veteran=false})
    civlua.createUnit(object.uPartisans, object.tRussians, {{40,40,0},{42,22,0},{44,21,0},{48,18,0}}, {count=2, randomize=true, veteran=false})
end
 
1687723831270.png
[/URL]
@Prof. Garfield
Got another one popping up - I'm investigating it.

Just wondering if there is a specific function area in triggerevents where these type of events should go?
This error is triggering based on the Legacy Events, either because there is an error in the Legacy Event Engine, or because an event was specified incorrectly. Somewhere (I'll be determining where shortly), the function 'string.lower' is expecting to get a string argument to convert to lower case, but is receiving a nil instead.

It doesn't have anything to do with the quoted event. If that was a separate question, probably the best place to put it is in afterProduction (provided you also check that it is the Soviet Player's turn, otherwise the event will run for all players, and the soviets have a 1/3 chance each time of getting units). onTurn would also be reasonable.
 
@Prof. Garfield
Got another one popping up - I'm investigating it.
This looks to be a problem with legacyEvents.txt or the Legacy Event Engine (the code which transforms the "macro" language to Lua.

According to the Macro.txt documentation I have, this is the documentation for TakeTechnology:
Code:
----------------------------------------------------------------------------------------------
TakeTechnology        whom=                civilization name
                [Collapse]
                technology=            technology index number
----------------------------------------------------------------------------------------------
Code:
TakeTechnology:

Takes the specified advance away from the named civilization (if they have it). The technology index number is the position
 of the particular advance in the advances list in the rules.txt file. Remember that the index numbers begin at zero (AFl), 
and only go up to 99 (X7). Also, note that Future Technology (90) cannot be taken away. Whom is the civilization destined 
to take a step backward. As if losing a tech isn't bad enough, the optional parameter Collapse makes it devastating; this also 
takes away any advance that has the specified advance as a prerequisite--and all advances that have those as prerequisites, 
on up the tree. This action must not appear in the same event with an EnableTechnology or GiveTechnology action.
Based on this, the Legacy Event Engine expects the TakeTechnology event to have a "whom" key word, not a "receiver" keyword.

However (line 1715), there is this event:
Code:
;----------------------------------------------
;Soviet Red Army Attacks
;----------------------------------------------
@IF
ReceivedTechnology
technology=219
receiver=Soviet Union
@THEN
TakeTechnology       
receiver=Soviet Union
technology=219
@ENDIF

By searching for TakeTechnology, I find several others as well.

If you can confirm 'receiver' is a valid alternate keyword for TakeTechnology, then I'll have to change the legacy event engine. Otherwise, you should change 'receiver' to 'whom' in legacyEvents.txt file.

Let me know if you still have trouble.
 

Attachments

If you can confirm 'receiver' is a valid alternate keyword for TakeTechnology, then I'll have to change the legacy event engine. Otherwise, you should change 'receiver' to 'whom' in legacyEvents.txt file.
OK, I just tested this, and 'receiver' is not a valid keyword for take technology.
 
Ah!
Thanks! This is some of the old macro structure that is defunct. I will look over this during the week - You've been an awesome help. :)
 
Yup - Fixed the "taketechnology" events, and the bug is gone...Excellent. Now to fine tune the tech-flow and make sure the Brits don't invade Europe in 1941!
 
Asking here by default, because I don't know if the answer is LUA-based, ToTPP-based, or the same as it was before. It used to be that the only way to, "resurrect," a civ who was killed by the cheat menu while designing a scenario when they were realized to be needed again was hex editing. Has either the ToTPP or LUA made this feat any easier, since?
 
Asking here by default, because I don't know if the answer is LUA-based, ToTPP-based, or the same as it was before. It used to be that the only way to, "resurrect," a civ who was killed by the cheat menu while designing a scenario when they were realized to be needed again was hex editing. Has either the ToTPP or LUA made this feat any easier, since?
In the Lua Console, try
Code:
civ.game.activeTribes = 255
This should resurrect all the tribes. (255 is the decimal representation of 11111111, which is why that is the number used.)
 
In the Lua Console, try
Code:
civ.game.activeTribes = 255
This should resurrect all the tribes. (255 is the decimal representation of 11111111, which is why that is the number used.)
Where exactly, in code order, in a LUA file do you put that command? I keep getting errors, and I assume it's because I'm putting in the wrong place. I also ask because the, "civ.game" qualifier doesn't seem to appear, as such, in any of the example events and triggers listed in the LUA template files.
 
Last edited:
Where exactly, in code order, in a LUA file do you put that command? I keep getting errors, and I assume it's because I'm putting in the wrong place. I also ask because the, "civ.game" qualifier doesn't seem to appear, as such, in any of the example events and triggers listed in the LUA template files.
You don't have to put this in a file.

Press CTRL+SHIFT+F3 to open the Lua Console.

At the bottom, there is a box beside the Load Script button.
activeTribes.png

Type the command
Code:
civ.game.activeTribes = 255
into the box and press enter.

This should restore the tribes (though they won't have any cities or units). If this doesn't work, let me know. (It worked for me in a quick test.)
 
You don't have to put this in a file.

Press CTRL+SHIFT+F3 to open the Lua Console.

At the bottom, there is a box beside the Load Script button.
View attachment 666913
Type the command
Code:
civ.game.activeTribes = 255
into the box and press enter.

This should restore the tribes (though they won't have any cities or units). If this doesn't work, let me know. (It worked for me in a quick test.)
Ah, got it! Thanks!
 
Ah, got it! Thanks!
Alright, just tried it, and it failed. Error messages were, "no field package preload," and, "general library not found." What do those mean, exactly? It sounds like it means I was mistaken and the scenario was only begun creation - long ago - with the current number of civ's and never had a full seven, with a couple being deleted in the process. Is that about correct, or does it mean something else?
 
Last edited:
Alright, just tried it, and it failed. Error messages were, "no field package preload," and, "general library not found." What do those mean, exactly? It sounds like it means I was mistaken and the scenario was only begun creation - long ago - with the current number of civ's and never had a full seven, with a couple being deleted in the process. Is that about correct, or does it mean something else?

Can you please post a picture of the error? The particular line of code I want you to execute doesn't depend on having any particular files. It is provided directly by the TOTPP.

Your error description seems more like something you'd get when loading a game if a file that events.lua is expecting isn't there. Even if an error is shown, you can still try to run the line of code in the console.

You might have a version of the Lua Template that is so old that it tries to find files in the Test of Time\lua directory, and not just in the scenario's directory. If that's the case, I can move your code to a recent version of the template.
 
You might have a version of the Lua Template that is so old that it tries to find files in the Test of Time\lua directory, and not just in the scenario's directory. If that's the case, I can move your code to a recent version of the template.
I think this might be it. An obsolete version. In fact, I'm not even completely sure when I downloaded the version I have. I'll download the one at the link in your post, and try again.
 
Back
Top Bottom