Quick Modding Questions Thread

DoC has conditional city art styles (based on majority culture instead of owner, but that can be easily changed to civics or anything else really) in the DLL, including caching (no need to waste performance every time the screen is redrawn). I ran into some pitfalls you could avoid, the source code is here. Just work your way backwards from the CvCity::getArtStyle() method.
 
@Nightinggale
I will try to make this, something i maybe don't said, i want to change city artstyle, not units.
Oops, didn't read your first post correctly. However cities work the same way. You most likely want to edit CvCity::getArtStyleType(). Maybe it would be best to call CvPlayer::getCityArtStyleType() and then write that new function to do precisely what you want. That way you have access to the player data rather than the city data.

Something like (pseudo code)
PHP:
CivilizationTypes& kCiv = GC.getCivilizationInfo();
if (hasCivic(CIVIC_HARMONY) && kCiv.getCityStyle(CIVIC_HARMONY).size > 0)
    return kCiv.getCityStyle(CIVIC_HARMONY)
else if (hasCivic(CIVIC_PURITY) && kCiv.getCityStyle(CIVIC_PURITY).size > 0)
    return kCiv.getCityStyle(CIVIC_PURITY)

(more checks)

// fallback in case nothing triggers 
return getArtStyleType();
I think that should do it as long as you add CvCivilizationInfo::getCityStyle, which will return strings from xml. It even has check for valid strings and a fallback, which mean you don't have to fill out the xml data for all civs for this to work. If you just want it for a single one, fill it out for a single one and the rest will be unaffected.

This should work, at least in theory. It's quite possible that it could be written a bit better than this. I just wrote this quickly without any real checks other than how city arty style works. It's more of a concept than actual code.

EDIT
Once again somebody writes while I'm typing.

including caching (no need to waste performance every time the screen is redrawn). I ran into some pitfalls you could avoid
I thought about caching as well. However I decided to keep it simple. Maybe the best solution is to cache the city style string in CvPlayer and get CvCity to read that string. It's just a matter of a single string, which can only be changed by doCivic as the style is the same for all cities. DoC appears to have one style for each city (possibly), which mean a single style cache for each player wouldn't work. However with the option of copy pasting existing code, it might still be the way to go, even if the cache isn't the best suited for your needs.
 
How i can see m_iArtStyleType from CvInfos.cpp is main responsible for city art style,
because in CvCity.cpp has ArtStyleTypes CvCity::getArtStyleType() const, which return PLAYER'S .getArtStyleType() from CvPlayer.cpp
from this method ArtStyleTypes CvPlayer::getArtStyleType() const and here return m_iArtStyleType this line 'return ((ArtStyleTypes)(GC.getCivilizationInfo(getCivilizationType()).getArtStyleType()));' from CvInfos.cpp


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

On begging he get value here:
CvInfos.cpp:
Code:
	pXML->GetChildXmlValByName(szTextVal, "ArtStyleType");
	m_iArtStyleType = GC.getTypesEnum(szTextVal);

CvInfos.h
Code:
[COLOR="Blue"]protected:[/COLOR]
	...
	int m_iArtStyleType;

CvCity.cpp
Code:
ArtStyleTypes CvCity::getArtStyleType() const
{
	return GET_PLAYER(getOwnerINLINE()).getArtStyleType();
}

CvPlayer.cpp
Code:
ArtStyleTypes CvPlayer::getArtStyleType() const
{
	if (GC.getInitCore().getArtStyle(getID()) == NO_ARTSTYLE)
	{
		return ((ArtStyleTypes)(GC.getCivilizationInfo(getCivilizationType()).getArtStyleType()));
	}
	else
	{
		return GC.getInitCore().getArtStyle(getID());
	}
}

1) if change m_iArtStyleType in CvInfos.cpp during the game, is that affect on all cities from that player in game ?

2) I am little bit confused, i already asked for trigger when and where player change CIVIC in .cpp ? I must in the moment when player switch to another civic, then i must change m_iArtStyleType. And in that part of code i can implement @Nightinggale pseudo code.

3) Player and civilization get ArtStyleType from XML, i must change that ArtStyleType, it same like when you make map in world builder and change artstyle for players or change name etc, example:

Code:
BeginPlayer
	Team=12
	LeaderType=LEADER_MANSA_MUSA
	LeaderName=TXT_KEY_LEADER_MANSA_MUSA
	CivDesc=TXT_KEY_CIV_MALI_DESC
	CivShortDesc=TXT_KEY_CIV_MALI_SHORT_DESC
	CivAdjective=TXT_KEY_CIV_MALI_ADJECTIVE
	FlagDecal=Art/Interface/TeamColor/FlagDECAL_Mask.dds
	WhiteFlag=0
	CivType=CIVILIZATION_MALI
	Color=PLAYERCOLOR_PEACH
	[B][COLOR="Red"]ArtStyle=ARTSTYLE_AFRICA[/COLOR][/B]
	PlayableCiv=1
	MinorNationStatus=0
	StartingGold=0
	StartingX=85, StartingY=51
	StateReligion=
	StartingEra=ERA_ANCIENT
	RandomStartLocation=false
	CivicOption=CIVICOPTION_GOVERNMENT, Civic=CIVIC_DESPOTISM
	CivicOption=CIVICOPTION_LEGAL, Civic=CIVIC_BARBARISM
	CivicOption=CIVICOPTION_LABOR, Civic=CIVIC_TRIBALISM
	CivicOption=CIVICOPTION_ECONOMY, Civic=CIVIC_DECENTRALIZATION
	CivicOption=CIVICOPTION_RELIGION, Civic=CIVIC_PAGANISM
	CivicOption=CIVICOPTION_POLITICAL_PARTY, Civic=CIVIC_NO_POLITICAL_PARTY
	Handicap=HANDICAP_NOBLE
EndPlayer
changed to HARMONY
Code:
BeginPlayer
	Team=12
	LeaderType=LEADER_MANSA_MUSA
	LeaderName=TXT_KEY_LEADER_MANSA_MUSA
	CivDesc=TXT_KEY_CIV_MALI_DESC
	CivShortDesc=TXT_KEY_CIV_MALI_SHORT_DESC
	CivAdjective=TXT_KEY_CIV_MALI_ADJECTIVE
	FlagDecal=Art/Interface/TeamColor/FlagDECAL_Mask.dds
	WhiteFlag=0
	CivType=CIVILIZATION_MALI
	Color=PLAYERCOLOR_PEACH
	[B][COLOR="Red"]ArtStyle=ARTSTYLE_HARMONY[/COLOR][/B]
	PlayableCiv=1
	MinorNationStatus=0
	StartingGold=0
	StartingX=85, StartingY=51
	StateReligion=
	StartingEra=ERA_ANCIENT
	RandomStartLocation=false
	CivicOption=CIVICOPTION_GOVERNMENT, Civic=CIVIC_DESPOTISM
	CivicOption=CIVICOPTION_LEGAL, Civic=CIVIC_BARBARISM
	CivicOption=CIVICOPTION_LABOR, Civic=CIVIC_TRIBALISM
	CivicOption=CIVICOPTION_ECONOMY, Civic=CIVIC_DECENTRALIZATION
	CivicOption=CIVICOPTION_RELIGION, Civic=CIVIC_PAGANISM
	CivicOption=CIVICOPTION_POLITICAL_PARTY, Civic=CIVIC_NO_POLITICAL_PARTY
	Handicap=HANDICAP_NOBLE
EndPlayer
and Mansa Musa of Mali will now have ARTSTYLE_HARMONY instead ARTSTYLE_AFRICA, and i must change that variable 'ArtStyle=' in the moment during player switch to another civic, somewhere in source code.
 
Is there a way to make a melee land unit that cannot defend but can still attack (similar to a guided missile)?
 
I make what i want, but its work on way on which i don't want to work. And of course this is just prototype version. Civilization get new city art when player switch to any civic (that is for now), but this new city art stay for that civilization, for example:

- I play with CHINA, and CHINA have ASIAN city style, when i switch to any civic, CHINA get ARABIAN city style, if i return to main menu and again start some new game with CHINA, CHINA have ARABIAN city style, instead of ASIAN.

- If i save game when CHINA have ASIAN city style, and change my civic, and CHINA get ARABIAN city style, and i go to load game, CHINA now have ARABIAN city style instead of ASIAN city style.

- CHINA only again get their default city style (ASIAN), if i exit from my mod, and load my mod again.

NEW CODE

CvPlayer.cpp:
Code:
void CvPlayer::setCivics(CivicOptionTypes eIndex, CivicTypes eNewValue)
{
	CvWString szBuffer;
	CivicTypes eOldCivic;
	int iI;

	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < GC.getNumCivicOptionInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");
	FAssertMsg(eNewValue >= 0, "eNewValue is expected to be non-negative (invalid Index)");
	FAssertMsg(eNewValue < GC.getNumCivicInfos(), "eNewValue is expected to be within maximum bounds (invalid Index)");

	eOldCivic = getCivics(eIndex);

	if (eOldCivic != eNewValue)
	{
		m_paeCivics[eIndex] = eNewValue;

		if (eOldCivic != NO_CIVIC)
		{
			processCivics(eOldCivic, -1);
		}
		if (getCivics(eIndex) != NO_CIVIC)
		{
			processCivics(getCivics(eIndex), 1);
		}

		GC.getGameINLINE().updateSecretaryGeneral();

		GC.getGameINLINE().AI_makeAssignWorkDirty();

		if (GC.getGameINLINE().isFinalInitialized())
		{
			if (gDLL->isDiplomacy() && (gDLL->getDiplomacyPlayer() == getID()))
			{
				gDLL->updateDiplomacyAttitude(true);
			}

/************************************************************************************************/
/* REVOLUTION_MOD                         04/28/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
/*
			if (!isBarbarian())
*/
			// Silence announcement for civs that are not alive, ie rebel civs who may not be born
			// and also for minor civs
			if (!isBarbarian() && !isMinorCiv() && isAlive())
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
			{
				if (getCivics(eIndex) != NO_CIVIC)
				{
					if (getCivics(eIndex) != GC.getCivilizationInfo(getCivilizationType()).getCivilizationInitialCivics(eIndex))
					{
						for (iI = 0; iI < MAX_PLAYERS; iI++)
						{
							if (GET_PLAYER((PlayerTypes)iI).isAlive())
							{
								if (GET_TEAM(getTeam()).isHasMet(GET_PLAYER((PlayerTypes)iI).getTeam()))
								{
									szBuffer = gDLL->getText("TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC", getNameKey(), GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide());
									gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CIVIC_ADOPT", MESSAGE_TYPE_MAJOR_EVENT);
								}
							}
						}

						szBuffer = gDLL->getText("TXT_KEY_MISC_PLAYER_ADOPTED_CIVIC", getNameKey(), GC.getCivicInfo(getCivics(eIndex)).getTextKeyWide());
						GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getID(), szBuffer);
					}
[COLOR="SeaGreen"]// < ZLATKO RECONSTRUCTION START > EXPERIMENT[/COLOR]
					[COLOR="Red"]GC.getCivilizationInfo(getCivilizationType()).setArtStyleType(2);[/COLOR]
[COLOR="SeaGreen"]// < ZLATKO RECONSTRUCTION END >[/COLOR]
				}
			}
		}

/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      09/03/09                       poyuzhe & jdog5000     */
/*                                                                                              */
/* Efficiency                                                                                   */
/************************************************************************************************/
		// From Sanguo Mod Performance, ie the CAR Mod
		// Attitude cache
		for (int iI = 0; iI < MAX_PLAYERS; iI++)
		{
			GET_PLAYER(getID()).AI_invalidateAttitudeCache((PlayerTypes)iI);
			GET_PLAYER((PlayerTypes)iI).AI_invalidateAttitudeCache(getID());
		}
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/

	}
}

CvInfos.h:
Code:
class CvArtInfoCivilization;
class CvCivilizationInfo :
	public CvInfoBase
{
	//---------------------------------------PUBLIC INTERFACE---------------------------------
public:
	....
[COLOR="SeaGreen"]// < ZLATKO RECONSTRUCTION START > EXPERIMENT[/COLOR]
	[COLOR="Red"]void setArtStyleType(int m_iArtStyleType);[/COLOR]
[COLOR="SeaGreen"]// < ZLATKO RECONSTRUCTION END >[/COLOR]
	....
};

CvInfos.cpp:
Code:
// < ZLATKO RECONSTRUCTION START > EXPERIMENT
void CvCivilizationInfo::setArtStyleType(int m_iArtStyleType)
{
	this->m_iArtStyleType = m_iArtStyleType;
}
// < ZLATKO RECONSTRUCTION END >
 
Is there a way to make a melee land unit that cannot defend but can still attack (similar to a guided missile)?
AI range attack thread: http://forums.civfanatics.com/showthread.php?t=558723
I'm not sure how tricky it is to set up, but if you can somehow set combat power to 0 and range attack to something else, it will likely provide the result you are looking for. I would love to tell you more, but figuring out the code for range attack is on my todo list. If anybody has documentation on how it works, then I would love to see it.
 
What is it with me and posting together with other people today? Now it's the 3rd time in one day in the same thread :crazyeye:

- If i save game when CHINA have ASIAN city style, and change my civic, and CHINA get ARABIAN city style, and i go to load game, CHINA now have ARABIAN city style instead of ASIAN city style.
Sounds like you fail to save the variable. YOu need to add the new variable to CvPlayer::read() and write(). Order matters and you will break old savegames, unless you write some backward compatibility code using uiFlag.

Code:
[COLOR="Red"]GC.getCivilizationInfo(getCivilizationType()).setArtStyleType(2);[/COLOR]
I would recommend using an enum if you want to hardcode numbers into the DLL and XML values if you want it to be modder friendly. Using numbers like 2 will not only make the code unreadable, it will also haunt you later on if you need to change something.
 
What programs do people commonly use to edit XML files? I'm not really happy with my current way of just doing it with the default Editor.
 
What programs do people commonly use to edit XML files? I'm not really happy with my current way of just doing it with the default Editor.
Notepad++ is my program of choice.
 
What programs do people commonly use to edit XML files? I'm not really happy with my current way of just doing it with the default Editor.
Civ4 XML editor is useful for people who aren't that happy with editing xml files directly. Just be aware that it only shows tags already present in the file. This mean tags set to minOccurs="0" in the schema might not show up. At least that was the case when I tried it. I usually use notepad++.
http://forums.civfanatics.com/showthread.php?t=270586
 
Thanks for the tip you two, Notepad++ is awesome! I have no idea how I ever got around without it!
 
Thanks for the tip you two, Notepad++ is awesome! I have no idea how I ever got around without it!
No worries, and I feel the same about Notepad++. So much better than the normal text editor.
 
The only bad thing about Notepad++ is that it is Windows only.
 
The only bad thing about Notepad++ is that it is Windows only.
That goes for most of the tools. Also mods tend to be windows only due to dll modifications, which mean most modders should already be able to run exe files.

If you know how to make a dll modification, which works on non-windows without windows emulation like wine, then do tell.
 
If you know how to make a dll modification, which works on non-windows without windows emulation like wine, then do tell.
I wish. I've always wondered if you could compile .so files from the C++ but then I don't even know how Civ4 for Mac is set up.

For Notepad++ I was mostly talking about how much I prefer it over any text editor that is prolific on Linux.
 
If you know how to make a dll modification, which works on non-windows without windows emulation like wine, then do tell.

I wish. I've always wondered if you could compile .so files from the C++ but then I don't even know how Civ4 for Mac is set up.

The DLL is hardcoded into the application itself in the Mac version of Civ4. So even if you could compile an OS X compatible DLL, Civ4 will just ignore it.
 
The DLL is hardcoded into the application itself in the Mac version of Civ4. So even if you could compile an OS X compatible DLL, Civ4 will just ignore it.
How nice of Firaxis.
 
The only bad thing about Notepad++ is that it is Windows only.

Oh well, sincere condolences to the people on Linux and a heartfelt "HAHA" to the drones of the fruit company.
 
Back
Top Bottom