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

FreeBuildingThisCity XML tag not cooperating..

Discussion in 'Civ5 - Creation & Customization' started by DarkScythe, Aug 5, 2014.

  1. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    Hey there, everyone,

    I'm implementing some new features today, partially to help balance a few things, and after spending a while in Lua, I figured some stuff would be easily handled in XML.

    That is, until Civ said "Lolno."

    Here is the entirety of what I am attempting to do:
    I have a UB. It has a maintenance cost. That means the building is sellable.
    I decided I didn't want this, so I created a new hidden dummy building with a maintenance cost, and removed the maintenance from the UB. I then tell the UB to give out a copy of this dummy building when it's built.

    Problem is.. it seems to refuse to hand out this building.

    Relevant code:
    Code:
    	<BuildingClasses>
    		<Row>
    			<Type>BUILDINGCLASS_MAINTENANCE_DUMMY</Type>
    			<DefaultBuilding>BUILDING_MAINTENANCE_DUMMY</DefaultBuilding>
    		</Row>
    	</BuildingClasses>
    	<Buildings>
    		<Row>
    			<Type>BUILDING_MAINTENANCE_DUMMY</Type>
    			<BuildingClass>BUILDINGCLASS_MAINTENANCE_DUMMY</BuildingClass>
    			<Description>TXT_KEY_BUILDING_MAINTENANCE_DUMMY</Description>
    			<Cost>-1</Cost>
    			<FaithCost>-1</FaithCost>
    			<PrereqTech>NULL</PrereqTech>
    			<GreatWorkCount>-1</GreatWorkCount>
    			<ArtDefineTag>NONE</ArtDefineTag>
    			<MinAreaSize>-1</MinAreaSize>
    			<NeverCapture>true</NeverCapture>
    			<NukeImmune>true</NukeImmune>
    			<HurryCostModifier>-1</HurryCostModifier>
    			<PortraitIndex>0</PortraitIndex>
    			<IconAtlas>CIV_COLOR_ATLAS</IconAtlas>
    			<GoldMaintenance>3</GoldMaintenance>
    		</Row>
    	</Buildings>
    
    I can't seem to find any issues with this, and this building shows up and works properly in the game -- I can hand it out via IGE, and FireTuner, and it works. The problem is that it refuses to be handed out from another working building via:
    Code:
    <FreeBuildingThisCity>BUILDINGCLASS_MAINTENANCE_DUMMY</FreeBuildingThisCity>
    If I replace that with BUILDINGCLASS_LIBRARY, it works fine. It also can't be an issue with handing out a hidden building, because I've successfully done this before. What am I missing?

    Edit:
    I should mention that I have absolutely zero errors in any of my logs related to this.
    I've even gone to lengths to fix the errors about the barbarian horseman, among others.

    I'm about ready to just do this in Lua, and it'll be trivial for me to do so at this point, but it really aggravates me that this simple XML that should work, doesn't.
     
  2. Machiavelli24

    Machiavelli24 Mod creator

    Joined:
    May 9, 2012
    Messages:
    818
    If you aren't seeing anything in your log file check via SQLite manager that the building shows up in the debug database. Use firetuner to check if the city IsHasBuilding().
     
  3. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    I did check SQLite Manager as well, and it shows up in there -- one of the first things I did after checking the logs.

    I will poke FireTuner with the IsHasBuilding() method, though, but I'm not expecting much.

    Curiously, I have another working dummy building I use elsewhere in that same file (but it's handed out via Lua) and if I set the FreeBuildingThisCity to point to its BuildingClass, it works. That stumps me even more, since I more or less copy/pasted that working building as a base to prevent any sort of typos from creeping in.

    Update:

    Okay, I am more confused now. I used a combination of IsHasBuilding() and GetNumRealBuilding() -- the problem is, they return conflicting results!
    Here is what I got:
    (Shrine is set to call the dummy building. Membership dummy is another building that is not called anywhere, being used as a sanity check.)

    Code:
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_SHRINE)
    true
    [B]> UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_MAINTENANCE_DUMMY)
    true[/B]
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_MEMBERSHIP_DUMMY)
    false
    
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_SHRINE)
    1
    [B]> UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_MAINTENANCE_DUMMY)
    0[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_MEMBERSHIP_DUMMY)
    0
    
    ..seriously, what is going on. :/
    Passing a turn doesn't fix this, either.

    Update 2:

    Okay, some more testing.
    I attached a Spy to this hidden building, to give me more visual feedback if this building was being assigned properly.

    Its definition is now:
    Code:
    		<Row>
    			<Type>BUILDING_MAINTENANCE_DUMMY</Type>
    			<BuildingClass>BUILDINGCLASS_MAINTENANCE_DUMMY</BuildingClass>
    			<Cost>-1</Cost>
    			<FaithCost>-1</FaithCost>
    			<PrereqTech>NULL</PrereqTech>
    			<GreatWorkCount>-1</GreatWorkCount>
    			<ArtDefineTag>NONE</ArtDefineTag>
    			<MinAreaSize>-1</MinAreaSize>
    			<NeverCapture>true</NeverCapture>
    			<NukeImmune>true</NukeImmune>
    			<HurryCostModifier>-1</HurryCostModifier>
    			<PortraitIndex>0</PortraitIndex>
    			<IconAtlas>CIV_COLOR_ATLAS</IconAtlas>
    			<GoldMaintenance>3</GoldMaintenance>
    			<ExtraSpies>1</ExtraSpies>
    		</Row>
    
    When giving myself a Shrine, I get a free Spy!
    ...but my maintenance costs have not increased.
    I am thinking that the game doesn't quite like hidden buildings with maintenance costs, or buildings that provide only 1 Gold (as neither scenario resulted in any visible difference to my Gold income.)

    I also suspect the discrepancy I reported before between IsHasBuilding() and GetNumRealBuildings() is that the former seems to catch hidden buildings, (such as the hidden building which provides certain parts of my Civ's UA, which returns 'true' and '0' respectively) while the latter only reports the number of visible buildings.
     
  4. LeeS

    LeeS Imperator Supporter

    Joined:
    Jul 23, 2013
    Messages:
    7,132
    Location:
    Illinois, USA
    Your building works fine. I made it generate a scout and added it as a free building this city via shrines. Scout appears just fine. "Free" in FreeBuildingThisCity also apparently means maintenance free. To be honest I've never looked that closely before.

    [edit]Try <Building_YieldChanges> and put a YIELD_GOLD of -3 in. Then eliminate the GoldMaintenance from the dummy building just to be certain what is creating what effect.
     
  5. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    Ugh. That is annoying.
    Thanks for confirming my suspicion.. I just tested exactly that -- I made my Maintenance Dummy have 300 Gold maintenance cost, and the membership Dummy provide 100 Gold yield.

    I attached each of them to a different building via FreeBuildingThisCity.
    Maintenance Dummy provided the free Spy, but no Maintenance Cost. Manually added another copy of this building via Firetuner, GPT went to -300 (though no second free Spy.)
    Spawned the other building which was supposed to grant the Membership Dummy and the 100 Gold yield, GPT went up to +100.

    In both cases, IsHasBuilding() returned true, but GetNumRealBuilding() returned 0 -- except for when I manually added in another copy of maintenance dummy, in which case GetNumRealBuilding() returned 1. I removed it via Firetuner, and GetNumRealBuilding() returned 0 again, though IsHasBuilding() remained true throughout the test once it was "given" via FreeBuildingThisCity.

    Long story short:
    Firaxis logic says hello. /facepalm.

    Thanks for the help, you two. I'll either just add a SetNumRealBuildings() line in my function, or just scrap the idea entirely. I don't know anyone in their sane mind who would sell a UB anyway; this was more to prevent the case of "What if someone actually does that?"
     
  6. DarkScythe

    DarkScythe Hunkalicious Holo

    Joined:
    May 6, 2014
    Messages:
    804
    Okay, thanks for the suggestion!

    Having a negative yield actually does work, though it looks ugly since you see +-3 for the yield display. However, pushing that change to the hidden building instead seems to have done the trick -- it's now properly given via FreeBuildingThisCity, and it does indeed subtract 3 Gold from the city's yield.

    As an update to this thread, for anyone interested, it appears that indeed, buildings given out for "Free" are free of maintenance costs, even if you explicitly assign them some ridiculous maintenance cost.

    In addition to this, the game's Lua methods also appear to treat these "Free" buildings differently from normal variants -- this explains why GetNumRealBuilding() returned 0, even when IsHasBuilding() returned true. Yes, you have that building, but it isn't REALLY that building.. at least according to Firaxis.

    As a test on this latter point, I recorded results from two (actually three, but forgot to record results from one) World Wonders which provide free buildings using the two available methods: The Great Wall (FreeBuildingThisCity for Walls) and The CN Tower (FreeBuilding Broadcast Tower in all cities.)

    Results are as follows:
    Code:
    [B][U]The CN Tower[/U][/B]
    [B]Before adding anything:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    false
    
    [B]Adding an 'actual' Broadcast Tower:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    1
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    true
    
    [B]Removing 'actual' Broadcast Tower:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    false
    
    [B]Spawning CN Tower, which provides a free Broadcast Tower:[/B]
    [B]> UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    true[/B]
    
    [B]Removing CN Tower, which removes the associated Broadcast Tower with it:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_BROADCAST_TOWER)
    false
    
    ------------------------------------------------------------------------------------------
    
    [B][U]The Great Wall[/U][/B]
    [B]Before adding anything:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_WALLS)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_WALLS)
    false
    
    [B]Adding 'actual' Walls:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_WALLS)
    1
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_WALLS)
    true
    
    [B]Removing 'actual' Walls:[/B]
    > UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_WALLS)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_WALLS)
    false
    
    [B]Spawning Great Wall, which provides free Walls:[/B]
    [B]> UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_WALLS)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_WALLS)
    true[/B]
    
    [B]Removing Great Wall, which leaves Walls intact:[/B]
    [B]> UI.GetHeadSelectedCity():GetNumRealBuilding(GameInfoTypes.BUILDING_WALLS)
    0
    > UI.GetHeadSelectedCity():IsHasBuilding(GameInfoTypes.BUILDING_WALLS)
    true[/B]
    
    I guess if anyone is using GetNumRealBuilding(), please be careful with what you are expecting out of it.
     

Share This Page