• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

[TOTPP] Prof. Garfield's Lua Code Thread

Would it be possible to create a lua script were certain units will give adjacent units a damage each turn?

For example I'm using non moveable fortress units. Every time when an enemy unit will move next to the fortress unit the enemy unit should suffering a small damage.
1720714597925.png
[/URL]

Would it be easy to achieve a script like that? In best case an easy script which I will be able to understand how it works? I'm not a programmer so I would like to ask the experts here.

Well, the enemy unit should only suffering a damage each turn as long as it will stay right next to the fortress.
Here is some untested code that I think will do what you want.

Code:
discreteEvents.onTribeTurnBegin(function (turn, tribe)
    for fortress in civ.iterateUnits() do
        if fortress.owner == tribe and fortress.type == object.uFortress then
            for adjacentUnit in gen.nearbyUnits(fortress.location,1,fortress.location.z) do
                if diplomacy.warExists(fortress.owner,adjacentUnit.owner) then
                    adjacentUnit.damage = adjacentUnit.damage + 1
                    if adjacentUnit.damage >= adjacentUnit.type.hitpoints then
                        gen.defeatUnit(adjacentUnit,fortress,fortress,adjacentUnit,adjacentUnit.location,fortress.veteran,adjacentUnit.veteran)
                    end
                end
            end
        end
    end
end)
EDIT: Above code changed so that unit is only damaged if at war (instead of the war check doing nothing).

You will have to change object.uFortress to whatever the actual fortress unit type is, and I just set the damage to 1.

You can test this code without ending the turn using this console command
Code:
console.onTribeTurnBegin()

Let me know if you have any questions or difficulties.
 
Last edited:
Here is some untested code that I think will do what you want.

Code:
discreteEvents.onTribeTurnBegin(function (turn, tribe)
    for fortress in civ.iterateUnits() do
        if fortress.owner == tribe and fortress.type == object.uFortress then
            for adjacentUnit in gen.nearbyUnits(fortress.location,1,fortress.location.z) do
                if diplomacy.warExists(fortress.owner,adjacentUnit.owner) then
                end
                adjacentUnit.damage = adjacentUnit.damage + 1
                if adjacentUnit.damage >= adjacentUnit.type.hitpoints then
                    gen.defeatUnit(adjacentUnit,fortress,fortress,adjacentUnit,adjacentUnit.location,fortress.veteran,adjacentUnit.veteran)
                end
            end
        end
    end
end)

You will have to change object.uFortress to whatever the actual fortress unit type is, and I just set the damage to 1.

You can test this code without ending the turn using this console command
Code:
console.onTribeTurnBegin()

Let me know if you have any questions or difficulties.

Thanks prof.

Shouldn't the end of "diplomacy.warExists" condition met be written after damage is dealt (and its potential consequences) ?
 
Shouldn't the end of "diplomacy.warExists" condition met be written after damage is dealt (and its potential consequences) ?
You're right. I'll edit the post.
 
Many thanks for the code Prof.Garfield.

I've tested it but it doesn't seem to work. The nearby unit won't be damaged. LUA itself doesn't show me any errors.
Code:
if turn >= 1 then
    for fortress in civ.iterateUnits() do
        if (fortress.owner == object.pFrench or fortress.owner == object.pOttomanEmpire or fortress.owner == object.pSpanishHabsburgEmpire) and fortress.type == object.uFortress then
            for adjacentUnit in gen.nearbyUnits(fortress.location,1,fortress.location.z) do
                if diplomacy.warExists(fortress.owner,adjacentUnit.owner) then
                    adjacentUnit.damage = adjacentUnit.damage + 10
                    if adjacentUnit.damage >= adjacentUnit.type.hitpoints then
                        gen.defeatUnit(adjacentUnit,fortress,fortress,adjacentUnit,adjacentUnit.location,fortress.veteran,adjacentUnit.veteran)
                    end
                    civ.ui.text("Our troops are under attack from a nearby fortress")
                end
            end
        end
    end
end
 
I've tested it but it doesn't seem to work. The nearby unit won't be damaged. LUA itself doesn't show me any errors.
Have you made sure that the two tribes are at war? Actually at war, not just no peace treaty. That's what diplomacy.warExists checks for.

If you want units to be damaged regardless of war status, you should change the check to something like
Code:
fortress.owner ~= adjacentUnit.owner
Let me know if it still doesn't work.
 
Sorry for asking you again Prof.Garfield, but the code doesn't work.
I've an event which declares war to both civs, so they are actually at war. But the unit right next to the fortress unit doesn't suffering any damage.

I`m a little bit confused because LUA doesn't show me any errors.
 
Sorry for asking you again Prof.Garfield, but the code doesn't work.
I've an event which declares war to both civs, so they are actually at war. But the unit right next to the fortress unit doesn't suffering any damage.

I`m a little bit confused because LUA doesn't show me any errors.
Time to add some 'print("code location")' in your code to see with the console what is not trigerring ;)
 
Now, as it is located in the right directory the LUA console shows me an error
1720963741376.png
[/URL]
Unfortunately I don't understand the error
"Attempt to call a nil value" means that you're trying to use a variable or table value like a function, but that value is actually nil. "field warExists" means that the table value associated with the key 'warExists' is causing the error.

Code:
                if diplomacy.warExists(fortress.owner,adjacentUnit.owner) then

Adding the require line
Code:
local diplomacy = require("diplomacy")
should fix the problem.

This error does confuse me a bit, since this particular error means that a `diplomacy` variable has been defined, and is a table, but isn't referencing the diplomacy module.
 
The error message is fixed now, but unfortunately the script doesn't damage the units next to the fortress.
Only the variable 'fortress' was missing according to LUA so I added this line
Code:
    local function fortress()
Aftre adding the line I haven't any errors. However I'm not sure if this is right.

The code is looking as follow
Code:
if turn >= 1 then
    local function fortress()
    for fortress in civ.iterateUnits() do
        if fortress.owner == tribe and fortress.type == object.uFortress then
            for adjacentUnit in gen.nearbyUnits(fortress.location,1,fortress.location.z) do
                if diplomacy.warExists(fortress.owner,adjacentUnit.owner) then
                    adjacentUnit.damage = adjacentUnit.damage + 10
                    if adjacentUnit.damage >= adjacentUnit.type.hitpoints then
                        gen.defeatUnit(adjacentUnit,fortress,fortress,adjacentUnit,adjacentUnit.location,fortress.veteran,adjacentUnit.veteran)
                    end
                    civ.ui.text("Our troops are under attack from a nearby fortress")
                end
            end
        end
    end
end
end
 
That's not right. What your code does now is that each turn a function "fortress" is defined, but not executed. Since the function is never executed, whatever is causing the error is now ignored.

Remove the line
Code:
local function fortress
and the corresponding `end` line.

Does your object.lua file have a line associating object.uFortress with the fortress unit type?
 
I've deleted the 'local fortress line' and the script seems to be work. At least the text message pops up every turn when a unit is next to the fortress unit.
1721064950026.png


But the adjacent unit doesn't suffer any damage.
 
The code works now. I only had to add all civs at 'fortress.owner == tribe'
Now all adjacent units suffers a damage each turn if they are at war with the civ who controls the fortress unit.:)
 
Back
Top Bottom