A way to make targeted Upgrade_Unit (Leonardo) effect

What would you like to see in Freeciv? Do you have a good idea what should be improved or how?
Ignatus
Elite
Posts: 492
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

A way to make targeted Upgrade_Unit (Leonardo) effect

Postby Ignatus » Tue Apr 21, 2020 10:26 pm

It's a long awaited feature: make Leonardo Workshop-type wonders specific for upgrading only certain types or kinds of units. There is the main obstacle: Upgrade_Unit effect is player-wide (number of upgraded units per turn is defined for a nation), and it's a holy cow (really, a much worthy convention) of effect programming that a specific effect any time depends on current sum of its values disregarding of what individual requirement vectors have spawned them. So, consider we want Leonardo Workshop to upgrade land units and Archimed's Workshop to upgrade triremes: we try to write

Code: Select all

[effect_leonardo]
type = "Upgrade_Unit"
value = 2
reqs = {"type", "name", "range", "present"
 "UnitClass", "Land", "Local"
 "Building", "Leonardo's Workshop", "Player"
 "Tech", "Combustion", "Player", FALSE
}
[effect_archimed]
type = "Upgrade_Unit"
value = 2
reqs = {"type", "name", "range", "present"
 "UnitClass", "Trireme", "Local"
 "Building", "Archimed's Workshop", "Player"
}

Currently, local requirements are just redundant, have not tested if the ruleset fails or you just have 4 random units, sometimes even Biplanes, updated, it just does not sort upgradable units by types. But imagine the server tests this effect for any unit: if a player has both buildings active, the effect value goes 2 for both Triremes and Warriors, so there is no chance to know that we need two units upgraded in each of the classes. Iterating by individual effects, as I have said before, is a taboo. We could iterate by class, but may another ruleset want that we update only the types Warrior and Trireme, and yet another effect upgrades 3 units per turn each of which is either Phalanx or Horsemen (and someone may want free upgrades only for units stationed in cities!) How could we design it to get around these problems?

My suggestion is: let we, iterating by the units, record the different nonzero effect values appeared, sort them, and in the list of units with each value upgrade so many units as the difference with the previous value. A bit complicated, but no holy cows were harmed. So, for our case of two buildings, we accomplish them with a third effect definition to have the desired result:

Code: Select all

[effect_leonardo_and_archimed]
;combine player-wide reqs, leave only some unit-specific
type = "Upgrade_Unit"
value = 2
reqs = {"type", "name", "range", "present"
 "Building", "Archimed's Workshop", "Player"
 "Building", "Leonardo's Workshop", "Player"
 "Tech", "Combustion", "Player", FALSE
 "UnitClass", "Trireme", "Local"
}

Thus, with both buildings warriors have 2 and triremes totally 4, 4 - 2 = 2 - ok. Three groups would require 2 ^ 3 - 1 = 7 individual effects for all possible combinations (but since Phalanx and Horsemen have different vectors with the same value, actually processing them with the two another groups takes at minimum 8 definitions, that goes up to 14 if both the other groups also span two types).

Ignatus
Elite
Posts: 492
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: A way to make targeted Upgrade_Unit (Leonardo) effect

Postby Ignatus » Mon May 25, 2020 8:01 pm

Uh, waait, if you have the effect 2 for land units, 4 for naval units and 6 for aviation, it's intended to upgrade 2 units from each class... But if you have NO naval units, it, as designed above, will upgrade 2 land and 4 aviation! :( Well, maybe the effect should be evaluated per each type in the game, and then something else is needed that should check if auto-upgrade is possible for each existing unit.

Ignatus
Elite
Posts: 492
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: A way to make targeted Upgrade_Unit (Leonardo) effect

Postby Ignatus » Tue Oct 20, 2020 6:34 am

The solution is to include into the list values of a new effect like "Upgrade_Unit_Type" that is evaluated for the player for each unit type; belonging to the type does not make a unit subject to upgrade if "Upgrade_Unit" does not affect it as described above. Actually, that is a kludgy solution - the type means nothing, we just take some objects that are numerous enough to give us flexibility and that can be easily iterated over. Maybe we should really use the new effect to limit the selection by "Upgrade_Unit" from a specific group of unit types (normally, a class or a flag).

Ignatus
Elite
Posts: 492
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: A way to make targeted Upgrade_Unit (Leonardo) effect

Postby Ignatus » Fri Jul 30, 2021 11:37 am

Well, after a good consideration I decided that there is no good way to unhardcode "Upgrade_Unit" within the system of specfiles, effects and requiremements with any reasonable modifications. This effect is a bonus that should be unhardcoded by Lua as it has been done to hut bonuses long ago. See osdn#42659 and related tickets.