Events question...

A question about the eventTriggers, file...Do the un-used functions need to be kept in the file? Or can I delete any I plan not to use? Does Lua care?

This is more to have the file clear of chaff and easier to work with.

They have to stay in there, but you can cut and paste them into a different order, so that all the ones you don't plan to use are at the bottom (or top) of your file. Alternatively, you can work in the individual files in the UniversalTriggers folder, which won't be as cluttered. That was the way I envisioned working with the template

If your text editor supports hiding lines, you can put
Code:
if true then
-- all the code you don't want to see
end
and probably collapse all that stuff into one or two lines.
 
Thanks, @Prof. Garfield - I'll delegate the unused stuff to the bottom. I want to work in one file as much as I can.

Just wondering if this code looks OK?
Code:
function triggerEvents.onTurn(turn)
    context[getContext()]["onTurn"](turn)
    universal["onTurn"](turn)
    delay.doOnTurn(turn)
    legacy.onTurnEventsAndMaintenance(turn)
    
if unit.owner == object.tRussians and civ.hasTech(object.tRussians, object.aSovEuropeanFront) then
    justOnce("Soviet European Front", function()
    civ.ui.text("German observation posts report increased Russian military traffic. The OKW signals for high alert...")
        civlua.createUnit(object.uRedArmy, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=3, randomize=false, veteran=false})
    diplomacy.setWar(object.tRussians,object.tGermans)
    diplomacy.setVendettaWith(object.tRussians,object.tGermans)
    civ.playSound("INFO.wav")
    end)
    end


I have the local functions set, and the object file matching.
 
Last edited:
Great work, sir! So, can you tell us where the image should be stored, and what formats are supported?

Image sizes are best described in pixels.
Many thanks:)
I've stored the images in the scenario folder.
As for the size of the images: I'm using 242 x 195 pixels
civ.ui.loadImage() actually accepts a file path, not just a file name, that will be searched relative to the scenario directory. So to load an image from a subdirectory within the scenario directory, you would just type something like:
civ.ui.loadImage("images/99_DietofWorms.bmp")

The documentation says that BMP and GIF images are supported -- probably the standard formats used elsewhere in the game. Pretty sure you won't get something like PNG to work, but I guess you could try and see what happens.

Regarding sizes, I did some testing with this. Here's what I learned, at least for my TOT installation:
  1. A dialog object without an image can have a max width of 992 (assigned to the dialog.width field) before the display gets messed up (like this, where the frame and buttons don't appear properly).
    • Note that 992 + 32 = 1024 which is a nice power of 2. So my guess is that 1024 is the real game max, and it's reserving 32 pixels for the frame etc.
  2. The dialog.width property actually sets the width of the text portion of the dialog box only.
  3. However, it's the total width of the box (image plus text) that cannot exceed 992.
  4. Even if you supply no text and set dialog.width = 1, the dialog object appears to use a minimum width of 40.
  5. Therefore, the largest image that I can get to appear properly has a width of 952 pixels -- and this only works if there is no text, or at least so little text that it fits in width 40.
  6. I think this means that if you want to display an image that is 600 pixels wide, for example, then you have to set dialog.width = 352 or lower, and make sure that your text lines fit into that region.
I didn't test image heights yet. I know there are limits on the overall height of a dialog box as well, before the same display issue occurs, but I haven't spent the time to figure out exactly what they are.
 
Last edited:
Just wondering if this code looks OK?

if unit.owner == object.tRussians and civ.hasTech(object.tRussians, object.aSovEuropeanFront) then

Checking if the unit is owned by Russia makes no sense if the event is an onTurn event (and will cause an error). Get rid of the text in bold. EDIT: I think JPetroski had it because he was checking every time a unit activated (I guess so that if the tech was acquired during the turn, the result would happen immediately instead of waiting for the next turn).

Also, make sure you have the line

Code:
local diplomacy = require("diplomacy")

at the top of your file.
 
@Prof. Garfield - My thanks again. I'm very happy - I got the event to work!
Sov_Event1.png

There is still a Lua error popping up, due to me not know how to handle an "anyCity" event in Lua...
But the invasion script fired, and that is good progress today!
 
Things are positive on my Lua experiments - I now know the feeling of making an event work for the first time, and wanting to do more.

Two things I noticed.
Firstly, the German invasion event for the Soviets does work perfectly, but on the 2nd turn after the trigger tech is discovered...
How can I force the event to kick off on the exact turn the Russians gain this tech? Here is the current trigger code:

Code:
if civ.hasTech(object.tRussians, object.aSovEuropeanFront) then
    gen.justOnce("SovietEuropeanFront",function()
    civ.ui.text("German observation posts report increased Russian military traffic. The OKW signals for high alert...")
        civlua.createUnit(object.uRedArmy, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=20, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=10, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=3, randomize=false, veteran=false})
    diplomacy.setWar(object.tRussians,object.tGermans)
    diplomacy.setVendettaWith(object.tRussians,object.tGermans)
    civ.playSound("INFO.wav")
    end)
    end

Is this 2nd turn thing to do with activation of units, or the type of trigger?

The second, I decided to put my city capture events into "onCityTaken", not sure if this was a wise move.
This code runs after the spawn of the invasion forces above...

Code:
-- If the Soviets take a city during their European Front Invasion
if defender == object.tGermany then
    gen.justOnce("SovietsAttackGermany",function()
    civ.ui.text("Stalin has daringly unleashed a concerted strike upon German positions. He hopes to dislocate any future aggression from the fascists. An inspired move, or potential disaster? Time will tell...")
    civ.playSound("RUS.wav")
    end)
end

Not sure why - But bow when any city is captured, Lua gives this error:

Code:
...s\CIV2 TOT\1_Overlords Update\LuaCore\generalLibrary.lua:2759: The Global table doesn't have a value associated with object.
stack traceback:
    [C]: in function 'error'
    ...s\CIV2 TOT\1_Overlords Update\LuaCore\generalLibrary.lua:2759: in metamethod '__index'
    ...\LuaTriggerEvents\UniversalTriggerEvents\onCityTaken.lua:5: in function 'UniversalTriggerEvents\onCityTaken.onCityTaken'
    ...OT\1_Overlords Update\LuaTriggerEvents\triggerEvents.lua:239: in function 'triggerEvents.onCityTaken'
    C:\CIV2 Games\CIV2 TOT\1_Overlords Update\events.lua:298: in function <C:\CIV2 Games\CIV2 TOT\1_Overlords Update\events.lua:294>

I am inclined to believe this might be to do with what file I am using, and not my code?
 
Not sure why - But bow when any city is captured, Lua gives this error:

Code:
\LuaTriggerEvents\UniversalTriggerEvents\onCityTaken.lua:5: in function 'UniversalTriggerEvents\onCityTaken.onCityTaken'

Looks like you're using the onCityTaken.lua file. At the top of this file (outside the event function) is there a line

Code:
local object = require("object")

Whenever you reference stuff from another file, the file you're in must have a corresponding 'require' line, so that the Lua Interpreter knows what you are referencing.

How can I force the event to kick off on the exact turn the Russians gain this tech? Here is the current trigger code:

Move your code to the afterProduction event. If you only want the event to happen on Russia's turn (in case they get the tech during someone else's turn), add the check tribe == object.tRussians.
 
By the way, I updated the error you encountered to hopefully be more useful. Replace generalLibrary.lua in the LuaCore, and events.lua in the main folder. Backup these files just in case, especially the old events.lua file. I'm pretty sure generalLibrary won't cause any errors, but if you're using an older version of the template, events.lua might want to access other files that you don't have. the General Library has the updated error, but some suggested options require the new events.lua file in order to work.
 

Attachments

  • LuaFiles.zip
    30.8 KB · Views: 44
Made the changes, and am still getting the same city capture error.

Updated the files, and now some extra errors.

C:\CIV2 Games\CIV2 TOT\1_Overlords Update\events.lua:71: module 'calculateCityYield' not found:
no field package.preload['calculateCityYield']
no file 'C:\CIV2 Games\CIV2 TOT\1_Overlords Update\calculateCityYield.lua'
no file 'C:\CIV2 Games\CIV2 TOT\1_Overlords Update\LuaCore\calculateCityYield.lua'
no file 'C:\CIV2 Games\CIV2 TOT\1_Overlords Update\LuaRulesEvents\calculateCityYield.lua'
no file 'C:\CIV2 Games\CIV2 TOT\1_Overlords Update\LuaTriggerEvents\calculateCityYield.lua'
no file 'C:\CIV2 Games\CIV2 TOT\1_Overlords Update\LuaParameterFiles\calculateCityYield.lua'
no file 'C:\CIV2 Games\CIV2 TOT\calculateCityYield.dll'
no file 'C:\CIV2 Games\CIV2 TOT\..\lib\lua\5.3\calculateCityYield.dll'
no file 'C:\CIV2 Games\CIV2 TOT\loadall.dll'
no file '.\calculateCityYield.dll'
stack traceback:
[C]: in function 'require'
C:\CIV2 Games\CIV2 TOT\1_Overlords Update\events.lua:71: in main chunk
 
Updated the files, and now some extra errors.

Option 1:
Revert to older events.lua file (if you saved it).

Option 2:
Update template:

Download (green 'code' button):
https://github.com/ProfGarfield/LuaTemplate

For each missing file (module 'calculateCityYield'), copy the file from the template to your scenario folder.

I think the files are:
LuaRulesEvents: calculateCityYield.lua, initiateCombat.lua
LuaTriggerEvents: beforeProduction.lua (You will have to put this in UniversalTriggerEvents, and each of the 3 folders in the context folder)

Change triggerEvents.lua to add the following lines
Code:
function triggerEvents.beforeProduction(turn,tribe)
context[getContext()]["beforeProduction"](turn,tribe)  
universal["beforeProduction"](turn,tribe)
delay.doBeforeProduction(turn,tribe) -- at the moment this
-- is an empty function, but we might want to use it,
-- so it is here for future compatibility
end
 
After moving the code to afterProduction, the event flawlessly triggers at the right moment, but now does not declare war on the Germans...

Does the diplomacy change instruction need to be put somewhere else, I wonder?

Is there no 'war status' in the diplomacy menu, or is there simply a lack of text box stating that war has started?

You could also try
makeAggression
civ.makeAggression(who, whom) -> void

Cancels any peace treaties between tribe `who` and tribe `whom`, and make `who` declare war on `whom`.
 
The Russian/German alliance is still in effect, and it doesn't end when the unit spawn and war situation triggers.

I will try the suggestion you gave, it looks promising. Thanks.

BTW - What is the best method to cover negotiations in Lua? I notice in the scenario the setup in legacy/macro is ignored.
The diplo (F3) menu doesn't work, as if the civs have not made contact...I feel I must set things up in Lua.
 
Code:
function triggerEvents.afterProduction(turn,tribe)
    context[getContext()]["afterProduction"](turn,tribe)
    universal["afterProduction"](turn,tribe)
    delay.doAfterProduction(turn,tribe)
    
if civ.hasTech(object.tRussians, object.aSovEuropeanFront) then
    gen.justOnce("SovietEuropeanFront",function()
    civ.ui.text("German observation posts report increased Russian military traffic. The OKW signals for high alert...")
        civlua.createUnit(object.uRedArmy, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=9, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count-5, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=5, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{19,33,0},{25,21,0},{27,17,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=9, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=5, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=5, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{21,41,0},{30,30,0},{36,28,0}}, {count=3, randomize=false, veteran=false})
        civlua.createUnit(object.uRedArmy, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=9, randomize=false, veteran=false})
        civlua.createUnit(object.uArtillery, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=5, randomize=false, veteran=false})
        civlua.createUnit(object.uLightTank, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=5, randomize=false, veteran=false})
        civlua.createUnit(object.uTB3, object.tRussians, {{22,46,0},{28,46,0},{39,43,0}}, {count=3, randomize=false, veteran=false})
    makeAggression
    civ.makeAggression(object.tRussians, object.tGermans) -> void
    diplomacy.setVendettaWith(object.tRussians,object.tGermans)
    civ.playSound("INFO.wav")
    end)
    end 
end

Tried this, but getting a syntax error...If I cannot get it to work, I might relegate the war declaration to macro events.
 
If your negotiation settings file looks like this, you are already using the macro system.

Code:
local legacy = require("legacyEventEngine")
local negotiationSettings = {}
function negotiationSettings.negotiation(talker,listener)
legacy.doNegotiationEvents(talker,listener)
--return false
return legacy.canNegotiate(talker,listener)
--return true
end
return negotiationSettings

In Lua, if you can't negotiate with a tribe, you can's see them in the foreign affairs window either. @TheNamelessOne would have to fix that bug.

Tried this, but getting a syntax error...If I cannot get it to work, I might relegate the war declaration to macro events.

Code:
   makeAggression
    civ.makeAggression(object.tRussians, object.tGermans) -> void
should be replaced with
Code:
    civ.makeAggression(object.tRussians, object.tGermans)

to set tribes to war, you might have to use the diplomacy module to clear the alliance as well. Probably diplomacy.clearAlliance, though it might be something slightly different.
 
Top Bottom