CityStyles: Between ArtStyleType and Culture name... Nothing?

Leugi

Supreme Libertador
Joined
Jan 25, 2013
Messages
1,675
Location
Bolivia
So... Deliverator's new Nexus Buddy allows to replace multiple models in a single gr2; which probably enables the possibility of custom city-styles at least when talking of specifically model barriers.

With that in mind, I have decided to attempt adding an ArtStyleType and all that fuss. There's good and bad news.

To add a new Artstyle ID one simply does this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<GameData>
	<ArtStyleTypes>
		<Row>
			<Type>ARTSTYLE_TESTEAN</Type>
		</Row>		
	</ArtStyleTypes>
</GameData>

("testean" as in, from test :p ) So, I assigned this to a civilization; and then I used Lua to check the ArtStyleType ID said civilization was used (normally, the last ID is 6, being the ruined city style)... And, amazingly, the ID of the player's ArtStyleType ID was 7! That means, one can add ArtStyleTypes with mods.

Interestingly, the new type defaulted all art to European (which is odd too, given that European isn't the id 0 or anything) (also,when an unexistant ArtStyleType is assigned, it also defaults the art to European, but its ID through lua returns -1 ; so I know this one was rightly assigned)... So, that part is good :cool:.

--

Part 2 of my test was, using Polynesia's kind of file to see if I can change the gr2 files or something. After all my tests, not even setting a file with the same name ("Civ5ArtDefines_CityBuildings_Polynesia.xml") with VFS=True works, so one has to edit the file directly... Editing the file directly I managed to make ArtStyleType Polynesia to use Mediterranean modern buildings in ancient times! :crazyeye: :

Code:
<?xml version="1.0" encoding="utf-8"?>
<BuildingArtInfos>
	<!-- Polynesian ************************************************************ -->
	<Culture name="Polynesian" lighting="Asia">
		<Era name="Ancient">
			<PopulationBuildings>
				<Granny>Medit_Mod_City.gr2</Granny>
			</PopulationBuildings>
		</Era>
		<Era name="Rennaisance">
			<PopulationBuildings>
				<Granny>Poly_Ren_City.gr2</Granny>
			</PopulationBuildings>
		</Era>
		<Era name="Industrial">
			<PopulationBuildings>
				<Granny>Poly_Ind_City.gr2</Granny>
			</PopulationBuildings>
		</Era>
		<Era name="Modern">
			<PopulationBuildings>
				<Granny>Poly_Mod_City.gr2</Granny>
			</PopulationBuildings>
		</Era>
	</Culture>
	<!-- Polynesian 
</BuildingArtInfos>

So... the file is functional... making custom citystyles would require Polynesia DLC, but that's not a huge problem.

Next part of the test was to change the Culture name = "Polynesian"... I was assuming there was an automatic naming thing like with Music... so Culture name = "Polynesian" links automatically to ARTSTYLE_POLYNESIAN ; but I was terribly wrong... First because that's not how it works for Mediterranean (Culture name = "Mediterranean" , but ARTSTYLE_GRECO_ROMAN)... So creating a Culture name = "Testean" didn't work at all...

So... I then changed Polynesian to whatever (to Culture name = "Polychromatic" just for fun)... Ingame it defaulted to Native American citystyle (this one's more explainable, American is the first style being defined in BuildingArtInfos it seems)... Which means that somehow there's a mysterious way ARTSTYLE manages to connect with a specific Culture name...

Therefore... the next step forward would be finding whatever on earth links a specific Culture name with a specific ArtStyleType... It definitively isn't automatic like music... so there's some other background linking (probably DLL?)

TLDR: We can create an ArtStyleType ID... and we can create a Culture name... we just can't seem to link them both to have a working custom City Style. :sad: (yet)

Anyone knows where should I look for that? A schema? A hidden table column? or something? Anyone can find that? :confused:

As you can notice, I'm not particularly focused on compatibility here, so any answer will do really ;)

EDIT: Also found this on CvEnums.h (no idea what it is)
Code:
enum CultureTypes
{
	NULL_CULTURE = -1, 

	CULTURE_AMERICA,
	CULTURE_ASIA,
	CULTURE_AFRICA,
	CULTURE_EUROPE,
	CULTURE_MED,
	CULTURE_POLY,

	CULTURE_NONE,

	CULTURE_MAX,
};

After finding that DLL .h thing I made another test... Changed the ArtStyleType from ARTSTYLE_ASIA to whatever... and it kept its relationship to Asia, so Asian buildings ingame! ... this means that the mysterious link is somehow related to ID number.

So... possibly the enumeration on the DLL is somehow linked to the ID and thus to the Culture name... However, where are CultureTypes linked to Culture names on BuildingArtInfos... without wanting it I already tested the first letters... (when I changed the culture name of Polynesia it was to Polychromatic ; and the CultureType is CULTURE_POLY, they still share the same letters... so no luck)
 
Well, that's disappointing. So, the Culture types are hardcoded, so you'll need a custom DLL to add new ones. However, can you use CULTURE_NONE and/or CULTURE_MAX for your purposes?

EDIT: ...plus it looks like you'll at least need a fake DLC to pull it off...
 
So, the one I added would technically be related to CULTURE_MAX (Culture None seems to have the same number as the Ruined city-style)... However I had no luck for it, setting Culture name = Max didn't work sadly...

So yeah, it seems I need the help of someone with DLL editing skills for this (plus yeah, DLC)
 
I failed to change city model too, but we can try this
Maybe you can move your files into this folder:
SteamApps\common\Sid Meier's Civilization V\Assets\DLC\Expansion\DLC\Expansion

the <BuildingArtInfos> table and all buildings models are loaed when civ5 start, when you active mod, it won't reload, so you need to copy all building/citystyle model and xml files into game dir

I'm not sure if this can work for a new ArtStyle, but should be able to replace existing ones
 
So I'm looking through the DLL, and while I'm not a DLL modder, I'll try to trace how ARTSTYLE_ tags link up with 'Culture' tags.

------------------------------------------------------------
GetArtInfoCulturalVariation(): This just returns a boolean, so I guess it's just checking if there are building variants. Probably not terribly useful to us.

CvBuildingClasses.h:
Line 229 (BNW):
Code:
const bool GetArtInfoCulturalVariation() const;

CvBuildingClasses.cpp:
Line 1534 (BNW):
Code:
/// Return whether we should try to find a culture specific variant art tag
const bool CvBuildingEntry::GetArtInfoCulturalVariation() const
{
	return m_bArtInfoCulturalVariation;
}

CvDllBuildingInfo.h:
Line 35:
Code:
const bool DLLCALL GetArtInfoCulturalVariation() const;

CvDllBuildingInfo.cpp:
Line 104:
Code:
const bool CvDllBuildingInfo::GetArtInfoCulturalVariation() const
{
	return m_pBuildingInfo->GetArtInfoCulturalVariation();
}
---------------------------------------------------------------------
getArtStyleType(): This function returns an integer or ArtStyleTypes, and has an interface with Lua. I think this is what we're looking for.

CvDllCivilizationInfo.h:
Line 36:
Code:
int DLLCALL GetArtStyleType();

CvDllCivilizationInfo.cpp:
Line 110:
Code:
int CvDllCivilizationInfo::GetArtStyleType()
{
	return m_pCivilizationInfo->getArtStyleType();
}

(and similar for CvDllMinorCivInfo)

CvDllPlayer.h:
Line 36:
Code:
ArtStyleTypes DLLCALL GetArtStyleType() const;

CvDllPlayer.cpp:
Line 134:
Code:
ArtStyleTypes CvDllPlayer::GetArtStyleType() const
{
	return m_pPlayer->getArtStyleType();
}

CvCity.h:
Line 243:
Code:
ArtStyleTypes getArtStyleType() const;

CvCity.cpp:
Line 6435:
Code:
ArtStyleTypes CvCity::getArtStyleType() const
{
	VALIDATE_OBJECT
	return GET_PLAYER(getOwner()).getArtStyleType();
}

CvPlayer.h:
Line 144:
Code:
ArtStyleTypes getArtStyleType() const;

CvPlayer.cpp:
Line 4025:
Code:
ArtStyleTypes CvPlayer::getArtStyleType() const
{
	if(CvPreGame::artStyle(GetID()) == NO_ARTSTYLE)
	{
		return ((ArtStyleTypes)(getCivilizationInfo().getArtStyleType()));
	}
	else
	{
		return CvPreGame::artStyle(GetID());
	}
}

CvInfos.h: (header for CvCivilizationInfo)
Line 591:
Code:
int getArtStyleType() const;

CvInfos.cpp:
Line 2064:
Code:
int CvCivilizationInfo::getArtStyleType() const
{
	return m_iArtStyleType;
}


CvMinorCivAI.h: (header for CvMinorCivInfo)
Line 614:
Code:
int getArtStyleType() const;

CvMinorCivAI.cpp
Line 9866:
Code:
int CvMinorCivInfo::getArtStyleType() const
{
	return m_iArtStyleType;
}
 
setArtStyle(): Function that appears to set the artstyle for buildings and cities. setArtStylePrefix() and setArtStyleSuffix() are related, but since they deal more with other types of assets, I don't think they are relevant.

CvPreGame.h:
Line 177:
Code:
void setArtStyle(PlayerTypes p, ArtStyleTypes a);

CvPreGame.cpp
Line 2265:
Code:
void setArtStyle(PlayerTypes p, ArtStyleTypes a)
{
	if(p >= 0 && p < MAX_PLAYERS)
		s_artStyles.setAt(p, a);
}

---------------------------------------------------------------------------
artStyle(): Not totally sure about this one, but it seems to relate players to a particular artstyle. s_artStyles appears to be save/load data.

CvPregame.h:
Line 54:
Code:
ArtStyleTypes artStyle(PlayerTypes p);

CvPregame.cpp:
Line 662:
Code:
ArtStyleTypes artStyle(PlayerTypes p)
{
	if(p >= 0 && p < MAX_PLAYERS)
		return s_artStyles[p];
	return NO_ARTSTYLE;
}

CvPregame.cpp:
Line 194:
Code:
PREGAMEVAR(std::vector<ArtStyleTypes>,         s_artStyles,              MAX_PLAYERS);

---------------------------------------------------------------------------
m_iArtStyleType: Again, not totally sure what this is, but it seems to confirm that this group of methods is in fact related to the ArtStyleType tag in the XML.

CvInfos.cpp:
Line 1978:
Code:
m_iArtStyleType(NO_ARTSTYLE),

CvInfos.cpp: (something to do with caching CvCivilizationInfo)
Line 2238:
Code:
szTextVal = kResults.GetText("ArtStyleType");
m_iArtStyleType = GC.getInfoTypeForString(szTextVal, true);

(More to come...)
 
Interesting! Hopefully actually delving into the dll and trying to change stuff will help, as many mods are lately using custom dll's anyway (Piety and Prestige is my favorite of such)...

However, I think the issue is more related to the database for cultures being fixed. So even if you add something on the xml/sql thingy it won't even exist, as the code will not read beyond the fixed number of maximum citystyles:

Also found this on CvEnums.h (no idea what it is)
Code:
enum CultureTypes
{
	NULL_CULTURE = -1, 

	CULTURE_AMERICA,
	CULTURE_ASIA,
	CULTURE_AFRICA,
	CULTURE_EUROPE,
	CULTURE_MED,
	CULTURE_POLY,

	CULTURE_NONE,

	CULTURE_MAX,
};

After finding that DLL .h thing I made another test... Changed the ArtStyleType from ARTSTYLE_ASIA to whatever... and it kept its relationship to Asia, so Asian buildings ingame! ... this means that the mysterious link is somehow related to ID number.

So... possibly the enumeration on the DLL is somehow linked to the ID and thus to the Culture name... However, where are CultureTypes linked to Culture names on BuildingArtInfos... without wanting it I already tested the first letters... (when I changed the culture name of Polynesia it was to Polychromatic ; and the CultureType is CULTURE_POLY, they still share the same letters... so no luck)
 
Right, but the DLL has to read in the XML city buildings data in somewhere. I've traced m_pBuildingInfo to some gDLL->(stuff) calls, so I think wherever the city building graphics are being loaded is not included in the SDK source available to us. Sad panda. I think even if we just had an XML schema for BuildingArtInfos, we'd be able to pull it off.

Considering that IDs are automatically created in the available XML files, it's kind of weird that they'd enumerate them in the DLL as well. It seems like it's redundant, doesn't it?

It's odd, I think for Civ 4, the entire SDK, including all the graphical stuff, was released fairly soon compared to Civ 5.
 
It's odd, I think for Civ 4, the entire SDK, including all the graphical stuff, was released fairly soon compared to Civ 5.

I believe this was for marketing purposes; due to this, the Civ 5 DLC Civilizations didn't have to compete with high-quality mods. It was safe to release the DLL after this phase was over.
 
Top Bottom