This mod makes it so Forts and Citadels increase the "height" of a tile in terms of affecting vision and targeting.
In other words, a fort grants vision as if on a hill, allowing sight past features such as other hills or jungle. This also means that a fort atop a hill grants vision past obstructed terrain such as a forest hill.
Workshop Link: Forts and Citadels Increase Sight Height
This is my first mod ever! I drew most of my inspiration from whoward69's [DLL/C++] Adding new columns to the database tutorial. Thanks to all of you for being an awesome community.
Here are the steps I followed for creating this mod:
However, it is not yet complete. There are two things I would like this amazing community's help with.
1. This mod makes forts on a hills grant vision and targeting of tiles past mountains. This feels a bit ridiculous and overpowered, but I haven't found how to circumvent it.
I tried changing the default value received from GC.getMOUNTAIN_SEE_THROUGH_CHANGE() from 2 to 3 (called under int CvPlot::seeThroughLevel), but that didn't seem to work.
2. While I am proud and happy about this mod, the fact that it alters the games Core DLL really limits using it with other mods. For example, I wish I could use it with whoward69's Passable Forts mod and JdH's Active AI Diplomacy in MP mod. Would there be no other way other than to manually merge the CoreDLL source codes, compile it, create a new modpack for it and then send it to my friends? What do you suggest?
How would I go about getting assistance? I don't know how to use github or anything, or which files I should share and where.
Any input is welcome!
In other words, a fort grants vision as if on a hill, allowing sight past features such as other hills or jungle. This also means that a fort atop a hill grants vision past obstructed terrain such as a forest hill.
Workshop Link: Forts and Citadels Increase Sight Height
This is my first mod ever! I drew most of my inspiration from whoward69's [DLL/C++] Adding new columns to the database tutorial. Thanks to all of you for being an awesome community.
Here are the steps I followed for creating this mod:
Spoiler :
My first order of business was figuring out just why hills granted vision past obstacles. After much digging around the game's inner workings, I found what I was looking for in the core DLL's CvPlot.cpp code. Specifically, under the CvPlot::seeFromLevel int.
I needed to find a way to have forts increment this iLevel value if one was present on the plot involved. In order to do that, I added a new column to the Improvements XML table, called SeeFrom, similar to the one used in the Terrains or Features XML tables.
I then changed this value to 1 for Forts and Citadels
The next step was to make the game recognize these new table entries as valid Improvement values. I used the fort's DefenseModifier as a clue to where in the source code I needed to add my new SeeFrom Improvement table entry. The trail led me to CvImprovementClasses.cpp and CvImprovementClasses.h. Everywhere I saw a reference to DefenseModifier, I added my SeeFrom reference under it.
CvImprovementClasses.h
CvImprovementClasses.cpp
The next step was the most interesting: I needed to figure out a way to increment CvPlot::seeFromLevel's iLevel using Improvement code. As I am clueless in programming, I dug around some more and felt that my best bet would be finding out how the game determines a tile's defensive bonus, as that makes use of everything present on a plot: The terrain, the feature, and most importantly, the improvement; more specifically, the fort. I found this information deeper down in CvPlot.cpp, under int CvPlot::defenseModifier. In it, we find the following:
This tells us that we can use a CvImprovementEntry* variable to increment an integer for a plot using an improvement. Exactly what I needed!
A few deductions later, I added the following under the infamous CvPlot::seeFromLevel
After this, I compiled the DLL wrapped up my mod, wanting to see what would happen. To my shock and disbelief, it just worked! I was floored an ecstatic.
Code:
int CvPlot::seeFromLevel(TeamTypes eTeam) const
{
int iLevel;
CvAssertMsg(getTerrainType() != NO_TERRAIN, "TerrainType is not assigned a valid value");
// Plot recon-ed?
if(getReconCount() > 0)
{
iLevel = GC.getRECON_VISIBILITY_RANGE() * 2;
}
// Normal visibility
else
{
iLevel = GC.getTerrainInfo(getTerrainType())->getSeeFromLevel();
}
if(isMountain())
{
iLevel += GC.getMOUNTAIN_SEE_FROM_CHANGE();
}
if(isHills())
{
iLevel += GC.getHILLS_SEE_FROM_CHANGE();
}
if(isWater())
{
iLevel += GC.getSEAWATER_SEE_FROM_CHANGE();
if(GET_TEAM(eTeam).isExtraWaterSeeFrom())
{
iLevel++;
}
}
return iLevel;
}
Code:
ALTER TABLE Improvements
ADD SeeFrom INTEGER DEFAULT 0;
Code:
<GameData>
<Improvements>
<Update>
<Where Type="IMPROVEMENT_FORT"/>
<Set SeeFrom="1"/>
</Update>
<Update>
<Where Type="IMPROVEMENT_CITADEL"/>
<Set SeeFrom="1"/>
</Update>
</Improvements>
</GameData>
The next step was to make the game recognize these new table entries as valid Improvement values. I used the fort's DefenseModifier as a clue to where in the source code I needed to add my new SeeFrom Improvement table entry. The trail led me to CvImprovementClasses.cpp and CvImprovementClasses.h. Everywhere I saw a reference to DefenseModifier, I added my SeeFrom reference under it.
CvImprovementClasses.h
Code:
!-- under class CvImprovementEntry
int GetDefenseModifier() const;
//Elevated Forts
int GetSeeFrom() const;
Code:
int m_iDefenseModifier;
//Elevated Forts
int m_iSeeFrom;
CvImprovementClasses.cpp
Code:
!-- under CvImprovementEntry::CvImprovementEntry(void):
m_iDefenseModifier(0),
// Elevated Forts
m_iSeeFrom(0),
Code:
!-- under bool CvImprovementEntry::CacheResults
m_iDefenseModifier = kResults.GetInt("DefenseModifier");
//Elevated Forts
m_iSeeFrom = kResults.GetInt("SeeFrom");
Code:
/// Modifier for the defensive improvement this improvement provides
int CvImprovementEntry::GetDefenseModifier() const
{
return m_iDefenseModifier;
}
/// SeeFrom height (Elevated Forts)
int CvImprovementEntry::GetSeeFrom() const
{
return m_iSeeFrom;
}
The next step was the most interesting: I needed to figure out a way to increment CvPlot::seeFromLevel's iLevel using Improvement code. As I am clueless in programming, I dug around some more and felt that my best bet would be finding out how the game determines a tile's defensive bonus, as that makes use of everything present on a plot: The terrain, the feature, and most importantly, the improvement; more specifically, the fort. I found this information deeper down in CvPlot.cpp, under int CvPlot::defenseModifier. In it, we find the following:
Code:
ImprovementTypes eImprovement;
int iModifier;
!-- [...]
{
eImprovement = getImprovementType();
}
if(eImprovement != NO_IMPROVEMENT && !IsImprovementPillaged())
{
if(eDefender != NO_TEAM && (getTeam() == NO_TEAM || GET_TEAM(eDefender).isFriendlyTerritory(getTeam())))
{
CvImprovementEntry* pkImprovement = GC.getImprovementInfo(eImprovement);
if (pkImprovement)
iModifier += pkImprovement->GetDefenseModifier();
}
}
This tells us that we can use a CvImprovementEntry* variable to increment an integer for a plot using an improvement. Exactly what I needed!
A few deductions later, I added the following under the infamous CvPlot::seeFromLevel
Code:
// Elevated Forts
ImprovementTypes eImprovement;
eImprovement = getImprovementType();
if(eImprovement != NO_IMPROVEMENT && !IsImprovementPillaged())
{
CvImprovementEntry* pkImprovement = GC.getImprovementInfo(eImprovement);
if (pkImprovement)
{
iLevel += pkImprovement->GetSeeFrom();
}
}
After this, I compiled the DLL wrapped up my mod, wanting to see what would happen. To my shock and disbelief, it just worked! I was floored an ecstatic.
However, it is not yet complete. There are two things I would like this amazing community's help with.
1. This mod makes forts on a hills grant vision and targeting of tiles past mountains. This feels a bit ridiculous and overpowered, but I haven't found how to circumvent it.
I tried changing the default value received from GC.getMOUNTAIN_SEE_THROUGH_CHANGE() from 2 to 3 (called under int CvPlot::seeThroughLevel), but that didn't seem to work.
2. While I am proud and happy about this mod, the fact that it alters the games Core DLL really limits using it with other mods. For example, I wish I could use it with whoward69's Passable Forts mod and JdH's Active AI Diplomacy in MP mod. Would there be no other way other than to manually merge the CoreDLL source codes, compile it, create a new modpack for it and then send it to my friends? What do you suggest?
How would I go about getting assistance? I don't know how to use github or anything, or which files I should share and where.
Any input is welcome!