[TOTPP] Lua Scenario Template

Try putting a few extra newline (\n) characters in your text. Without the ^, it shouldn't display as a new line, but I think it will help the game display the text properly.

Yes, this works.:)

Just another question about the math.ramdom counter. If I would like to create a unit every fifth, six turn, what value should I use? Currently I'm using these values:
Code:
if turn >=7 and turn <= 50 and tribe == object.tHabsburgian and math.random(1, 5) == 5 then

I thought with this value at least every fifth turn the units will appear. But unfortunatelly they doesn't appear.
 
Just another question about the math.ramdom counter. If I would like to create a unit every fifth, six turn, what value should I use? Currently I'm using these values:
Code:
if turn >=7 and turn <= 50 and tribe == object.tHabsburgian and math.random(1, 5) == 5 then
I thought with this value at least every fifth turn the units will appear. But unfortunatelly they doesn't appear.

math.random is not a counter, it is a random number generator. You use it to have randomness. Your code says that between turns 7 and 50, each turn there is a 20% (1 in 5) chance of something happening. If you want something to happen every 5 turns, you do this:
Code:
 turn % 5 == 0
This is true on turn 0,5,10,15,20,etc.
Code:
turn % 6 == 3
is true on turn 3,9,15,21,etc
In general
Code:
turn % turnIncrement == firstTurn
makes an event happen every turnIncrement turns, with the first instance on firstTurn. However, firstTurn must be between 0 and turnIncrement-1. If you want to start at a later turn, have a separate condition like turn >= 12.
 
Not only did it work, it worked like a charm. There were significant "special characters" in the rules file that this just cut through. This is definitely worth an add to the template (and my updating the designer readme) when there's time. Thanks!

I included the ability to leave comments beside the entries associated with certain ID numbers. For example, engineers, freight, and spy were marked beside the unit type corresponding to that id. What kinds of notes would be helpful to have?
 
I think I would use the random number generator, having a chance of 30-35% each turn that the event will happen. What value should I use? "1 in 5" means a 20% chance.

Sorry for asking you so much but I have another hopefully small problem.
I'm currently using a code you wrote for me for the AWI scenario, where the player could buy mercenaries every 10 turn. I've copied the code and made the neccessary changes for making it running in the 1517 scenario. Now the game asks if the player will invest an amount of money for preventing a city in the Holy Roman Empire became protestant.
This is the code I'm using for the example Berlin:
Code:
if tribe == object.tHabsburgian and BerlinReformation[turn] then
        local BerlinProtestant = {}
        BerlinProtestant[1] = "We can't do anything (Berlin became protestant)."
        if tribe.money >= 500 then
            BerlinProtestant[2] = "Send a papal inquisitor and troops to the city (Risk of religious unrest near Berlin)."
        end
        local choice = text.menu(BerlinProtestant,"People in Berlin now following Martin Luther. What shall we do?  Our treasury stands at "..tostring(tribe.money).." gold.","")
        -- if the choice is 1, Berlin became protestant
        if choice == 1 then
            object.cBerlin.owner = object.tProtestant
            if unit.owner ~= object.tProtestant and unit.location.x == object.cBerlin.location.x and unit.location.y == object.cBerlin.location.y and unit.location.z == object.cBerlin.location.z then
            civ.deleteUnit(unit)
        end
        civlua.createUnit(object.uProtestantPikemen, object.tProtestant, {{162,30,0}}, {count=2, randomize=false, veteran=false})
        --If the choice is 2, Berlin remains catholic   
        elseif choice == 2 then   
        civlua.createUnit(object.uReligiousFanatics, object.tBarbarians, {{161,29,0},{162,28,0},{16,29,0}}, {count=6, randomize=false, veteran=false})   
        tribe.money = tribe.money - 1500   
        end
    end-- end of Berlin Reformation

I specified "BerlinReformation" and "BerlinPrice" and with the following code:
Code:
local BerlinReformation = {[10]=true,[20]=true,[30]=true,[40]=true,[50]=true,[60]=true,}
local BerlinPrice = {[1] = 1500,[2] = 1500}

Everything works fine, the game also shows me the dialog window and Berlin became protestant (changed ownership) but then LUA sends an error message:
upload_2021-4-3_16-15-53.png


I'm a little bit confused because all other events with a value associated with 'unit' don't having problems and working fine.
 
I think I would use the random number generator, having a chance of 30-35% each turn that the event will happen. What value should I use? "1 in 5" means a 20% chance.

math.random(low,high) chooses an integer between low and high inclusive.
math.random() chooses a number between 0 and 1, so for a 35% chance, just write math.random()<0.35

I'm a little bit confused because all other events with a value associated with 'unit' don't having problems and working fine.

This is the relevant code:

Code:
if unit.owner ~= object.tProtestant and unit.location.x == object.cBerlin.location.x and unit.location.y == object.cBerlin.location.y and unit.location.z == object.cBerlin.location.z then
            civ.deleteUnit(unit)
end

A variable with 'unit' hasn't been defined here, so that is your problem. It looks like what you want to do is delete all units in Berlin that are not owned by the protestants. For this we need to 'loop' over all the units that could possibly have to be deleted.

Code:
for unit in object.cBerlin.location.units do
    if unit.owner ~= object.tProtestant then
        civ.deleteUnit(unit)
    end
end
Code:
for unit in mytile.units do
will run code for all the units on the tile myTile, and only those units. We don't have to check the location, since we already know it.

If you want to run code for every unit in the game (perhaps you want to delete units near Berlin, not just in Berlin itself),
Code:
for unit in civ.iterateUnits() do
    if unit.owner ~= object.tProtestant and unit.location == object.cBerlin.location then
           civ.deleteUnit(unit)
    end
end
You also simply check that locations (tiles) are equal, you don't need to check each coordinate individually.
 
A very last question, I promise.:D

I would like to use this option for more than one city. So I created a second script for Hamburg. Beneath 'BerlinReformation' I too specified one for Hamburg. So I have now two local variables which are as followed:
Code:
local HamburgReformation = {[15]=true,[35]=true,[55]=true,[65]=true,[75]=true,}
local BerlinReformation = {[20]=true,[40]=true,[60]=true,[70]=true,[80]=true,}

Unfortunatelly LUA starts the event at turn 15 for Hamburg and completely ignores 'local BerlinReformation'. Is there any trick to make the Berlin events available too?
 
A very last question, I promise.:D

I would like to use this option for more than one city. So I created a second script for Hamburg. Beneath 'BerlinReformation' I too specified one for Hamburg. So I have now two local variables which are as followed:

I don't mind answering questions, but I'll need to see the code to work out why the BerlinReformation isn't working.
 
Oh sorry, I've attached the triggerEvent LUA
At line 171 the events starts.
At line 90 you will find the local variables for Berlin and Hamburg
 

Attachments

  • triggerEvents1517.zip
    3.1 KB · Views: 28
When you defined the BerlinCatholic flag (probably in your object file), did you set it to true?

add a line just inside that event
Code:
civ.ui.text("Berlin Protestant Event")
If the text box displays when it is supposed to, the event conditions aren't the problem, but something else in the event is.

Just before the Berlin protestant event, (still in the afterProduction event), add a line
civ.ui.text("BerlinCatholic flag value: "..tostring(flag.value("BerlinCatholic")))
This will tell you whether the BerlinCatholic flag is the problem (perhaps being set false elsewhere or something).
 
I've insert the codes and they are displayed both ingame.
When I use the codes, the events working sometimes, but not everytime.

The flags are in my object lua file and the flags themselve are all set on true. I've attached the object.lua file.
At line 472 I've defined the flags.
 

Attachments

  • object1517.zip
    5.2 KB · Views: 40
comment out this line
Code:
    if tribe == object.tHabsburgian and BerlinReformation[turn] and flag.value("BerlinCatholic") == true then
and replace it with
Code:
if true then
If the Berlin Reformation event happens, then remove the 3 conditions one at a time until you find the one with the problem. If the Berlin Reformation event doesn't happen, then there is a problem with the actual code for the event, and I'll have to look at it more closely.

Try adding turns 19 and 21 to the BerlinReformation table, just in case you're off by one turn when making your test.
 
I think I found the reason why the event didn't work. I changed the code according to your previous post. Everytime, when I started the savegame again and I didn't move the two active units, the Reformation event ddidn't trigger.
But when I move at least one of the active units at the start of the savegame, the Reformation events trigger both. So I inserted one by one the "BerlinReformation[turn]" and the "flag.value..." codes and now it works.

I always thought there must be one active unit at the start of a game to activate all events. But it seams that they must be moved too.
So it must be the units, which wheren't moved at the start of the game.:)
 
I always thought there must be one active unit at the start of a game to activate all events. But it seams that they must be moved too.
So it must be the units, which wheren't moved at the start of the game.:)

It think what happens is that the currently active unit when you load the game doesn't trigger the 'onActivateUnit' event, and, therefore, doesn't trigger afterProduction, since that is tied into onActivateUnit. Moving the unit causes the next one to activate, thereby triggering the event.
 
Based on a template tutorial -

With these settings in the parameter.lua file

Code:
local param = {}

param.MfgGoodsKillPenalty = 150
param.GoodsTruckKillPenalty = 300

return param

I was trying to make this basic event run in onUnitKilled.lua

Code:
function unitKilledEvents.unitKilledInCombat(loser,winner) do
loser.owner.money = math.max(loser.owner.money -campaignCost,0)
winner.owner.money = math.max(winner.owner.money-campaignCost,0)
    if loser.type == object.uMfgGoods then
    civ.ui.text("A goods train is destroyed! Attackers plunder "..tostring(param.MfgGoodsKillPenalty).." gold!")
    object.tRussians.money = object.tRussians.money - param.MfgGoodsKillPenalty
    object.tJapanese.money = object.tJapanese.money - param.MfgGoodsKillPenalty
    object.tGermans.money = object.tGermans.money - param.MfgGoodsKillPenalty
    object.tIndependent.money = object.tIndependent.money - param.MfgGoodsKillPenalty
    object.tAmericans.money = object.tAmericans.money - param.MfgGoodsKillPenalty
    object.tBritish.money = object.tBritish.money - param.MfgGoodsKillPenalty
    object.tFrench.money = object.tFrench.money - param.MfgGoodsKillPenalty
        end
    end   
end
end

Code doesn't seem to fire...Not even the text...I'm missing something, I'm sure...
 
Double check that object.uMfgGoods actually references the correct unit. That's the only thing I can think of.

Your event here currently deducts money from all the tribes when any MfgGoods is killed. That's probably not what you want.

P.S. You can use text.money to convert a number to money (converts the number to a string, then writes the currency as well). In parameters.lua, you can change how text.money displays using text.setMoney.
 
Thanks, I will look into this. :)

EDIT:
Just can't get this to work.

I want trying to set up a simple event, similar to the "capture worker" one, which works fine.

Code:
function unitKilledEvents.unitKilledInCombat(loser,winner) do
loser.owner.money = math.max(loser.owner.money -campaignCost,0)
winner.owner.money = math.max(winner.owner.money-campaignCost,0)
    if loser.type == object.uLabourers then
    local newLabourers = civ.createUnit(object.uLabourers,winner.owner,winner.location)
    end
    if loser.type == object.uEngineers then
    local newEngineers = civ.createUnit(object.uEngineers,winner.owner,winner.location)
    end
end
end

I was hoping to make a generic event with a simple text message that displays and gives 150 gold for killing a MfgGoods unit.

No specifics, just a small winner/loser code. Seems I am just not destined to even make simple events happen. :D

It's not really essential to the scen, just me trying to learn, but badly...!
 
Last edited:
Top Bottom