[TOTPP] Lua Scenario Template

That line of code should reduce the treasury by 10% whenever it is run. Are you running it afterProduction without checking if SpanishHabsburgEmpire is the current player? If only some of your tribes have units to trigger afterProduction, that would account for losing different amounts of gold each turn. 34% loss is about what you would expect if 10% were applied 4 times, and 41% if 10% loss is applied 5 times.
 
I've forgot to say LUA that this should only occur when SpanishHabsburgEmpire the current player is and have implemented the line with the current tribe information. The event works now. Many thanks Prof.Garfield.
 
Hello Prof.Garfield,
I've another problem where I don't know why the event doesn't work. The event itself fires correctly on a certain turn and showing the textbox ingame with the menue but the city doesn't change ownership. LUA itself says everything is correct.
Why does the ownership of the city doesn't change? I'm using the code after 'doAfterProduction'.
Attached are the code I'm using:

Code:
if tribe == object.pSpanishHabsburgEmpire and HamburgReformation[turn] == true and flag.value("HamburgCatholic") == true then
    local Reformation = civ.ui.loadImage("Images/01_Reformation.bmp")
    local dialog = civ.ui.createDialog()
        dialog.title = "The Reformation: Protestant movement in Hamburg"
        dialog.width = 700
        dialog:addImage(Reformation)
    local multiLineText = "The heretic theses ..."
        text.addMultiLineTextToDialog(multiLineText,dialog)           
    if object.pSpanishHabsburgEmpire.money >= 950 then               
        dialog:addOption("Send a Papal Inquisitor ...", 1)       
    end   
        dialog:addOption("We can't do ...", 2)
    local choice = dialog:show()
    if choice == 1 then
        object.cHamburg.owner = object.pProtestantLeague
        for unit in civ.iterateUnits() do
            if unit.owner ~= object.pProtestantLeague and unit.location.x == object.cHamburg.location.x and unit.location.y == object.cHamburg.location.y and unit.location.z == object.cHamburg.location.z then
            civ.deleteUnit(unit)
            end
        end
        civlua.createUnit(object.uProtestantPikemenI, object.pProtestantLeague, {{157,27,0}}, {count=2, randomize=false, veteran=false})
        civlua.createUnit(object.uFortress, object.pProtestantLeague, {{157,27,0}}, {count=1, randomize=false, veteran=false})       
        flag.setFalse("HamburgCatholic")
    elseif choice == 2 then   
        local tribe = object.pSpanishHabsburgEmpire   
            tribe.money = tribe.money - 950   
        flag.setTrue("HamburgCatholic")
    end
end-- end of Hamburg Reformation
 
I'm glad you figured it out.

You can simplify your code a little bit:

Code:
if tribe == object.pSpanishHabsburgEmpire and HamburgReformation[turn] == true and flag.value("HamburgCatholic") == true then
can probably be written as
Code:
if tribe == object.pSpanishHabsburgEmpire and HamburgReformation[turn] and flag.value("HamburgCatholic") then

In an if statement, you can usually write
Code:
if myVariable then
in place of
Code:
if myVariable == true then
The only time you can't is when myVariable could have some other "truthy" value (in Lua, that is anything other than nil and false), and you specifically want to know if the value is true, and not something else. This is definitely not an issue for flag.value, but I don't know for sure about HamburgReformation[turn] without seeing that table.

Code:
            if unit.owner ~= object.pProtestantLeague and unit.location.x == object.cHamburg.location.x and unit.location.y == object.cHamburg.location.y and unit.location.z == object.cHamburg.location.z then
can be written as
Code:
            if unit.owner ~= object.pProtestantLeague and unit.location == object.cHamburg.location then
You can check equality of tileObjects directly, you don't have to compare coordinates.

I wouldn't necessarily bother changing code you already have (what you have isn't wrong), but it can make your code a bit more compact in the future.
 
I've determine in the table 'HamburgReformation[turn], when the Reformation event should always occur.
Code:
local HamburgReformation = {[42]=true,[61]=true,[82]=true,[102]=true,[122]=true,}
 
I've determine in the table 'HamburgReformation[turn], when the Reformation event should always occur.
Code:
local HamburgReformation = {[42]=true,[61]=true,[82]=true,[102]=true,[122]=true,}

I thought that was the structure, so, yes, you can use the code I suggested.
 
Hello @JPetroski ,
I would like to ask you if I may use the weapon selling system you currrently using in your Cold War scenario.
I would like to use it as a system where you can hire mercenaries within the Holy Roman Empire. The price system isn't necessary. Just a list of available units for hiring.

There should be a few amount of units available, which should be updated automatically after a certain turn. The units should be only available within the Holy Roman Empire.

Would it be easy to implement this into my scenario? Unfortunatelly I don't know how I should do this.
 
You're free to use anything you want from any scenario I ever build - @Prof. Garfield is the person who put that in place so I'd credit him with it. The way it currently stands it doesn't have all the functionality you want (a unit pool that changes/updates) but that is very cool indeed and while I won't pretend to be skilled enough to figure out how to do that, I do suspect it is possible given we can track/count different values over time and I suppose you could increase/decrease a value per turn (like, +1 grenadier available each turn up to a maximum of 5 or what have you). It could have the makings of a pretty interesting mercenary system indeed.
 
Hello @JPetroski ,
I would like to ask you if I may use the weapon selling system you currrently using in your Cold War scenario.
I would like to use it as a system where you can hire mercenaries within the Holy Roman Empire. The price system isn't necessary. Just a list of available units for hiring.

There should be a few amount of units available, which should be updated automatically after a certain turn. The units should be only available within the Holy Roman Empire.

Would it be easy to implement this into my scenario? Unfortunatelly I don't know how I should do this.

I can make that for you. Let me see if I understand what you want.

1. The player opens the Hire Mercenaries Menu.

2. The player is presented with a list of mercenary units available for hire. The list of all mercenary unit types that can be hired is short enough that they don't have to be split into categories.

3. For each unit type, there is a limit to the amount that can be hired. This limit can be increased or decreased over time or as a result of specific events.

4. The price of each mercenary unit type doesn't change. The price paid to hire the mercenary is not paid to any other treasury.

5. The player chooses among his or her cities where the mercenary will appear, and some cities can't be chosen. There is no extra "transportation cost" that changes with the city chosen.

If you want something different (or the option to have something different), please reply with that information.
 
You're free to use anything you want from any scenario I ever build - @Prof. Garfield is the person who put that in place so I'd credit him with it. The way it currently stands it doesn't have all the functionality you want (a unit pool that changes/updates) but that is very cool indeed and while I won't pretend to be skilled enough to figure out how to do that, I do suspect it is possible given we can track/count different values over time and I suppose you could increase/decrease a value per turn (like, +1 grenadier available each turn up to a maximum of 5 or what have you). It could have the makings of a pretty interesting mercenary system indeed.

Many thanks @JPetroski . :)

I think the mercenary system could work very well in my scenario, as there are some events where it could be usefull to hire them as a support for the existing troops.
Historically mercenaries played a major role during that time period.
 
I can make that for you. Let me see if I understand what you want.

1. The player opens the Hire Mercenaries Menu.

2. The player is presented with a list of mercenary units available for hire. The list of all mercenary unit types that can be hired is short enough that they don't have to be split into categories.

3. For each unit type, there is a limit to the amount that can be hired. This limit can be increased or decreased over time or as a result of specific events.

4. The price of each mercenary unit type doesn't change. The price paid to hire the mercenary is not paid to any other treasury.

5. The player chooses among his or her cities where the mercenary will appear, and some cities can't be chosen. There is no extra "transportation cost" that changes with the city chosen.

If you want something different (or the option to have something different), please reply with that information.

Many thanks for the support @Prof. Garfield :)

1. The player opens the Hire Mercenaries Menu.

Yes

2. The player is presented with a list of mercenary units available for hire. The list of all mercenary unit types that can be hired is short enough that they don't have to be split into categories.

Yes
These are the units which should be available for hire until 1595:
- Landsknechte
- Pikemen
- Doppelsoldner
- Reiter
- Cuirassiers
- Falconet

From 1595, the following units should be available. If possible, the others from pre 1595 shouldn't be able to hire by the player anymore.
- Pikemen II
- German Mercenaries
- Cuirassiers
- Harquebusiers
- Demi-Culverin

3. For each unit type, there is a limit to the amount that can be hired. This limit can be increased or decreased over time or as a result of specific events.

Yes.
I'm not sure if I will increase or decrease the limit in future. But if it could be implemented without much problems even if I don't use it currently, it would be great.

4. The price of each mercenary unit type doesn't change. The price paid to hire the mercenary is not paid to any other treasury.

Yes.
There should be only money taken away from the players treasury

5. The player chooses among his or her cities where the mercenary will appear, and some cities can't be chosen. There is no extra "transportation cost" that changes with the city chosen.

Yes

That's exactly what I'm looking for.
 
I've updated the template.

Preventing diplomacy using the Legacy Event Engine should working now. My mistake was thinking that talkertype/listenertype were alternatives to talker/listener, and not required with them. Hopefully, this is correct now, but if someone can find an example where it isn't, please let me know. The negotiation event has given me a surprising amount of trouble, especially considering how easy it is to do directly in Lua.

I provided the civlua.lua file that @TheNamelessOne released with TOTPP16. The files in the template require civluaModified.lua, so I just passed civlua.lua though that file for now, just in case there is some sort of regression and it has to be undone.

I also introduced the consolidatedEvents.lua file (found in the main template folder), which is a single file where most kinds of events can be written. It has come up more than once that the file separation system that I implemented is confusing to newcomers (and maybe just plain inconvenient for small scenarios), so I figure this is a reasonable way to do things.
 
I've updated the General Library with a series of functions for tile visibility. I haven't updated the documentation webpage for these changes yet.

Code:
-- gen.isTileRevealed(tile,tribe) -> boolean
-- gen.revealTile(tile,tribe) -> void
-- gen.coverTile(tile,tribe) -> void
-- gen.isCityCharted(city,tribe) --> bool
-- gen.chartCity(city,tribe,visibleSize=nil) --> void
-- gen.unchartCity(city,tribe) --> void
-- gen.isIrrigationCharted(tile,tribe) --> bool
-- gen.chartIrrigation(tile,tribe) --> void
-- gen.unchartIrrigation(tile,tribe) --> void
-- gen.isMineCharted(tile,tribe) --> bool
-- gen.chartMine(tile,tribe) --> void
-- gen.unchartMine(tile,tribe) --> void
-- gen.isFarmlandCharted(tile,tribe) --> bool
-- gen.chartFarmland(tile,tribe) --> void
-- gen.unchartFarmland(tile,tribe) --> void
-- gen.isRoadCharted(tile,tribe) --> bool
-- gen.chartRoad(tile,tribe) --> void
-- gen.unchartRoad(tile,tribe) --> void
-- gen.isRailroadCharted(tile,tribe) --> bool
-- gen.chartRailroad(tile,tribe) --> void
-- gen.unchartRailroad(tile,tribe) --> void
-- gen.unchartTransportation(tile,tribe) --> void
-- gen.isFortressCharted(tile,tribe) --> bool
-- gen.chartFortress(tile,tribe) --> void
-- gen.unchartFortress(tile,tribe) --> void
-- gen.isAirbaseCharted(tile,tribe) --> bool
-- gen.chartAirbase(tile,tribe) --> void
-- gen.unchartAirbase(tile,tribe) --> void
-- gen.isPollutionCharted(tile,tribe) --> bool
-- gen.chartPollution(tile,tribe) --> void
-- gen.unchartPollution(tile,tribe) --> void
-- gen.isTransporterCharted(tile,tribe) --> bool
-- gen.chartTransporter(tile,tribe) --> void
-- gen.unchartTransporter(tile,tribe) --> void

I don't think I mentioned this before, but I also added a table
Code:
gen.original
which functions as an 'object' table using keys based on the original names of structures. This is mainly meant for if someone is writing reusable code that is making checks for specific unit types/improvements/wonders, and would make the code more readable and less error prone.
 
I've been adding the new TOTPPv0.16 flag operations to the General Library. Some of those flags are the settler flags:

Code:
- Reduce population when built (bit 10, the rightmost bit is the first)
- Requires food support (bit 11)
- Can found cities (bit 12)
- Can improve tiles (bit 13) (can only be turned off for settler-type units,
not on for regular units)

Due to the all these flags being hard-coded true for settler-type units in vanilla,
you turn the behaviour OFF for them by setting the flag to 1, while for regular
units you turn it ON by setting the flag to 1. Hence a 1 for any of these flags
should be interpreted as "use the non-default behaviour".

My strategy is to have
Code:
gen.isReducePopulationWhenBuilt(unitType)
gen.giveReducePopulationWhenBuilt(unitType)
gen.removeReducePopulationWhenBuilt(unitType)
For Reduce Population When Built, Requires Food Support, and Can Found Cities this works fine. I just do different things based on whether the unit has the settler role or not.

However, it is not completely obvious what makes sense for
Code:
gen.giveCanImproveTiles(unitType)
If the unit doesn't have the settler role, should this do nothing? Or, should the function change the unit type's role to settler, and disable the other three attributes? I'm inclined to think do nothing (perhaps with a suppressible error to warn the designer that they might be making a mistake) is the way to go, and let the designer make their own function if they need the other kind of change (or, build it as a separate function). Does anyone have any thoughts on this?
 
I've updated the template again. Unit type advancedFlags can now be modified using the General Library (ask if you need help).

Code:
gen.giveCanImproveTiles(unitType)
If the unit doesn't have the settler role, should this do nothing?
I ultimately chose the throw error if the unit isn't a settler route, but that error to be suppressed with a second argument. This seemed simple and sensible, and a more complicated function would leave simple functionality of just changing a flag absent.

makeObject.lua no longer asks for the number of terrain types for each map. Instead, pcall is used for arguments of civ.getTerrain and civ.getBaseTerrain. These throw an error with arguments out of bounds, rather than simply returning nil, which is why I previously asked the user for the number of terrain types.

I have added "discrete events" functionality. This is so that events can be written using a similar structure to the old macro system, where each trigger is its own self contained code, regardless of the location of code for similar triggers. There is a discreteEvents.lua file, but the events could be written in any file.

For example:
Code:
function discreteEvents.onTurn(turn) 
    civ.ui.text("discrete on turn event 1")
end

function discreteEvents.onTurn(turn) 
    civ.ui.text("discrete on turn event 2")
end

function discreteEvents.onTurn(turn) 
    civ.ui.text("discrete on turn event 3")
end

function discreteEvents.onUnitKilled(loser,winner,aggressor,victim,loserLocation,winnerVetStatus,loserVetStatus) 
    civ.ui.text(loser.type.name.." was killed by "..winner.type.name.." discrete event 1")
end

function discreteEvents.onTurn(turn) 
    civ.ui.text("discrete on turn event 4")
end

I think people have commented in the past that the "write all events for a given execution point at the same place" it a sticking point when starting to learn Lua, so this could help solve that.

Also, this should make it easier to offer help writing code, since you can provide an entire self contained event.
 
Top Bottom