Skip to content

Commit

Permalink
CvAssert and PRECONDITION (#11444)
Browse files Browse the repository at this point in the history
* CvAssert and PRECONDITION

* Remove dev names in assert msgs

* Fixes

* Replace CvAssert with ASSERT, merge macro variants

* Use chat window in multiplayer

* Replace CvAssert everywhere

* remove test assertion
  • Loading branch information
axatin authored Dec 18, 2024
1 parent 0bbc47c commit 1f3cf6c
Show file tree
Hide file tree
Showing 121 changed files with 5,861 additions and 5,783 deletions.
48 changes: 15 additions & 33 deletions CvGameCoreDLLUtil/include/CvAssert.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
//! This file includes assertion macros used by Civilization.
//!
//! Key Macros:
//! - CvAssert(expr) - assertions w/ no message
//! - CvAssertFmt(expr, fmt, ...) - assertions w/ printf style messages
//! - CvAssertMsg(expr, msg) - assertions w/ constant messages
//! - CvAssert(expr, ...) - assertions w/ printf style messages
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifndef _CVASSERT_H
#define _CVASSERT_H
Expand All @@ -23,48 +21,35 @@ bool CvAssertDlg(const char* expr, const char* szFile, unsigned int uiLine, bool
#define CVASSERT_BREAKPOINT assert(0)
#endif

// Only compile in FAssert's if CVASSERT_ENABLE is defined. By default, however, let's key off of
// _DEBUG. Sometimes, however, it's useful to enable asserts in release builds, and you can do that
// simply by changing the following lines to define CVASSERT_ENABLE or using project settings to override
#if !defined(FINAL_RELEASE) || defined(VPDEBUG)
// Only compile in CvAssertMsg's in debug configuration, or in release configuration (with a more user-friendly text) if VPRELEASE_ERRORMSG is defined
// Asserts can be disabled by defining DISABLE_CVASSERT in the project settings
#if !defined(CVASSERT_ENABLE) && !defined(DISABLE_CVASSERT)
#if !defined(FINAL_RELEASE) || defined(VPDEBUG) || defined(VPRELEASE_ERRORMSG)
#define CVASSERT_ENABLE
#endif // FINAL_RELEASE

#endif // DISABLE_CVASSERT

#ifdef CVASSERT_ENABLE

#define CvAssertMsg(expr, msg) \
// shows a message dialog if expr is false and CVASSERT_ENABLE is defined.
// Unlike PRECONDITION, a failed assertion does not cause the game to crash
#define ASSERT(expr, ...) \
{ \
static bool bIgnoreAlways = false; \
if( !bIgnoreAlways && !(expr) ) \
{ \
if(CvAssertDlg(#expr, __FILE__, __LINE__, bIgnoreAlways, msg)) \
{ CVASSERT_BREAKPOINT; } \
} \
}

#define CvAssertFmt(expr, fmt, ...) \
{ \
static bool bIgnoreAlways = false; \
if( !bIgnoreAlways && !(expr) ) \
if( !bIgnoreAlways && !(expr) ) \
{ \
CvString str; \
CvString::format(str, fmt, __VA_ARGS__); \
if(CvAssertDlg(#expr, __FILE__, __LINE__, \
bIgnoreAlways, str.c_str())) \
{ CVASSERT_BREAKPOINT; } \
CvString::format(str, __VA_ARGS__); \
if(CvAssertDlg(#expr, __FILE__, __LINE__, bIgnoreAlways, str.c_str())) \
{ CVASSERT_BREAKPOINT; } \
} \
}

#define CvAssert( expr ) CvAssertMsg(expr, "")

// An assert that only happens in the when CVASSERT_ENABLE is true AND it is a debug build
#ifdef _DEBUG
#define CvAssert_Debug( expr ) CvAssertMsg(expr, "")
#define CvAssertMsg_Debug(expr, msg) CvAssertMsg(expr, msg)
#define CvAssert_Debug( expr, ...) CvAssertMsg( expr, __VA_ARGS__)
#else
#define CvAssert_Debug(expr)
#define CvAssertMsg_Debug(expr, msg)
#define CvAssert_Debug(expr, ...)
#endif

#if 0 // disabling Object Validation
Expand Down Expand Up @@ -106,11 +91,8 @@ struct ObjectValidator

#else //CVASSERT_ENABLE == FALSE

#define CvAssertFmt(expr, fmt, ...)
#define CvAssertMsg(expr, msg)
#define CvAssert(expr)
#define CvAssert_Debug(expr)
#define CvAssertMsg_Debug(expr, msg)

#define OBJECT_VALIDATE_DEFINITION(ObjectType)
#define OBJECT_ALLOCATED
Expand Down
2 changes: 1 addition & 1 deletion CvGameCoreDLLUtil/include/CvString.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CvString : public std::string
public:
CvString() {}
CvString(int iLen) { reserve(iLen); }
CvString(const char* s) : std::string(s ? s : "") {CvAssertMsg(s != NULL, "Passing NULL to std::string; possible heap corruption!");}
CvString(const char* s) : std::string(s ? s : "") {ASSERT(s != NULL, "Passing NULL to std::string; possible heap corruption!");}
CvString(const std::string& s): std::string(s) {}

~CvString() {}
Expand Down
10 changes: 5 additions & 5 deletions CvGameCoreDLL_Expansion2/CustomMods.h
Original file line number Diff line number Diff line change
Expand Up @@ -1213,11 +1213,11 @@ void CheckSentinel(uint);

#define MOD_SERIALIZE_INIT_WRITE_NO_SENTINEL(stream) uint uiDllSaveVersion = MOD_DLL_VERSION_NUMBER; (stream) << uiDllSaveVersion;
#define MOD_SERIALIZE_INIT_WRITE(stream) uint uiDllSaveVersion = MOD_DLL_VERSION_NUMBER; (stream) << uiDllSaveVersion; (stream) << 0xDEADBEEF;
#define MOD_SERIALIZE_WRITE(stream, member) CvAssert(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << member
#define MOD_SERIALIZE_WRITE_AUTO(stream, member) CvAssert(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << member
#define MOD_SERIALIZE_WRITE_ARRAY(stream, member, type, size) CvAssert(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << ArrayWrapper<type>(size, member)
#define MOD_SERIALIZE_WRITE_CONSTARRAY(stream, member, type, size) CvAssert(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << ArrayWrapperConst<type>(size, member)
#define MOD_SERIALIZE_WRITE_HASH(stream, member, type, size, obj) CvAssert(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); CvInfosSerializationHelper::WriteHashedDataArray<obj, type>(stream, member, size)
#define MOD_SERIALIZE_WRITE(stream, member) ASSERT(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << member
#define MOD_SERIALIZE_WRITE_AUTO(stream, member) ASSERT(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << member
#define MOD_SERIALIZE_WRITE_ARRAY(stream, member, type, size) ASSERT(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << ArrayWrapper<type>(size, member)
#define MOD_SERIALIZE_WRITE_CONSTARRAY(stream, member, type, size) ASSERT(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); (stream) << ArrayWrapperConst<type>(size, member)
#define MOD_SERIALIZE_WRITE_HASH(stream, member, type, size, obj) ASSERT(uiDllSaveVersion == MOD_DLL_VERSION_NUMBER); CvInfosSerializationHelper::WriteHashedDataArray<obj, type>(stream, member, size)
#else
#define MOD_SERIALIZE_INIT_READ(stream) __noop
#define MOD_SERIALIZE_READ(version, stream, member, def) __noop
Expand Down
60 changes: 30 additions & 30 deletions CvGameCoreDLL_Expansion2/CvAdvisorCounsel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,22 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
bool bSuccess = false;
strLoc = Localization::Lookup("TXT_KEY_BUILD_A_CITY_MCFLY_ECONOMIC");
bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_ECONOMIC, strLoc.toUTF8(), 99);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;

strLoc = Localization::Lookup("TXT_KEY_BUILD_A_CITY_MCFLY_MILITARY");
bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_MILITARY, strLoc.toUTF8(), 99);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;

strLoc = Localization::Lookup("TXT_KEY_BUILD_A_CITY_MCFLY_SCIENCE");
bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 99);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;

strLoc = Localization::Lookup("TXT_KEY_BUILD_A_CITY_MCFLY_FOREIGN");
bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_FOREIGN, strLoc.toUTF8(), 99);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;

std::stable_sort(&m_aCounsel[0], &m_aCounsel[0] + m_aCounsel.size(), CounselSort);
Expand All @@ -123,7 +123,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
{
strLoc = Localization::Lookup(pStrategy->GetAdvisorCounselText());
bool bSuccess = SetCounselEntry(uiCounselIndex, pStrategy->GetAdvisor(), strLoc.toUTF8(), pStrategy->GetAdvisorCounselImportance());
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand All @@ -143,15 +143,15 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
if(pMilitaryAI->IsUsingStrategy(eStrategy))
{
CvMilitaryAIStrategyXMLEntry* pStrategy = pMilitaryAI->GetMilitaryAIStrategies()->GetEntry(iStrategiesLoop);
CvAssert(pStrategy != NULL);
ASSERT(pStrategy != NULL);
if(pStrategy)
{
// if this strategy has an advisor set, then try to add it to the list
if(pStrategy->GetAdvisor() != NO_ADVISOR_TYPE)
{
strLoc = Localization::Lookup(pStrategy->GetAdvisorCounselText());
bool bSuccess = SetCounselEntry(uiCounselIndex, pStrategy->GetAdvisor(), strLoc.toUTF8(), pStrategy->GetAdvisorCounselImportance());
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -181,7 +181,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc = Localization::Lookup(pStrategy->GetAdvisorCounselText());
strLoc << pLoopCity->getNameKey();
bool bSuccess = SetCounselEntry(uiCounselIndex, pStrategy->GetAdvisor(), strLoc.toUTF8(), pStrategy->GetAdvisorCounselImportance());
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -228,7 +228,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GET_PLAYER(ePlayer).getCivilizationInfo().getAdjectiveKey();

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 2);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand All @@ -244,7 +244,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getBuildingInfo(pPlayerTechs->GetCivTechUniqueBuilding(eTech))->GetTextKey();
strLoc << GET_PLAYER(ePlayer).getCivilizationInfo().getAdjectiveKey();
bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 2);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand All @@ -260,7 +260,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getImprovementInfo(pPlayerTechs->GetCivTechUniqueImprovement(eTech))->GetTextKey();
strLoc << GET_PLAYER(ePlayer).getCivilizationInfo().getAdjectiveKey();
bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 2);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand All @@ -276,7 +276,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << pPlayerTechs->GetTechs()->GetEntry(eTech)->GetTextKey();
strLoc << GET_PLAYER(ePlayer).getCivilizationInfo().getAdjectiveKey();
bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 2);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand All @@ -300,7 +300,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << pPlayerTechs->GetTechs()->GetEntry(eTech)->GetTextKey();
strLoc << GC.getResourceInfo(eResource)->GetTextKey();
bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 60);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if (!bSuccess)
{
break;
Expand Down Expand Up @@ -368,7 +368,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
}

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 15);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -443,7 +443,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_MILITARY, strLoc.toUTF8(), 15);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}
}
Expand All @@ -459,7 +459,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_MILITARY, strLoc.toUTF8(), 15);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}
}
Expand Down Expand Up @@ -512,7 +512,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), iRating);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}

Expand Down Expand Up @@ -974,7 +974,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
if(eAdvisor != NO_ADVISOR_TYPE)
{
bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisor, strLoc.toUTF8(), iMessageRating);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -1096,7 +1096,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
if(eAdvisor != NO_ADVISOR_TYPE)
{
bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisor, strLoc.toUTF8(), iMessageRating);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -1308,7 +1308,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
{
bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisor, strLoc.toUTF8(), iMessageRating);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}
}
Expand Down Expand Up @@ -1380,7 +1380,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getMinorCivInfo(pMinorCivAI->GetMinorCivType())->GetTextKey();

bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisor, strLoc.toUTF8(), iMessageRating);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -1449,7 +1449,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getMinorCivInfo(pMinorCivAI->GetMinorCivType())->GetTextKey();
break;
default:
CvAssertMsg(false, "No entry for this quest type!");
ASSERT(false, "No entry for this quest type!");
break;
}
}
Expand Down Expand Up @@ -1520,7 +1520,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getMinorCivInfo(pMinorCivAI->GetMinorCivType())->GetTextKey();
break;
default:
CvAssertMsg(false, "No entry for this quest type!");
ASSERT(false, "No entry for this quest type!");
break;
}
}
Expand Down Expand Up @@ -1590,7 +1590,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getMinorCivInfo(pMinorCivAI->GetMinorCivType())->GetTextKey();
break;
default:
CvAssertMsg(false, "No entry for this quest type!");
ASSERT(false, "No entry for this quest type!");
break;
}
}
Expand All @@ -1614,7 +1614,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
if(iMessageRating > 0)
{
bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisor, strLoc.toUTF8(), iMessageRating);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -1706,7 +1706,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
strLoc << GC.getBuildingInfo(eRecommendedResearchBuilding)->GetTextKey();

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_SCIENCE, strLoc.toUTF8(), 20);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
if(!bSuccess)
{
break;
Expand Down Expand Up @@ -1832,7 +1832,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_ECONOMIC, strLoc.toUTF8(), 20);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}

Expand Down Expand Up @@ -1934,15 +1934,15 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)
}
else
{
CvAssertMsg(false, "Can't trade a bonus resource");
ASSERT(false, "Can't trade a bonus resource");
}

strLoc << GC.getResourceInfo(eTradableResource)->GetTextKey();
strLoc << GET_PLAYER(eTargetPlayer).getCivilizationInfo().GetTextKey();

bool bSuccess = SetCounselEntry(uiCounselIndex, ADVISOR_FOREIGN, strLoc.toUTF8(), 20);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}

Expand Down Expand Up @@ -1987,7 +1987,7 @@ void CvAdvisorCounsel::BuildCounselList(PlayerTypes ePlayer)

bool bSuccess = SetCounselEntry(uiCounselIndex, eAdvisorTypes, strLoc.toUTF8(), 0);
DEBUG_VARIABLE(bSuccess);
CvAssertMsg(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
ASSERT(bSuccess, "Unable to add counsel to list. Too many strategies running at once");
uiCounselIndex++;
}
}
Expand Down
Loading

0 comments on commit 1f3cf6c

Please sign in to comment.