Using LUA to prevent unit upgrade?

sman1975

Emperor
Joined
Aug 27, 2016
Messages
1,314
Location
Dallas, TX
Greetings,

I'm working on a mod that adds units throughout the tech tree, for example, it adds 8 UUs, one for each Era of the normal game.

I'd like to make it possible to upgrade a unit to the next Era's version, once a civ discovers the prereq tech (pretty easy to do).

I'd also like to limit the number of each Era's units (also easy to do using the MaxPlayerInstances element).

---------------------------

My problem is that I'd like to limit the total number of units at 3 for each Era, for a max of 24 total units, assuming you never upgraded any units.

Unfortunately, when it's possible to upgrade a unit, the game lets you do this - and does not check the MaxPlayerInstances numbers before upgrading the unit.

This means I can build 3 "ancient" units. When I get to "classical" I can build 3 "classical" units, then upgrade the 3 "ancient" units. I now have 6 "classical" units.

Ultimately, I can end up with 24 "Information" units if I plan accordingly. This is definitely game breaking, as these latter units are pretty OP.

---------------------------

I can think of some LUA ways of preventing a player for "producing" a given Era unit if there are already too many fielded. But I still can't figure out a way of preventing an upgrade if there are too many of that Era's units already in the game.

Does anyone have any suggestions on how to pull this off?

Thanks!
 

whoward69

DLL Minion
Joined
May 30, 2011
Messages
8,662
Location
Near Portsmouth, UK

sman1975

Emperor
Joined
Aug 27, 2016
Messages
1,314
Location
Dallas, TX
Thank you, Mr. whoward69! I didn't see this event in the modiki, and forgot to look at that extended list of events in the reference you sent. Great tip, BTW!

I looked over the example in your "Units - Multiple Upgrades" mod. Here is the admittedly bare-bones/suboptimal solution I got working. It limits a civ's ability to upgrading units to a total of 3 of the higher unit. I'll expand it later to put in the limits on specific units later, but here is the basic function:

Code:
g_iTotalUnitsPerClass = 3

function OnCanHaveAnyUpgrade(iPlayer, iUnit)                                                                    -- Function determines if an upgrade is possible, based on number of higher units
    local pPlayer = Players[iPlayer]                                                                        -- Set the player pointer
    local pUnit = pPlayer:GetUnitByID(iUnit)                                                                -- Set the unit pointer
    local iUpgradeUnitType = pUnit:GetUpgradeUnitType()                                                        -- Get the upgrade unit type
    local iUpgradeUnitClass = GameInfo.Units[iUpgradeUnitType].Class                                        -- Get the class of the upgrade unit
    local iUpgradeUnitClassType = GameInfo.UnitClasses["" .. iUpgradeUnitClass .. ""].ID                    -- Convert the class key to the ID
    local iUpgradeUnitClassCount = pPlayer:GetUnitClassCount("" .. iUpgradeUnitClassType .. "")    or g_iTotalUnitsPerClass        -- Get the total upgrade unit class count        
    if iUpgradeUnitClassCount >= g_iTotalUnitsPerClass then                                                    -- If the number of upgrade units is more than the amount allowed, then...
        return false                                                                                        -- Return false: no more upgrades are allowed
    end
    return true                                                                                                -- Return true, if the number of upgrade units is less than the limit
end
GameEvents.CanHaveAnyUpgrade.Add(OnCanHaveAnyUpgrade)


The function works exactly as I want it to, except for one small UI problem: the tooltip on the Unit Panel on the now grayed-out "upgrade" button. It shows the same text as it does when there's no restriction on upgrading the unit.

Here is a picture of the issue:

upload_2018-6-22_14-5-4.jpeg

Is there any way, short of replacing UnitPanel.lua, to update that tooltip with a "too many units" error message, or simply call it "good enough" and then a day?

Thanks!
 

LeeS

Imperator
Joined
Jul 23, 2013
Messages
7,241
Location
Illinois, USA
  1. Somewhat simplified
    Code:
    g_iTotalUnitsPerClass = 3
    
    function OnCanHaveAnyUpgrade(iPlayer, iUnit)							-- Function determines if an upgrade is possible, based on number of higher units
        local pPlayer = Players[iPlayer]								-- Set the player pointer
        local pUnit = pPlayer:GetUnitByID(iUnit)							-- Set the unit pointer
        local iUpgradeUnitType = pUnit:GetUpgradeUnitType()						-- Get the upgrade unit type
        local sUpgradeUnitClass = GameInfo.Units[iUpgradeUnitType].Class				-- Get the class of the upgrade unit
        local iUpgradeUnitClassCount = pPlayer:GetUnitClassCount(GameInfoTypes[sUpgradeUnitClass])	-- Get the total upgrade unit class count        
        if iUpgradeUnitClassCount >= g_iTotalUnitsPerClass then					-- If the number of upgrade units is more than the amount allowed, then...
            return false										-- Return false: no more upgrades are allowed
        end
        return true											-- Return true, if the number of upgrade units is less than the limit
    end
    GameEvents.CanHaveAnyUpgrade.Add(OnCanHaveAnyUpgrade)
  2. You don't need the syntax like here
    Code:
    "" .. iUpgradeUnitClass .. ""
    You can directly state the viariable name you have inserted either a text string or an ID # into, so long as the string or the ID # exists within the table.
  3. If you did this you'd get a nil value error because there's no such thing as UNIT_CHEESEBURGLER
    Code:
    local iUnitType = GameInfoTypes.UNIT_CHEESEBURGLER
    local sUnitClass = GameInfo.Units[iUnitType].Class
    local iUnitClassID = GameInfoTypes[sUnitClass]
    print(iUnitClassID)
    But this is fine
    Code:
    local iUnitType = GameInfoTypes.UNIT_SWORDSMAN
    local sUnitClass = GameInfo.Units[iUnitType].Class
    local iUnitClassID = GameInfoTypes[sUnitClass]
    print(iUnitClassID)
  4. For the issue with the unit panel, you'd have to re-write the unit-panel lua file
 

sman1975

Emperor
Joined
Aug 27, 2016
Messages
1,314
Location
Dallas, TX
@LeeS - appreciate the help optimizing the code. I put in the changes and, surprise-surprise, it worked beautifully... :lol:

And thanks also for letting me know what I had suspected: there simply isn't a way to update that "upgrade unit" tooltip without rewriting the UnitPanel.lua. I know that a lot of mods replace that UI already, so one should only add a change like that if it's somehow worth breaking compatibility with a vast number of very popular mods. In this particular case (an inadequate tooltip), it's not.

Thanks again - appreciate the help learning how to write better code!
 
Top Bottom