1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Extracting a Civ's unique building (class) in Lua

Discussion in 'Civ5 - Creation & Customization' started by bootrecords, Aug 20, 2015.

  1. bootrecords

    bootrecords Chieftain

    Joined:
    Aug 14, 2015
    Messages:
    16
    Location:
    Disordered States of Europe
    For a mod that I am currently working on, on acquisition of a social policy I want to add a hidden building to cities that already have a museum-class building at that time. Importantly, I also want to add this hidden building to cities that belong to civs that potentially replaced BUILDING_MUSEUM with a unique building of BUILDINGCLASS_MUSEUM.

    Accordingly, I have been wondering whether there is a simple way to extract the ID of the building from BUILDINGCLASS_MUSEUM that a player uses. Does anyone know of an according function that achieves this?

    Alternatively, if no such function exists, can anyone think of an approach that is at least more convenient than crawling all the Civilization_BuildingClassOverrides entries and checking whether any entry is of BUILDINGCLASS_MUSEUM and, if there is one, if the according CivilizationType matches the current player's? Granted, the aforementioned crawling could probably be reduced to one iteration in the beginning that stores all pairs of CivilizationTypes and BuildingTypes matching the BUILDINGCLASS_MUSEUM in a static or global table, but if there was a way to go without, I'd sure like to know.
     
  2. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    There are several ways of doing this, although I don't believe there exists any way of doing so directly.

    One method, as you described, is to simply scan the database as your script loads for all valid Museum replacements and store them in a table for later use. If you will be scanning often, this may be the best way to go, as you would effectively cache the entries into a Lua table, which can be accessed much more quickly than a database query.

    Alternatively, you can use the information from the building to scan the Buildings database and look for matches for BuildingClass Museum there.
     
  3. AW Arcaeca

    AW Arcaeca Deus Vult

    Joined:
    Mar 10, 2013
    Messages:
    2,969
    Gender:
    Male
    Location:
    Operation Padlock ground zero
    JFD has used several times a function highly akin to this except for UUs. So I stole that function and changed the word "unit" to "building", and we'll just say JFD wrote this function :p.
    Code:
    function JFD_GetUniqueBuilding(player, buildingClass)
      local buildingType = nil
      local civType = GameInfo.Civilizations[player:GetCivilizationType()].Type
    
      for uniqueBuilding in GameInfo.Civilization_BuildingClassOverrides{CivilizationType = civType, BuildingClassType = buildingClass} do
        buildingType = uniqueBuilding.BuildingType
        break
      end
    
      if (buildingType == nil) then
        buildingType = GameInfo.BuildingClasses[buildingClass].DefaultBuilding
      end
    
      return buildingType
    end
    Or maybe he really did write that function and I just don't know where.
     
  4. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    Yeah, at its core, that function simply scans the BuildingClassOverrides table for matches and returns them. JFD simply wrapped it up in its own little abstracted sub-function for easier calling on-demand.
     
  5. bootrecords

    bootrecords Chieftain

    Joined:
    Aug 14, 2015
    Messages:
    16
    Location:
    Disordered States of Europe
    Hm, yeah, my thoughts went in a very similar direction... this is basically that database crawling I referred to. Although I have to say that the notation
    is pretty elegant, actually. Didn't realise that DB queries could relatively efficiently be formulated like this in Lua. Thanks for bringing that up!

    EDIT: BTW, when a civ with a unique building replacement captures a city with the default (or another unique replacement) building of that class, that building, if not destroyed, is transformed into the capturing civ's unique, right? Or is it destroyed by default? Does this also happen when the captured city is puppeted?
     
  6. LeeS

    LeeS Imperator Supporter

    Joined:
    Jul 23, 2013
    Messages:
    7,127
    Location:
    Illinois, USA
    I always revert to a bit of gifted wisdom when I have it available:
    Code:
    ------------------------------------------------------------
    ---- Whoward69' BuildingClass in a city check
    ------------------------------------------------------------
    
    function HasBuildingClass(pCity, sBuildingClass)
      for building in GameInfo.Buildings("BuildingClass='" .. sBuildingClass .. "'") do
        if (pCity:IsHasBuilding(building.ID)) then
          return true
        end
      end
      
      return false
    end
    -------------------------------------------

    edit --> and you would want to state sBuildingClass as a string: ie, "BUILDINGCLASS_MUSEUM"
     
  7. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    If I recall correctly, unique buildings will always be destroyed when the City is captured -- even if you set it explicitly to have a 100% chance of capture. All other normal buildings I believe have a chance of surviving a City capture, at which point if it does survive and the conquering Civ has a unique version of that building, the game will swap the basic building for the unique building. I believe it makes no difference whether you puppet it or not, because the game has to update the City's buildings once it has transferred over to your control to await your decision on what to do with it.

    With that said, both AW's posted JFD code and LeeS' posted whoward code will work fine for most scenarios. I personally use a variant of whoward's code because it suits my needs better. JFD's code works well for whatever situation he's coded it for, but while it will generally work as expected, his code will fail to catch some corner cases, of which my Civ would be one of.

    My Civ doesn't do anything with Museums specifically, but it does have two unique Shrine replacement buildings. Unfortunately, the game doesn't like the idea of anyone having multiple uniques within the same building class, so it freaks out if I handle it normally. I ended up having to write a bunch of Lua to handle it the way I needed it to, and as a result, my Civ uses two unique buildings from the Shrine buildingclass, but only one of which is actually defined as a unique building. JFD's code would not be able to catch my second unique Shrine, and once my code swaps it in, his code will 'miss' it. I bring this up because it could potentially be applied to a Civ which wanted to have multiple Museums.

    In my case, I used the variant of whoward's code so that I could simply check that I had one of the buildings within the Shrine buildingclass in my Cities.
     
  8. bootrecords

    bootrecords Chieftain

    Joined:
    Aug 14, 2015
    Messages:
    16
    Location:
    Disordered States of Europe
    Yes! So much this! THANK YOU, LeeS! :goodjob:


    Good to know - that probably spares me the trouble of having to implement manual checks on most of these conditions. Thanks a lot for the help. :)
     

Share This Page