1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. Photobucket has changed its policy concerning hotlinking images and now requires an account with a $399.00 annual fee to allow hotlink. More information is available at: this link.
    Dismiss Notice
  3. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  4. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  5. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  6. Dismiss Notice
  7. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

Buildings Require Local Resources Utility

Discussion in 'Civ6 - Utilities, Code Snippets & Art Assets' started by LeeS, Jan 5, 2017.

  1. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    Buildings Require Local Resources Utility
    (see zipped attachment to opening post)​

    this utility is now superceeded by this far more capable one: LeeS' Dummy Buildings Utilities

    If you are looking to add this to your mod you should use the newer better system instead of this one.

    For those already using this version, it is not affected by the new system. The same game can use both systems whenever a mod is using this older system and another mod is using the newer more-capable system. I will not be expanding capability of this older version in any way, however.


    1. This is a utility meant for the use of other mod-makers and allows a city-building to require the city has an available map resource within the city's territory before a building can be constructed within the city. The utility uses a combination of lua scripting and dummy buildings to create the desired effects.
      • The way the xml side of the system works is we create a dummy building that has no purpose except to act as a prerequisite for the 'real' building.
      • The lua side of the system works by adding the dummy building to cities as is appropriate.
      • Once the lua script adds the dummy building to the city, the 'real' building becomes available for construction or purchase in the city.
    2. The game's modifier system cannot achieve this effect. Don't leave comments on this thread about using the modifier system to accomplish the goals of this utility.
    3. The reason a dummy building will be used instead of a direct lua CityCanConstruct event is that Firaxis hasn't implemented such an event for Civ6.
    4. Resources must always be 'visible' to the owner of the city for the purposes of this utility. So if the player hasn't discovered the tech that reveals a particular resource, this utility will not enact a dummy building in a city when that dummy building is linked to that unrevealed resource.

    Creating a Dummy and Real Building Where The Dummy Will Act As a Prereq For the Real Building:
    1. For the purposes of explaining how to use this utility, assume we want to create a building called a Stoneworks that will add +1 Production to the city center and +1 Production to every Stone and Marble resource plot the city works. But we only want this Stoneworks building to be available to a city if the city already has an improved copy of Stone or Marble within its working area. So, we want:
      • The city must have improved stone or marble in its map plots
      • the improved map plot with the stone or marble must be in the city's borders and must 'belong' to the city
      • once these two conditions are met, the city can construct or purchase a Stoneworks building.
    2. Our "Real" building will be called BUILDING_STONEWORKS. Here is what we need for the definition of the the real building that cities will be able to construct:
      Spoiler :
      All this info is included in the files that are part of the utility in the way it is packaged as a functioning mod.

      In an xml file for the actual building definition:
      Code:
      <GameInfo>
      	<Types>
      		<Row Type="BUILDING_STONEWORKS" Kind="KIND_BUILDING" />
      	</Types>
      	<Buildings>
      		<!-- ============ Stoneworks ============= -->
      		<Row BuildingType="BUILDING_STONEWORKS"
      			Name="LOC_BUILDING_STONEWORKS_NAME"
      			Description="LOC_BUILDING_STONEWORKS_DESCRIPTION"
      			PrereqTech="TECH_MASONRY"
      			PrereqDistrict="DISTRICT_CITY_CENTER"
      			Entertainment="1"
      			PurchaseYield="YIELD_GOLD"
      			Cost="80"
      			AdvisorType="ADVISOR_GENERIC" />
      	</Buildings>
      	<Building_YieldChanges>
      		<Row BuildingType="BUILDING_STONEWORKS" YieldType="YIELD_PRODUCTION" YieldChange="1"/>
      	</Building_YieldChanges>
      	<BuildingModifiers>
      		<!--Adjust City Yield-->
      		<Row>
      			<BuildingType>BUILDING_STONEWORKS</BuildingType>
      			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
      		</Row>
      		<Row>
      			<BuildingType>BUILDING_STONEWORKS</BuildingType>
      			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
      		</Row>
      	</BuildingModifiers>
      	<Modifiers>
      		<!--Adjust Plot Yield-->
      		<Row>
      			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
      			<ModifierType>MODIFIER_CITY_PLOT_YIELDS_ADJUST_PLOT_YIELD</ModifierType>
      			<SubjectRequirementSetId>RESOURCE_IS_STONE</SubjectRequirementSetId>
      		</Row>
      		<Row>
      			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
      			<ModifierType>MODIFIER_CITY_PLOT_YIELDS_ADJUST_PLOT_YIELD</ModifierType>
      			<SubjectRequirementSetId>RESOURCE_IS_MARBLE</SubjectRequirementSetId>
      		</Row>
      	</Modifiers>
      	<ModifierArguments>
      		<!--Adjust Plot Yield-->
      		<Row>
      			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
      			<Name>Amount</Name>
      			<Value>1</Value>
      		</Row>
      		<Row>
      			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
      			<Name>YieldType</Name>
      			<Value>YIELD_PRODUCTION</Value>
      		</Row>
      		<Row>
      			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
      			<Name>Amount</Name>
      			<Value>1</Value>
      		</Row>
      		<Row>
      			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
      			<Name>YieldType</Name>
      			<Value>YIELD_PRODUCTION</Value>
      		</Row>
      	</ModifierArguments>
      	<Requirements>
      		<Row>
      			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
      			<RequirementType>REQUIREMENT_PLOT_RESOURCE_TYPE_MATCHES</RequirementType>
      		</Row>
      		<Row>
      			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
      			<RequirementType>REQUIREMENT_PLOT_RESOURCE_TYPE_MATCHES</RequirementType>
      		</Row>
      	</Requirements>
      	<RequirementArguments>
      		<Row>
      			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
      			<Name>ResourceType</Name>
      			<Value>RESOURCE_STONE</Value>
      		</Row>
      		<Row>
      			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
      			<Name>ResourceType</Name>
      			<Value>RESOURCE_MARBLE</Value>
      		</Row>
      	</RequirementArguments>
      	<RequirementSets>
      		<Row>
      			<RequirementSetId>RESOURCE_IS_STONE</RequirementSetId>
      			<RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
      		</Row>
      		<Row>
      			<RequirementSetId>RESOURCE_IS_MARBLE</RequirementSetId>
      			<RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
      		</Row>
      	</RequirementSets>
      	<RequirementSetRequirements>
      		<Row>
      			<RequirementSetId>RESOURCE_IS_STONE</RequirementSetId>
      			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
      		</Row>
      		<Row>
      			<RequirementSetId>RESOURCE_IS_MARBLE</RequirementSetId>
      			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
      		</Row>
      	</RequirementSetRequirements>
      </GameInfo>
      
      In an xml file for the in-game text we need:
      Code:
      <GameData>
      	<LocalizedText>
      		<!-- ================================================================================================= -->
      		<!-- ====================================== STONEWORKS =============================================== -->
      		<!-- ================================================================================================= -->
      		<Row Tag="LOC_BUILDING_STONEWORKS_NAME" Language="en_US">
      			<Text>Stoneworks</Text>
      		</Row>
      		<Row Tag="LOC_BUILDING_STONEWORKS_DESCRIPTION" Language="en_US">
      			<Text>Provides +2 [ICON_Production] Production in the city center, and +1 [ICON_Production] Production to every [ICON_RESOURCE_MARBLE] Marble and [ICON_RESOURCE_STONE] Stone plot worked by the city. The city must have quarry-improved local [ICON_RESOURCE_MARBLE] Marble or [ICON_RESOURCE_STONE] Stone.</Text>
      		</Row>
      	</LocalizedText>
      </GameData>
      In an xml file for the in-game icons we need:
      Code:
      <GameData>
      	<IconDefinitions>
      		<Row Name="ICON_BUILDING_STONEWORKS" Atlas="ICON_ATLAS_BUILDINGS" Index="20"/>
      		<Row Name="ICON_BUILDING_STONEWORKS_FOW" Atlas="ICON_ATLAS_BUILDINGS_FOW" Index="20"/>
      	</IconDefinitions>
      </GameData>
      • note that we are borrowing the icon used by the workshop. Civ6 allows us to do this.
    3. Now we need to define a dummy building that will act as an unlocker prerequisite for the Stoneworks building:
      1. To make it easier to understand our own code, the tagname of the dummy building will be BUILDING_STONEWORKS_UNLOCKER
      2. Defining the dummy building to register it as a valid building within the game's system:
        Code:
        <GameInfo>
        	<Types>
        		<Row Type="BUILDING_STONEWORKS_UNLOCKER" Kind="KIND_BUILDING" />
        	</Types>
        	<Buildings>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" Name="LOC_BUILDING_STONEWORKS_UNLOCKER_NAME" Description="LOC_BUILDING_STONEWORKS_UNLOCKER_DESCRIPTION"
        			PrereqDistrict="DISTRICT_CITY_CENTER" Cost="1" PrereqTech="TECH_FUTURE_TECH" />
        	</Buildings>
        	<BuildingPrereqs>
        		<Row Building="BUILDING_STONEWORKS" PrereqBuilding="BUILDING_STONEWORKS_UNLOCKER"/>
        	</BuildingPrereqs>
        </GameInfo>
        • Keeping the Ai from constructing the dummy building:
          • Neither using EnabledByReligion="true" without specifying a belief that allows purchase of the building, nor stating MustPurchase="true" without specifying a "Yield Type" for PurchaseYield work successfully to keep the AI from adding a dummy building to their city build qeue:
            1. Using EnabledByReligion="true" without specifying a belief that allows purchase of the building merely locks all Religious buildings from being purchaseable or constructable.
            2. Stating MustPurchase="true" without specifying a "Yield Type" for PurchaseYield does not actually keep the AI from adding the building to its city build qeues. They are quite able to do so as evidenced by a "listener" code I added in lua to print out every turn what every city in the game was trying to construct in its Build Qeue.
          • Only setting either "TECH_FUTURE_TECH" as the PrereqTech or "CIVIC_FUTURE_CIVIC" as the PrereqCivic seems to successfully keep the AI from adding the dummy building to city build qeues. I prefer PrereqTech="TECH_FUTURE_TECH" because it seems in most games that the Civics tree is always finished before the Technology tree.
            • by doing things in this manner for the vast majority of any single game the ability to construct a dummy building where otherwise not desired will not come up because "TECH_FUTURE_TECH" will not have been reached by any player, AI or Human.
        • We do not specify a purchase type of yield, again to keep the building from becoming acquirable via 'normal' methods as much as is possible.
        • We cannot use InternalOnly="true" because while this allows us the other advantages we are looking for, once we place such a building into a city, we are unable to remove it from the city via an lua script if we would like our code to be able to do so.
        • For the game's normal 'baked-in' systems, it is the designation of BUILDING_STONEWORKS_UNLOCKER as a PrereqBuilding for BUILDING_STONEWORKS that allows this utility to work.
          • Since in Civ6 the <BuildingPrereqs> table acts as an "OR" table, your real building (such as the BUILDING_STONEWORKS) must only have one entry in the table, tying it to the dummy building (such as the BUILDING_STONEWORKS_UNLOCKER)
          • If for example you want the real building (such as the BUILDING_STONEWORKS) to also require another real building already exist in the city (such as the BUILDING_WORKSHOP), the utility has a built-in method to accomplish this, which will be discussed later. In all cases, however, the dummy building must be the one and only prerequisite listed in the <BuildingPrereqs> table.
      3. Definition of the Dummy Building's Icon.
        Code:
        <GameData>
        	<IconDefinitions>
        		<Row Name="ICON_BUILDING_STONEWORKS_UNLOCKER"		Atlas="ICON_ATLAS_BUILDINGS" Index="0"/>
        		<Row Name="ICON_BUILDING_STONEWORKS_UNLOCKER_FOW"	Atlas="ICON_ATLAS_BUILDINGS_FOW" Index="0"/>
        	</IconDefinitions>
        </GameData>
      4. Definition of the Dummy Building's In-Game Text:
        Code:
        <GameData>
        	<LocalizedText>
        		<Row Tag="LOC_BUILDING_STONEWORKS_UNLOCKER_NAME" Language="en_US">
        			<Text>Stoneworks Unlocker</Text>
        		</Row>
        		<Row Tag="LOC_BUILDING_STONEWORKS_UNLOCKER_DESCRIPTION" Language="en_US">
        			<Text>Acts as a Prereq Building for the Stoneworks. Has no other effect.</Text>
        		</Row>
        	</LocalizedText>
        </GameData>
    4. In the utility I have packaged all of these definitions of the buildings, their text, and their icons into three xml files within a folder called XML_RESOURCE_UNLOCKS
      • Building Definitions: XML_RESOURCE_UNLOCKS/Buildings.xml
        Spoiler :
        Code:
        <GameInfo>
        	<Types>
        		<Row Type="BUILDING_STONEWORKS_UNLOCKER" Kind="KIND_BUILDING" />
        	</Types>
        	<Buildings>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" Name="LOC_BUILDING_STONEWORKS_UNLOCKER_NAME" Description="LOC_BUILDING_STONEWORKS_UNLOCKER_DESCRIPTION"
        			PrereqDistrict="DISTRICT_CITY_CENTER" Cost="1" EnabledByReligion="true" />
        	</Buildings>
        
        		<!-- ===================================================================================
        		================================ STONEWORKS BUILDING ===================================
        		======================================================================================== -->
        
        	<Types>
        		<Row Type="BUILDING_STONEWORKS" Kind="KIND_BUILDING" />
        	</Types>
        	<BuildingPrereqs>
        		<Row Building="BUILDING_STONEWORKS" PrereqBuilding="BUILDING_STONEWORKS_UNLOCKER"/>
        	</BuildingPrereqs>
        	<Buildings>
        		<!-- ============ Stoneworks ============= -->
        		<Row BuildingType="BUILDING_STONEWORKS"
        			Name="LOC_BUILDING_STONEWORKS_NAME"
        			Description="LOC_BUILDING_STONEWORKS_DESCRIPTION"
        			PrereqTech="TECH_MASONRY"
        			PrereqDistrict="DISTRICT_CITY_CENTER"
        			Entertainment="1"
        			PurchaseYield="YIELD_GOLD"
        			Cost="80"
        			AdvisorType="ADVISOR_GENERIC" />
        	</Buildings>
        	<Building_YieldChanges>
        		<Row BuildingType="BUILDING_STONEWORKS" YieldType="YIELD_PRODUCTION" YieldChange="1"/>
        	</Building_YieldChanges>
        	<BuildingModifiers>
        		<!--Adjust City Yield-->
        		<Row>
        			<BuildingType>BUILDING_STONEWORKS</BuildingType>
        			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
        		</Row>
        		<Row>
        			<BuildingType>BUILDING_STONEWORKS</BuildingType>
        			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
        		</Row>
        	</BuildingModifiers>
        	<Modifiers>
        		<!--Adjust Plot Yield-->
        		<Row>
        			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
        			<ModifierType>MODIFIER_CITY_PLOT_YIELDS_ADJUST_PLOT_YIELD</ModifierType>
        			<SubjectRequirementSetId>RESOURCE_IS_STONE</SubjectRequirementSetId>
        		</Row>
        		<Row>
        			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
        			<ModifierType>MODIFIER_CITY_PLOT_YIELDS_ADJUST_PLOT_YIELD</ModifierType>
        			<SubjectRequirementSetId>RESOURCE_IS_MARBLE</SubjectRequirementSetId>
        		</Row>
        	</Modifiers>
        	<ModifierArguments>
        		<!--Adjust Plot Yield-->
        		<Row>
        			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
        			<Name>Amount</Name>
        			<Value>1</Value>
        		</Row>
        		<Row>
        			<ModifierId>STONEWORKS_ADDSTONEPROD</ModifierId>
        			<Name>YieldType</Name>
        			<Value>YIELD_PRODUCTION</Value>
        		</Row>
        		<Row>
        			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
        			<Name>Amount</Name>
        			<Value>1</Value>
        		</Row>
        		<Row>
        			<ModifierId>STONEWORKS_ADDMARBLEPROD</ModifierId>
        			<Name>YieldType</Name>
        			<Value>YIELD_PRODUCTION</Value>
        		</Row>
        	</ModifierArguments>
        	<Requirements>
        		<Row>
        			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
        			<RequirementType>REQUIREMENT_PLOT_RESOURCE_TYPE_MATCHES</RequirementType>
        		</Row>
        		<Row>
        			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
        			<RequirementType>REQUIREMENT_PLOT_RESOURCE_TYPE_MATCHES</RequirementType>
        		</Row>
        	</Requirements>
        	<RequirementArguments>
        		<Row>
        			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
        			<Name>ResourceType</Name>
        			<Value>RESOURCE_STONE</Value>
        		</Row>
        		<Row>
        			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
        			<Name>ResourceType</Name>
        			<Value>RESOURCE_MARBLE</Value>
        		</Row>
        	</RequirementArguments>
        	<RequirementSets>
        		<Row>
        			<RequirementSetId>RESOURCE_IS_STONE</RequirementSetId>
        			<RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
        		</Row>
        		<Row>
        			<RequirementSetId>RESOURCE_IS_MARBLE</RequirementSetId>
        			<RequirementSetType>REQUIREMENTSET_TEST_ALL</RequirementSetType>
        		</Row>
        	</RequirementSets>
        	<RequirementSetRequirements>
        		<Row>
        			<RequirementSetId>RESOURCE_IS_STONE</RequirementSetId>
        			<RequirementId>REQUIRES_STONE_IN_PLOT</RequirementId>
        		</Row>
        		<Row>
        			<RequirementSetId>RESOURCE_IS_MARBLE</RequirementSetId>
        			<RequirementId>REQUIRES_MARBLE_IN_PLOT</RequirementId>
        		</Row>
        	</RequirementSetRequirements>
        </GameInfo>
      • Icon Definitions: XML_RESOURCE_UNLOCKS/Buildings_Icons.xml
        Spoiler :
        Code:
        <GameData>
        	<IconDefinitions>
        		<Row Name="ICON_BUILDING_STONEWORKS_UNLOCKER"		Atlas="ICON_ATLAS_BUILDINGS" Index="0"/>
        		<Row Name="ICON_BUILDING_STONEWORKS_UNLOCKER_FOW"	Atlas="ICON_ATLAS_BUILDINGS_FOW" Index="0"/>
        		<Row Name="ICON_BUILDING_STONEWORKS" Atlas="ICON_ATLAS_BUILDINGS" Index="20"/>
        		<Row Name="ICON_BUILDING_STONEWORKS_FOW" Atlas="ICON_ATLAS_BUILDINGS_FOW" Index="20"/>
        	</IconDefinitions>
        </GameData>
      • Text Definitions: XML_RESOURCE_UNLOCKS/Buildings_Text.xml
        Spoiler :
        Code:
        <GameData>
        	<LocalizedText>
        		<!-- ================================================================================================= -->
        		<!-- ====================================== STONEWORKS =============================================== -->
        		<!-- ================================================================================================= -->
        		<Row Tag="LOC_BUILDING_STONEWORKS_UNLOCKER_NAME" Language="en_US">
        			<Text>Stoneworks Unlocker</Text>
        		</Row>
        		<Row Tag="LOC_BUILDING_STONEWORKS_UNLOCKER_DESCRIPTION" Language="en_US">
        			<Text>Acts as a Prereq Building for the Stoneworks. Has no other effect.</Text>
        		</Row>
        		<Row Tag="LOC_BUILDING_STONEWORKS_NAME" Language="en_US">
        			<Text>Stoneworks</Text>
        		</Row>
        		<Row Tag="LOC_BUILDING_STONEWORKS_DESCRIPTION" Language="en_US">
        			<Text>Provides +2 [ICON_Production] Production in the city center, and +1 [ICON_Production] Production to every [ICON_RESOURCE_MARBLE] Marble and [ICON_RESOURCE_STONE] Stone plot worked by the city. The city must have quarry-improved local [ICON_RESOURCE_MARBLE] Marble or [ICON_RESOURCE_STONE] Stone.</Text>
        		</Row>
        	</LocalizedText>
        </GameData>
    5. These three files are set-up in the modinfo file as follows:
      Code:
      	<Files>
      		<File>XML_RESOURCE_UNLOCKS/Buildings_Icons.xml</File>
      		<File>XML_RESOURCE_UNLOCKS/Buildings.xml</File>
      		<File>XML_RESOURCE_UNLOCKS/Buildings_Text.xml</File>
       	</Files>
      	<Components>
              	<Icons id="Dummy_UnlockerResources_ICONS">
                  		<Items>
                      		<File>XML_RESOURCE_UNLOCKS/Buildings_Icons.xml</File>
                  		</Items>
              	</Icons>
      		<UpdateDatabase id="Dummy_UnlockerResources_XML">
      			<Items>
      				<File>XML_RESOURCE_UNLOCKS/Buildings.xml</File>
      			</Items>
      		</UpdateDatabase>
      		<LocalizedText id="Dummy_UnlockerResources_Text">
      			<Items>
      				<File>XML_RESOURCE_UNLOCKS/Buildings_Text.xml</File>
      			</Items>
      		</LocalizedText>
      	</Components>
    6. Now that the "Real" building called the Stoneworks and its "Dummy Unlocker" called the Stoneworks Unlocker are set up to be added to the game's database, we can implement these two buildings within the code of the utility.
    7. So far, except for defining the dummy building, there is nothing that has been shown that you would not already need to do in order to create a Stoneworks building and make it give the desired extra production to a city.

    Adding Needed Files From This Utility to Your Mod:
    1. You will need three of the files from the attached mod. You will copy/paste these files into your mod.
      • DummyUnlockerResources.sql from the folder "SQL_RESOURCE_UNLOCKS"
        • You must add this whole file to your mod, and you must not make any changes to it.
      • DummyUnlockerResources.xml from the folder "XML_RESOURCE_UNLOCKS"
        • You will alter the xml-code as needed for your dummy and real building(s). You can also just add the stuff that will be shown in this file to any other convenient xml file.
      • DummyUnlockerResources.lua from the folder "LUA_RESOURCE_UNLOCKS"
        • You will make one minor change to the code within this file, but otherwise you will make no changes to it.
    2. Set-up in your modinfo file, as follows. It is important that the SQL file is listed above the xml file and the lua file in the mod's <Files> list, and also that it's UpdateDatabase in <Components> appears above that for the xml file.
      Code:
      	<Files>
      		<File>SQL_RESOURCE_UNLOCKS/DummyUnlockerResources.sql</File>
      		<File>XML_RESOURCE_UNLOCKS/DummyUnlockerResources.xml</File>
      		<File>LUA_RESOURCE_UNLOCKS/DummyUnlockerResources.lua</File>
       	</Files>
      	<Components>
      		<UpdateDatabase id="Dummy_UnlockerResources_SQL">
      			<Items>
      				<File>SQL_RESOURCE_UNLOCKS/DummyUnlockerResources.sql</File>
      			</Items>
      		</UpdateDatabase>
      		<UpdateDatabase id="Dummy_UnlockerResources_XML">
      			<Items>
      				<File>XML_RESOURCE_UNLOCKS/DummyUnlockerResources.xml</File>
      			</Items>
      		</UpdateDatabase>
      		<GameplayScripts id="Dummy_UnlockerResources_LUA">
      			<Items>
      				<File>LUA_RESOURCE_UNLOCKS/DummyUnlockerResources.lua</File>
      			</Items>
      		</GameplayScripts>
      	</Components>
    3. You can alter the folder names where you place these three files, for example, to meet your own needs within your mod. Just be sure the folder names where you actually place them match to what you designate within the modinfo file.
    4. What do these three files do?
      • The SQL file creates three new tables where information can be placed into the game's database. You must not change the contents of this file because when multiple mods are all using this system, they need to see the same definition of the three new tables as they are expecting, not an altered version of the new tables that work for your mod but kill off everyone else's who is using this system.
      • The XML is where you actually register your links between the dummy building and the needed map resources that you want to use as your requirments.
      • The LUA file reads the data entered in the XML file and implements the effects of the three new tables, and adds or removes the dummy buildings as appropriate.

    The New Game XML Tables:
    1. DummyUnlocker_LocalResources:
      1. This table is used to specify map-tile resources near a city that must exist in order for the city to be given the specified dummy building
      2. This table does not care whether the resource is improved or not, only that the resource exist on the map in a plot "owned" by the city.
      3. NEVER use this table and the DummyUnlocker_ImprovedLocalResources for the same dummy building. Each dummy building either needs to be in this table or the DummyUnlocker_ImprovedLocalResources table, but not both tables.
      4. Columns for the table:
        • BuildingType: this is the dummy building
        • ResourceType: this is the resource.
          • when multiple resources are listed for the same dummy building in the table, any one resource being present will allow the dummy building
        • CustomModId: this is a text string the need for which will be explained later
      5. Example:
        Code:
        	<DummyUnlocker_LocalResources>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_MARBLE" CustomModId="LeeS_Cheeseburgers" />
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_STONE" CustomModId="LeeS_Cheeseburgers" />
        	</DummyUnlocker_LocalResources>
    2. DummyUnlocker_ImprovedLocalResources:
      1. This table is used to specify map-tile resources near a city that must exist and be improved with the correct improvement in order for the city to be given the specified dummy building
      2. NEVER use this table and the DummyUnlocker_LocalResources for the same dummy building. Each dummy building either needs to be in this table or the DummyUnlocker_LocalResources table, but not both tables.
      3. Columns for the table:
        • BuildingType: this is the dummy building
        • ResourceType: this is the resource.
          • when multiple resources are listed for the same dummy building in the table, any one resource being present will allow the dummy building
        • CustomModId: this is a text string the need for which will be explained later
      4. Example:
        Code:
        	<DummyUnlocker_ImprovedLocalResources>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_MARBLE" CustomModId="LeeS_Cheeseburgers" />
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_STONE" CustomModId="LeeS_Cheeseburgers" />
        	</DummyUnlocker_ImprovedLocalResources>
    3. DummyUnlocker_RequiresBuildingPreReqORS:
      1. This table is used to specify that the dummy building also needs a "real" building to exist in the city in addition to any resource requirements.
      2. This table acts as an "ORS" table. This means that if more than one "real" building is listed as a prerequisite for a dummy building, only one of the listed "real" buildings is needed in the city. This is intentional to match the way the usual buildings-prereqs table works. So you could make a dummy need either a Barracks or a Stable exist in the city, for example, to make a similar effect to the way the Armory requires either a Barracks or a Stable.
      3. Columns for the table:
        • BuildingType: this is the dummy building
        • PrereqBuilding: this is the "real" building that also must be in the city before the dummy will be added.
        • CustomModId: this is a text string the need for which will be explained later
      4. Example:
        Code:
        	<DummyUnlocker_RequiresBuildingPreReqORS>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" PrereqBuilding="BUILDING_MARKET" CustomModId="LeeS_Cheeseburgers"/>
        	</DummyUnlocker_RequiresBuildingPreReqORS>
    (continued in next post)
     

    Attached Files:

    Last edited: Apr 30, 2017
  2. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    Implementing a Dummy Building That Will Act As a Prereq For Another Building:
    1. Now that we have the needed basic code as part of a mod, all that is necessary is to fill in the new tables (DummyUnlocker_LocalResources, DummyUnlocker_ImprovedLocalResources, DummyUnlocker_RequiresBuildingPreReqORS) as needed, and to make the needed edit in the lua file.
    2. We need to come up with a unique string of text that will identify our mod to the lua code. In these examples and in the packaged mod I am using LeeS_Cheeseburgers but you can use pretty much anything that is unique to your mod. For example, the name of your mod would work just fine. So where I have this in a modinfo file
      Code:
      	<Properties>
      		<Name>BaseGameplayMod</Name>
      		<Teaser>BaseGameplayMod</Teaser>
      		<Description>BaseGameplayMod</Description>
      		<Authors>LeeS</Authors>
      	</Properties>
      I could use the "Name" field of "BaseGameplayMod" as my unique text string.
    3. Designate your unique text string both in the xml code for the new game tables and within the lua file where indicated.
    4. Use this unique text string to update all previous entries into the new tables DummyUnlocker_LocalResources, DummyUnlocker_ImprovedLocalResources, DummyUnlocker_RequiresBuildingPreReqORS as like this:
      Code:
      <GameInfo>
      	<DummyUnlocker_LocalResources>
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_LocalResources>
      
      	<DummyUnlocker_ImprovedLocalResources>
      		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_MARBLE" />
      		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_STONE" />
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_ImprovedLocalResources>
      
      	<DummyUnlocker_RequiresBuildingPreReqORS>
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_RequiresBuildingPreReqORS>
      </GameInfo>
    5. In all three tables I am updating anything that may have been previously added to these tables so that all rows in the three tables now want to use CustomModId="LeeS_Cheeseburgers".
    6. In the first lines of the lua file, we have this:
      Code:
      local sCustomModId="LeeS_Cheeseburgers"
      • This designates for my version of the lua code my "modID"
      • to alter it to use a designation of "BaseGameplayMod" I alter this top line of the lua file to read as:
        Code:
        local sCustomModId="BaseGameplayMod"
        And I would change all my XML to match, as so
        Spoiler :
        Code:
        <GameInfo>
        	<DummyUnlocker_LocalResources>
        		<Update>
        			<Set CustomModId="BaseGameplayMod" />
        		</Update>
        	</DummyUnlocker_LocalResources>
        
        	<DummyUnlocker_ImprovedLocalResources>
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_MARBLE" />
        		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_STONE" />
        		<Update>
        			<Set CustomModId="BaseGameplayMod" />
        		</Update>
        	</DummyUnlocker_ImprovedLocalResources>
        
        	<DummyUnlocker_RequiresBuildingPreReqORS>
        		<Update>
        			<Set CustomModId="BaseGameplayMod" />
        		</Update>
        	</DummyUnlocker_RequiresBuildingPreReqORS>
        </GameInfo>
      • even if you aren't using one or two of the three tables, still make the <Update> as shown.
    7. The lua code is written to look through the three XML-tables DummyUnlocker_LocalResources, DummyUnlocker_ImprovedLocalResources, DummyUnlocker_RequiresBuildingPreReqORS for rows whose CustomModId matches the one stated in this top line of the lua file, and only to execute for those rows in the XML-tables where the two designations match to each other.
    8. In this way, if there are five different mods all running this same system, the final mod to load into the game's database will over-write all the CustomModId designations in the three XML-tables, and only the lua code running from this final mod will have a matching designation. So only this final mod's lua code will run, thus keeping processing down to a minimum and also ensuring that two different versions of the exact same lua code are not attempting to interfere with one another.
    9. You'll notice that for the new XML-table called DummyUnlocker_ImprovedLocalResources I've set up a row to link the dummy building "BUILDING_STONEWORKS_UNLOCKER" to both "RESOURCE_MARBLE" and "RESOURCE_STONE", and even though I am not using either of the other two new tables, I have still added the <Update> command to set all rows as having a CustomModId of "LeeS_Cheeseburgers".
    10. If I only wanted to specify that the city needed to have marble or stone at the city but not that the marble or stone needed to be improved, I would alter my code as follows:
      Code:
      <GameInfo>
      	<DummyUnlocker_LocalResources>
      		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_MARBLE" />
      		<Row BuildingType="BUILDING_STONEWORKS_UNLOCKER" ResourceType="RESOURCE_STONE" />
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_LocalResources>
      
      	<DummyUnlocker_ImprovedLocalResources>
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_ImprovedLocalResources>
      
      	<DummyUnlocker_RequiresBuildingPreReqORS>
      		<Update>
      			<Set CustomModId="LeeS_Cheeseburgers" />
      		</Update>
      	</DummyUnlocker_RequiresBuildingPreReqORS>
      </GameInfo>
    11. If you look at the contents of file XML_RESOURCE_UNLOCKS/DummyUnlockerResources.xml you will see that it's contents are slightly different than those that have been discussed so far. This is because I have also added a dummy and real building related to the Cattle resource, and that requires a city have both a market and at least one copy of improved cattle within the city's tiles before the city can construct a Livestock Exchange building. All of the code needed to imnplement this Livestock Exchange and its unlocker dummy building is contained within the mod attached as part of this utility.

    City-Center Plot Counting for A Resource ?
    1. The City Center plot will always count if the plot has the needed resource.

    Now for the bad news, because Firaxis there always is some:
    1. The dummy building will show in the city list of "Buildings and Wonders" view. It will also show in the civilopedia. Hence the need for the set-up of in-game text and icons, in order to not make the game look kludgey in the civilopedia, etc., as a result of these dummy buildings.
    2. If you remove a building via lua from a city, the building does not disappear from the list of buildings in the city's "Buildngs and Wonders" view. The building is actually gone, but the Icon of the Building and its description remain.
    3. In order to eliminate the dummy building from the list shown in the city's list, you have to save and reload the game. Civ5 graphics not update is alive and well in even more permutations in civ6 than it was in civ5.
    4. Adding and removing the building via lua acts correctly and the Building performs correctly as a Prereq for another building, etc. It is just that the display is not friendly to the modder.
    5. We are currently not able in a GameplayScripts context to determine if a plot improvement has been pillaged. So, for table DummyUnlocker_ImprovedLocalResources all that matters is that the plot has been improved with the correct improvement-type. Barbs can come by later and pillage the plot and the lua code will still see the plot as good for purposes of having an improved copy of the needed resource.

    What If I Want To Make A Unit Require A Resource ?
    1. You use the same system.
    2. The three tables the system uses do not know or care about what the dummy building is being used for.
    3. Just use the dummy building as a Prerequisite for the unit, rather than as a prerequisite for a building.
    4. the lua code is already written to accomodate for using the dummy building as a prereq for a unit.

    What If I Want To Make Some Other Effect Require A Resource Being Near a City ?
    1. You use the same system. You just make this affect come directly from the dummy building. Although in nearly all such cases you can probably use the game's pre-existing modifiers systems to create such an effect.
    2. The three tables the system uses do not know or care about how the dummy building is being used.
     
    Last edited: Jan 5, 2017
    Craig_Sutter likes this.
  3. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    Let me know if the instructions in post #2 on setting up the three new tables are too overheavy and I will try to re-write after I find out what if anything people are struggling with in the instructions.
     
    Last edited: Jan 5, 2017
    Horem likes this.
  4. Horem

    Horem Chieftain

    Joined:
    Apr 1, 2010
    Messages:
    1,707
    Location:
    Wales, UK
    Awesome! :thumbsup:
     
  5. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    Thanks for all your hard work! One question though, why can't the resource requirement table be applied directly to the building that I want the player to see? Why have the extra step of creating a dummy building?
     
  6. PlotinusRedux

    PlotinusRedux Chieftain

    Joined:
    Jul 11, 2013
    Messages:
    196
    He's actually adding and removing the dummy building based on the presence or absence of the required resource in a number of events like PlayerTurnActivated, so it can serve as a the prereq for the real building. If you used the real building rather than the dummy, the player wouldn't actually have to build the real building, it would just magically appear.
     
  7. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    Got it, thanks!
     
  8. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    As @PlotinusRedux said.

    I'm adapting the civ5 method of using dummy buildings to create any number of effects Firaxis did not provide for. In this particular case I'm filling the gap in the civ6 modifiers system discovered with local resources making buildings available, like civ5's Circus requiring Horse or Ivory and Stoneworks requiring Marble or Stone.

    The dummy building acts as the signal to civ6's normal systems that the "real" building is available for construction in a given city.
     
  9. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    If I set the PrereqDistrict for the unlocker buildings to another district other than the City Center would this work properly?
     
  10. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    You want to leave the district as the city center, I think.

    It doesn't seem to matter in anything I've tested which district a building is placed in in order for it to act as a prerequisite for a building that will be placed in a different district. All that seems to matter is that the city have the building.

    If you try to set the district to anything besides the city center for the dummy building, I am not sure how the game will react to trying to place the dummy in the city center (which the lua code is written to do) when the xml-code for the dummy has a different district designation.

    For example, before I tied the Livestock Exchange to a dummy building, I was requiring the city to have a Market before the city could build a Livestock Exchange. I was using the standard Market as the prereq, and the standard market goes in the Commercial Hub. But the Livestock Exchange as I originally created it is a City Center building. I did not see any trouble behavior from the game for having a set-up like this.

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

    The lua that places the dummies does so in the City Center, and does not even look to whether the dummy is specified for a different district than the city center, btw
     
    Last edited: Jan 7, 2017
  11. Lynnes

    Lynnes Chieftain

    Joined:
    Aug 23, 2015
    Messages:
    886
    Very useful, thanks a lot for making it!
     
  12. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    My guess is that it wouldn't work if the lua specifies the district. I didn't even bother testing it. I've incorporated this into my Specialized Industry mod and so far it works great! I'm not a fan of dummy buildings so I've come up with some creative ideas for them. This is actually evolving into a bigger mod than I had originally planned. It looks like I will be releasing this as a new mod that is different from my SI mod. Thanks again:goodjob:
     
  13. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    @LeeS, I have a request. For your next challenge a dummy building that requires terrain and/or features. Currently only wonders have this ability.

    To be more specific, I would like a building that requires a forest.
     
  14. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    1. eeesh! I has created Frankenstien's CodeSystem! :lol:
    2. Serious answer: it shouldn't be terribly hard to do. It's more a question of thinking through whether it would be more expedient to tack it onto this system or make it it's own system, and then checking to see if the available events in lua will provide what is needed.
     
  15. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    I have discovered that when dummy buildings have prereq techs they do not appear in the build menu. Even if the required resource is improved. As soon as the required resource and building prereqs are fulfilled then the dummy building appears in the city building list. This is great for cosmetic reasons.
     
  16. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    you mean in the city's list of buildings ?

    dummy buildings shouldn't be appearing in the list of buildable items regardless of whether there is a prereq tech.
     
  17. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    They appear in the city's list on the left when they are constructed as they should.
    Before I added the prereq techs, the dummy buildings were appearing in the building menu on the right. But clicking on them did nothing.
     
  18. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
  19. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,151
    Location:
    Illinois, USA
    I'll be updating the opening posts of this thread in the near future, but don't use EnabledByReligion="true" in the definition of a dummy building. Use MustPurchase="true" instead. Then you just never actually state a PurchaseYield as part of the dummy building definition in table <Buildings>.

    I was sure this was all working correctly previously, but in the most recent testing of different stuff in the game, using EnabledByReligion="true" without specifying the belief that unlocks the building causes all religious buildings to be unobtainable.
     
  20. UncivilizedGuy

    UncivilizedGuy Civ is brain candy.

    Joined:
    May 24, 2012
    Messages:
    630
    Location:
    Center of the Universe
    Thanks for the update :thumbsup:
     

Share This Page