Applying Individual Names to Improvements/Buildings

LPlate2

Warlord
Joined
Dec 27, 2018
Messages
299
Units and cities can be renamed.
What would it take to allow for renaming of improvements and buildings?
e.g. There are five mines on the map and you want to change the name of one (during the game), using python, to be described as “Bob’s Mine”, instead of “Mine”, but want the others to remain as they are.
 
Edit: I think I can accomplish what I want by creating an additional string, associated with the plot (which is usually empty), and writing to this when the improvement(s) I’m interested in are built.
 
I think I can accomplish what I want by creating an additional string, associated with the plot (which is usually empty), and writing to this when the improvement(s) I’m interested in are built.
I have named Ruins in my mod, and that's how I've implemented it too. CvGameTextMgr::setPlotHelp is responsible for showing improvement names (BtS code):
Code:
eImprovement = pPlot->getRevealedImprovementType(GC.getGameINLINE().getActiveTeam(), true);

if (eImprovement != NO_IMPROVEMENT)
{
   szString.append(NEWLINE);
   szString.append(GC.getImprovementInfo(eImprovement).getDescription());
   // ...
}
But I haven't implemented a dialog for renaming the ruins – they get named automatically after the destroyed city. Searching for WIDGET_UNIT_NAME in CvDLLWidgetData.cpp and CvMainInterface.py could be a starting point.
Edit: Perhaps I've misunderstood your first post; if you want to change the name programmatically, then you obviously don't need any dialog.
 
Thank @f1rpo, I got it to work the way I wanted. Adding the parameters which aren't in the xml was actually the most intimidating bit but now I'm ready to start adding in integer values on plots as well.

My amended code (surrounded by Tower of Whoever) in CvGameTextMgr::setPlotHelp is
Code:
           szString.append(NEWLINE);

// LPlate, Tower of Whoever
           if (GC.getImprovementInfo(eImprovement).isUsesIndividualNames())
           {
               szString.append(pPlot->getIndividualName());
           }
           else
           {
               szString.append(GC.getImprovementInfo(eImprovement).getDescription());
           }
// End LPlate, Tower of Whoever

// LPlate, Tower of Whoever, FFH Unmodified Original Code
//           szString.append(GC.getImprovementInfo(eImprovement).getDescription());
// End LPlate, Tower of Whoever, FFH Unmodified Original Code
           bFound = false;

The dll code for the creation of the new boolean, bUsesIndividualNames is in CvInfos.h, CvInfos.cpp, CyInfoInterface2.cpp, with a little explanation in CvGameTextMgr;

Spoiler :
CvInfos.h
Code:
// LPlate - Tower of Whoever
   bool isUsesIndividualNames() const;
// End LPlate - Tower of Whoever
   void read(FDataStreamBase* stream);
Code:
// LPlate - Tower of Whoever
   bool m_bUsesIndividualNames;
// End LPlate - Tower of Whoever
   // Arrays
CvInfos.cpp
Code:
// LPlate - Tower of Whoever
bool CvImprovementInfo::isUsesIndividualNames() const
{
   return m_bUsesIndividualNames;
}
// End LPlate - Tower of Whoever
// Arrays
Code:
// LPlate - Tower of Whoever
   stream->Read(&m_bUsesIndividualNames);
// End LPlate - Tower of Whoever
   // Arrays
Code:
// LPlate - Tower of Whoever
   stream->Write(m_bUsesIndividualNames);
// End LPlate - Tower of Whoever
   // Arrays
Code:
// LPlate - Tower of Whoever
   pXML->GetChildXmlValByName(&m_bUsesIndividualNames, "bUsesIndividualNames");
// End LPlate - Tower of Whoever
   return true;
}
CyInfoInterface2.cpp
Code:
// LPlate - Tower of Whoever
       .def("isUsesIndividualNames", &CvImprovementInfo::isUsesIndividualNames, "bool ()")
// End LPlate - Tower of Whoever
       .def("isRequiresIrrigation", &CvImprovementInfo::isRequiresIrrigation, "bool ()")
CvGameTextMgr::setImprovementHelp
Code:
// LPlate - Tower of Whoever
   if (info.isUsesIndividualNames())
   {
       szBuffer.append(NEWLINE);
       szBuffer.append(gDLL->getText("TXT_KEY_WONDER_INDIVIDUAL_NAMES", info.getPillageGold()));
   }
// End LPlate - Tower of Whoever
   if (info.isRequiresRiverSide())

The DLL code for setting and getting the new string for the plots is in; CvPlot.h, CvPlot.cpp, CyPlot.h, CyPlot.cpp, CyPlotInterface1;
Spoiler :
CvPlot.h
Code:
// LPlate - Tower of Whoever
   const CvWString& getIndividualName() const;                                                                               // Exposed to Python
   void setIndividualName(const CvWString szNewValue);                                                                           // Exposed to Python
// End LPlate - Tower of Whoever

   bool isFlatlands() const;
Code:
// LPlate - Tower of Whoever
   CvWString m_szIndividualName;
// End LPlate - Tower of Whoever
CvPlot.cpp
Code:
// LPlate - Tower of Whoever
   m_szIndividualName.clear();
// End LPlate - Tower of Whoever

   m_plotCity.reset();
Code:
// LPlate - Tower of Whoever
   pStream->ReadString(m_szIndividualName);
// End LPlate - Tower of Whoever

   SAFE_DELETE_ARRAY(m_aiCulture);
Code:
// LPlate - Tower of Whoever
   pStream->WriteString(m_szIndividualName);
// End LPlate - Tower of Whoever
   if (NULL == m_aiCulture)
Code:
// LPlate - Tower of Whoever
const CvWString& CvPlot::getIndividualName() const
{
   return m_szIndividualName;
}

void CvPlot::setIndividualName(CvWString szNewValue)
{
   gDLL->stripSpecialCharacters(szNewValue);

   m_szIndividualName = szNewValue;
}
// End LPlate - Tower of Whoever
CyPlot.h
Code:
// LPlate - Tower of Whoever
   std::wstring getIndividualName();
   void setIndividualName(std::wstring szNewValue);
// End LPlate - Tower of Whoever
CyPlot.cpp
Code:
// LPlate - Tower of Whoever
std::wstring CyPlot::getIndividualName()
{
   return m_pPlot ? m_pPlot->getIndividualName() : L"";
}

void CyPlot::setIndividualName(std::wstring szNewValue)
{
   if (m_pPlot)
       m_pPlot->setIndividualName(szNewValue);
}
// End LPlate - Tower of Whoever
CyPlotInterface1.cpp
Code:
// LPlate - Tower of Whoever
       .def("getIndividualName", &CyPlot::getIndividualName, "str () - Returns the individual name for an improvement")
       .def("setIndividualName", &CyPlot::setIndividualName, "void (str)")
// End LPlate - Tower of Whoever
       .def("isFlatlands", &CyPlot::isFlatlands, "bool ()")
 
Adding the parameters which aren't in the xml was actually the most intimidating bit but now I'm ready to start adding in integer values on plots as well.
Ever a chore :sad:, especially when you need to expose them to Python too. Looks all correct though; :yup: thanks for sharing your solution.
 
Back
Top Bottom