mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-04-09 19:20:03 +03:00
ZBot: Implemented immediate reloading of nav data after bot analysis, without requiring a full map restart
ZBot: Added cleanup for dangling navigation pointers in bots, enabling seamless map reanalysis Minor refactoring
This commit is contained in:
parent
f5cc6f3a8b
commit
6f70d6dd8e
@ -900,3 +900,129 @@ float CCSBot::GetRangeToFarthestEscortedHostage() const
|
|||||||
|
|
||||||
return away.m_farRange;
|
return away.m_farRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all occurrences of a given area from the path list
|
||||||
|
void CCSBot::RemovePath(CNavArea *area)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (i < m_pathLength)
|
||||||
|
{
|
||||||
|
if (m_path[i].area == area)
|
||||||
|
{
|
||||||
|
// If this area is linked to a ladder, clear the reference
|
||||||
|
if (m_path[i].ladder == m_pathLadder)
|
||||||
|
m_pathLadder = nullptr;
|
||||||
|
|
||||||
|
m_pathLength--;
|
||||||
|
|
||||||
|
// adjust the current path index if the removed element is being used
|
||||||
|
if (i == m_pathIndex)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
m_pathIndex = i - 1;
|
||||||
|
else
|
||||||
|
m_pathIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pathLength != i)
|
||||||
|
Q_memmove(&m_path[i], &m_path[i + 1], (m_pathLength - i) * sizeof(m_path[0]));
|
||||||
|
|
||||||
|
// clear the slot
|
||||||
|
Q_memset(&m_path[m_pathLength], 0, sizeof(m_path[m_pathLength]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a hiding spot from the checked spots list
|
||||||
|
void CCSBot::RemoveHidingSpot(HidingSpot *spot)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (i < m_pathLength)
|
||||||
|
{
|
||||||
|
if (m_checkedHidingSpot[i].spot == spot)
|
||||||
|
{
|
||||||
|
m_checkedHidingSpotCount--;
|
||||||
|
|
||||||
|
if (m_checkedHidingSpotCount != i)
|
||||||
|
Q_memmove(&m_checkedHidingSpot[i], &m_checkedHidingSpot[i + 1], (m_checkedHidingSpotCount - i) * sizeof(m_checkedHidingSpot[0]));
|
||||||
|
|
||||||
|
// clear the slot
|
||||||
|
Q_memset(&m_checkedHidingSpot[m_checkedHidingSpotCount], 0, sizeof(m_checkedHidingSpot[m_checkedHidingSpotCount]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle navigation-related cleanup when a nav area, spot, or encounter is destroyed
|
||||||
|
void CCSBot::OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead)
|
||||||
|
{
|
||||||
|
switch (navNotifyType)
|
||||||
|
{
|
||||||
|
case NAV_NOTIFY_DESTROY_AREA:
|
||||||
|
{
|
||||||
|
CNavArea *area = static_cast<CNavArea *>(dead);
|
||||||
|
|
||||||
|
// If the destroyed area was linked to a spot encounter, clear it
|
||||||
|
if (m_spotEncounter)
|
||||||
|
{
|
||||||
|
if (m_spotEncounter->from.area == area || m_spotEncounter->to.area == area)
|
||||||
|
m_spotEncounter = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemovePath(area);
|
||||||
|
|
||||||
|
// Invalidate any references to the destroyed area
|
||||||
|
|
||||||
|
if (m_noiseArea == area)
|
||||||
|
m_noiseArea = nullptr;
|
||||||
|
|
||||||
|
if (m_currentArea == area)
|
||||||
|
m_currentArea = nullptr;
|
||||||
|
|
||||||
|
if (m_lastKnownArea == area)
|
||||||
|
m_lastKnownArea = nullptr;
|
||||||
|
|
||||||
|
if (m_hideState.GetSearchArea() == area)
|
||||||
|
m_hideState.SetSearchArea(nullptr);
|
||||||
|
|
||||||
|
if (m_huntState.GetHuntArea() == area)
|
||||||
|
m_huntState.ClearHuntArea();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NAV_NOTIFY_DESTROY_SPOT_ENCOUNTER:
|
||||||
|
{
|
||||||
|
CNavArea *area = static_cast<CNavArea *>(dead);
|
||||||
|
|
||||||
|
// Remove the encounter if it references the destroyed area
|
||||||
|
if (m_spotEncounter && area->HasSpotEncounter(m_spotEncounter))
|
||||||
|
m_spotEncounter = nullptr;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NAV_NOTIFY_DESTROY_SPOT:
|
||||||
|
{
|
||||||
|
HidingSpot *spot = static_cast<HidingSpot *>(dead);
|
||||||
|
|
||||||
|
// Remove the destroyed hiding spot from the spot order list
|
||||||
|
if (m_spotEncounter)
|
||||||
|
{
|
||||||
|
SpotOrderList &spotOrderList = m_spotEncounter->spotList;
|
||||||
|
spotOrderList.erase(std::remove_if(spotOrderList.begin(), spotOrderList.end(), [&](SpotOrder &spotOrder) {
|
||||||
|
return spotOrder.spot == spot;
|
||||||
|
}
|
||||||
|
), spotOrderList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveHidingSpot(spot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
virtual const char *GetName() const { return "Hunt"; }
|
virtual const char *GetName() const { return "Hunt"; }
|
||||||
|
|
||||||
void ClearHuntArea() { m_huntArea = nullptr; }
|
void ClearHuntArea() { m_huntArea = nullptr; }
|
||||||
|
CNavArea *GetHuntArea() { return m_huntArea; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CNavArea *m_huntArea;
|
CNavArea *m_huntArea;
|
||||||
@ -204,6 +205,7 @@ public:
|
|||||||
const Vector &GetHidingSpot() const { return m_hidingSpot; }
|
const Vector &GetHidingSpot() const { return m_hidingSpot; }
|
||||||
|
|
||||||
void SetSearchArea(CNavArea *area) { m_searchFromArea = area; }
|
void SetSearchArea(CNavArea *area) { m_searchFromArea = area; }
|
||||||
|
CNavArea *GetSearchArea() { return m_searchFromArea; }
|
||||||
void SetSearchRange(float range) { m_range = range; }
|
void SetSearchRange(float range) { m_range = range; }
|
||||||
|
|
||||||
void SetDuration(float time) { m_duration = time; }
|
void SetDuration(float time) { m_duration = time; }
|
||||||
@ -544,6 +546,10 @@ public:
|
|||||||
|
|
||||||
float GetFeetZ() const; // return Z of bottom of feet
|
float GetFeetZ() const; // return Z of bottom of feet
|
||||||
|
|
||||||
|
void OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead);
|
||||||
|
void RemovePath(CNavArea *area);
|
||||||
|
void RemoveHidingSpot(HidingSpot *spot);
|
||||||
|
|
||||||
enum PathResult
|
enum PathResult
|
||||||
{
|
{
|
||||||
PROGRESSING, // we are moving along the path
|
PROGRESSING, // we are moving along the path
|
||||||
|
@ -337,7 +337,7 @@ void CCSBot::ResetValues()
|
|||||||
// NOTE: For some reason, this can be called twice when a bot is added.
|
// NOTE: For some reason, this can be called twice when a bot is added.
|
||||||
void CCSBot::SpawnBot()
|
void CCSBot::SpawnBot()
|
||||||
{
|
{
|
||||||
TheCSBots()->ValidateMapData();
|
TheCSBots()->LoadNavigationMap();
|
||||||
ResetValues();
|
ResetValues();
|
||||||
|
|
||||||
Q_strlcpy(m_name, STRING(pev->netname));
|
Q_strlcpy(m_name, STRING(pev->netname));
|
||||||
|
@ -477,31 +477,24 @@ void CCSBot::StartSaveProcess()
|
|||||||
|
|
||||||
void CCSBot::UpdateSaveProcess()
|
void CCSBot::UpdateSaveProcess()
|
||||||
{
|
{
|
||||||
char msg[256];
|
|
||||||
char cmd[128];
|
|
||||||
|
|
||||||
char gd[64]{};
|
char gd[64]{};
|
||||||
GET_GAME_DIR(gd);
|
GET_GAME_DIR(gd);
|
||||||
|
|
||||||
char filename[MAX_OSPATH];
|
char filename[MAX_OSPATH];
|
||||||
Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, TheBots->GetNavMapFilename());
|
Q_snprintf(filename, sizeof(filename), "%s\\%s", gd, TheBots->GetNavMapFilename());
|
||||||
|
|
||||||
HintMessageToAllPlayers("Saving...");
|
|
||||||
SaveNavigationMap(filename);
|
SaveNavigationMap(filename);
|
||||||
|
|
||||||
|
char msg[256]{};
|
||||||
Q_snprintf(msg, sizeof(msg), "Navigation file '%s' saved.", filename);
|
Q_snprintf(msg, sizeof(msg), "Navigation file '%s' saved.", filename);
|
||||||
HintMessageToAllPlayers(msg);
|
HintMessageToAllPlayers(msg);
|
||||||
|
CONSOLE_ECHO("%s\n", msg);
|
||||||
|
|
||||||
hideProgressMeter();
|
hideProgressMeter();
|
||||||
StartNormalProcess();
|
StartNormalProcess();
|
||||||
|
|
||||||
#ifndef REGAMEDLL_FIXES
|
// tell bot manager that the analysis is completed
|
||||||
Q_snprintf(cmd, sizeof(cmd), "map %s\n", STRING(gpGlobals->mapname));
|
if (TheCSBots())
|
||||||
#else
|
TheCSBots()->AnalysisCompleted();
|
||||||
Q_snprintf(cmd, sizeof(cmd), "changelevel %s\n", STRING(gpGlobals->mapname));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SERVER_COMMAND(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCSBot::StartNormalProcess()
|
void CCSBot::StartNormalProcess()
|
||||||
|
@ -231,13 +231,12 @@ bool CCSBotManager::IsOnOffense(CBasePlayer *pPlayer) const
|
|||||||
// Invoked when a map has just been loaded
|
// Invoked when a map has just been loaded
|
||||||
void CCSBotManager::ServerActivate()
|
void CCSBotManager::ServerActivate()
|
||||||
{
|
{
|
||||||
DestroyNavigationMap();
|
|
||||||
m_isMapDataLoaded = false;
|
m_isMapDataLoaded = false;
|
||||||
|
|
||||||
m_zoneCount = 0;
|
m_zoneCount = 0;
|
||||||
m_gameScenario = SCENARIO_DEATHMATCH;
|
m_gameScenario = SCENARIO_DEATHMATCH;
|
||||||
|
|
||||||
ValidateMapData();
|
LoadNavigationMap();
|
||||||
RestartRound();
|
RestartRound();
|
||||||
|
|
||||||
m_isLearningMap = false;
|
m_isLearningMap = false;
|
||||||
@ -591,7 +590,8 @@ void CCSBotManager::ServerCommand(const char *pcmd)
|
|||||||
}
|
}
|
||||||
else if (FStrEq(pcmd, "bot_nav_load"))
|
else if (FStrEq(pcmd, "bot_nav_load"))
|
||||||
{
|
{
|
||||||
ValidateMapData();
|
m_isMapDataLoaded = false; // force nav reload
|
||||||
|
LoadNavigationMap();
|
||||||
}
|
}
|
||||||
else if (FStrEq(pcmd, "bot_nav_use_place"))
|
else if (FStrEq(pcmd, "bot_nav_use_place"))
|
||||||
{
|
{
|
||||||
@ -1144,7 +1144,6 @@ private:
|
|||||||
CCSBotManager::Zone *m_zone;
|
CCSBotManager::Zone *m_zone;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef REGAMEDLL_ADD
|
|
||||||
LINK_ENTITY_TO_CLASS(info_spawn_point, CPointEntity, CCSPointEntity)
|
LINK_ENTITY_TO_CLASS(info_spawn_point, CPointEntity, CCSPointEntity)
|
||||||
|
|
||||||
inline bool IsFreeSpace(Vector vecOrigin, int iHullNumber, edict_t *pSkipEnt = nullptr)
|
inline bool IsFreeSpace(Vector vecOrigin, int iHullNumber, edict_t *pSkipEnt = nullptr)
|
||||||
@ -1163,6 +1162,9 @@ inline bool pointInRadius(Vector vecOrigin, float radius)
|
|||||||
CBaseEntity *pEntity = nullptr;
|
CBaseEntity *pEntity = nullptr;
|
||||||
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecOrigin, radius)))
|
while ((pEntity = UTIL_FindEntityInSphere(pEntity, vecOrigin, radius)))
|
||||||
{
|
{
|
||||||
|
if (!UTIL_IsValidEntity(pEntity->edict()))
|
||||||
|
continue; // ignore the entity marked for deletion
|
||||||
|
|
||||||
if (FClassnameIs(pEntity->edict(), "info_spawn_point"))
|
if (FClassnameIs(pEntity->edict(), "info_spawn_point"))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1171,12 +1173,10 @@ inline bool pointInRadius(Vector vecOrigin, float radius)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a simple algorithm that searches for the farthest point (so that the player does not look at the wall)
|
// a simple algorithm that searches for the farthest point (so that the player does not look at the wall)
|
||||||
inline Vector GetBestAngle(const Vector &vecStart)
|
inline bool GetIdealLookYawForSpawnPoint(const Vector &vecStart, float &flIdealLookYaw)
|
||||||
{
|
{
|
||||||
const float ANGLE_STEP = 30.0f;
|
const float ANGLE_STEP = 30.0f;
|
||||||
float bestAngle = 0.0f;
|
|
||||||
float bestDistance = 0.0f;
|
float bestDistance = 0.0f;
|
||||||
Vector vecBestAngle = Vector(0, -1, 0);
|
|
||||||
|
|
||||||
for (float angleYaw = 0.0f; angleYaw <= 360.0f; angleYaw += ANGLE_STEP)
|
for (float angleYaw = 0.0f; angleYaw <= 360.0f; angleYaw += ANGLE_STEP)
|
||||||
{
|
{
|
||||||
@ -1187,15 +1187,14 @@ inline Vector GetBestAngle(const Vector &vecStart)
|
|||||||
UTIL_TraceLine(vecStart, vecEnd, ignore_monsters, nullptr, &tr);
|
UTIL_TraceLine(vecStart, vecEnd, ignore_monsters, nullptr, &tr);
|
||||||
|
|
||||||
float distance = (vecStart - tr.vecEndPos).Length();
|
float distance = (vecStart - tr.vecEndPos).Length();
|
||||||
|
|
||||||
if (distance > bestDistance)
|
if (distance > bestDistance)
|
||||||
{
|
{
|
||||||
bestDistance = distance;
|
bestDistance = distance;
|
||||||
vecBestAngle.y = angleYaw;
|
flIdealLookYaw = angleYaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vecBestAngle;
|
return bestDistance > 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function from leaked csgo sources 2020y
|
// this function from leaked csgo sources 2020y
|
||||||
@ -1231,58 +1230,69 @@ inline bool IsValidArea(CNavArea *area)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetSpawnPositions()
|
#ifdef REGAMEDLL_ADD
|
||||||
{
|
|
||||||
const float MIN_AREA_SIZE = 32.0f;
|
|
||||||
const int MAX_SPAWNS_POINTS = 128;
|
|
||||||
const float MAX_SLOPE = 0.85f;
|
|
||||||
|
|
||||||
|
// Generates spawn points (info_spawn_point entities) for players and bots based on the navigation map data
|
||||||
|
// It uses the navigation areas to find valid spots for spawn points considering factors like area size, slope,
|
||||||
|
// available free space, and distance from other spawn points.
|
||||||
|
void GenerateSpawnPointsFromNavData()
|
||||||
|
{
|
||||||
|
// Remove any existing spawn points
|
||||||
|
UTIL_RemoveOther("info_spawn_point");
|
||||||
|
|
||||||
|
const int MAX_SPAWNS_POINTS = 128; // Max allowed spawn points
|
||||||
|
|
||||||
|
const float MAX_SLOPE = 0.85f; // Maximum slope allowed for a spawn point
|
||||||
|
const float MIN_AREA_SIZE = 32.0f; // Minimum area size for a valid spawn point
|
||||||
|
const float MIN_NEARBY_SPAWNPOINT = 128.0f; // Minimum distance between spawn point
|
||||||
|
|
||||||
|
// Total number of spawn points generated
|
||||||
int totalSpawns = 0;
|
int totalSpawns = 0;
|
||||||
|
|
||||||
for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); iter++)
|
for (CNavArea *area : TheNavAreaList)
|
||||||
{
|
{
|
||||||
if (totalSpawns >= MAX_SPAWNS_POINTS)
|
if (totalSpawns >= MAX_SPAWNS_POINTS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
CNavArea *area = *iter;
|
|
||||||
|
|
||||||
if (!area)
|
if (!area)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// ignore small areas
|
// Skip areas that are too small
|
||||||
if (area->GetSizeX() < MIN_AREA_SIZE || area->GetSizeY() < MIN_AREA_SIZE)
|
if (area->GetSizeX() < MIN_AREA_SIZE || area->GetSizeY() < MIN_AREA_SIZE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// ignore areas jump, crouch etc
|
// Skip areas with unwanted attributes (jump, crouch, etc.)
|
||||||
if (area->GetAttributes())
|
if (area->GetAttributes() != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Skip areas with steep slopes
|
||||||
if (area->GetAreaSlope() < MAX_SLOPE)
|
if (area->GetAreaSlope() < MAX_SLOPE)
|
||||||
{
|
{
|
||||||
//CONSOLE_ECHO("Skip area slope: %0.3f\n", area->GetAreaSlope());
|
//CONSOLE_ECHO("Skip area slope: %0.3f\n", area->GetAreaSlope());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the spawn point position above the area center
|
||||||
Vector vecOrigin = *area->GetCenter() + Vector(0, 0, HalfHumanHeight + 5);
|
Vector vecOrigin = *area->GetCenter() + Vector(0, 0, HalfHumanHeight + 5);
|
||||||
|
|
||||||
|
// Ensure there is free space at the calculated position
|
||||||
if (!IsFreeSpace(vecOrigin, human_hull))
|
if (!IsFreeSpace(vecOrigin, human_hull))
|
||||||
{
|
{
|
||||||
//CONSOLE_ECHO("No free space!\n");
|
//CONSOLE_ECHO("No free space!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pointInRadius(vecOrigin, 128.0f))
|
if (pointInRadius(vecOrigin, MIN_NEARBY_SPAWNPOINT))
|
||||||
continue;
|
continue; // spawn point is too close to others
|
||||||
|
|
||||||
if (!IsValidArea(area))
|
if (!IsValidArea(area))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Vector bestAngle = GetBestAngle(vecOrigin);
|
// Calculate ideal spawn point yaw angle
|
||||||
|
float flIdealSpawnPointYaw = 0.0f;
|
||||||
if (bestAngle.y != -1)
|
if (GetIdealLookYawForSpawnPoint(vecOrigin, flIdealSpawnPointYaw))
|
||||||
{
|
{
|
||||||
CBaseEntity* pPoint = CBaseEntity::Create("info_spawn_point", vecOrigin, bestAngle, nullptr);
|
CBaseEntity *pPoint = CBaseEntity::Create("info_spawn_point", vecOrigin, Vector(0, flIdealSpawnPointYaw, 0), nullptr);
|
||||||
|
|
||||||
if (pPoint)
|
if (pPoint)
|
||||||
{
|
{
|
||||||
totalSpawns++;
|
totalSpawns++;
|
||||||
@ -1302,24 +1312,64 @@ void GetSpawnPositions()
|
|||||||
|
|
||||||
CONSOLE_ECHO("Total spawns points: %i\n", totalSpawns);
|
CONSOLE_ECHO("Total spawns points: %i\n", totalSpawns);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Search the map entities to determine the game scenario and define important zones.
|
// Load the map's navigation data
|
||||||
void CCSBotManager::ValidateMapData()
|
bool CCSBotManager::LoadNavigationMap()
|
||||||
{
|
{
|
||||||
|
// check if the map data is already loaded or if bots are not allowed
|
||||||
if (m_isMapDataLoaded || !AreBotsAllowed())
|
if (m_isMapDataLoaded || !AreBotsAllowed())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
m_isMapDataLoaded = true;
|
m_isMapDataLoaded = true;
|
||||||
|
|
||||||
if (LoadNavigationMap())
|
// Clear navigation map data from previous map
|
||||||
|
DestroyNavigationMap();
|
||||||
|
|
||||||
|
// Try to load the map's navigation file
|
||||||
|
NavErrorType navStatus = ::LoadNavigationMap();
|
||||||
|
if (navStatus != NAV_OK)
|
||||||
{
|
{
|
||||||
CONSOLE_ECHO("Failed to load navigation map.\n");
|
CONSOLE_ECHO("ERROR: Failed to load 'maps/%s.nav' file navigation map!\n", STRING(gpGlobals->mapname));
|
||||||
return;
|
|
||||||
|
switch (navStatus)
|
||||||
|
{
|
||||||
|
case NAV_CANT_ACCESS_FILE:
|
||||||
|
CONSOLE_ECHO("\tNavigation file not found or access denied.\n");
|
||||||
|
break;
|
||||||
|
case NAV_INVALID_FILE:
|
||||||
|
CONSOLE_ECHO("\tInvalid navigation file format.\n");
|
||||||
|
break;
|
||||||
|
case NAV_BAD_FILE_VERSION:
|
||||||
|
CONSOLE_ECHO("\tBad navigation file version.\n");
|
||||||
|
break;
|
||||||
|
case NAV_CORRUPT_DATA:
|
||||||
|
CONSOLE_ECHO("\tCorrupted navigation data detected.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navStatus != NAV_CANT_ACCESS_FILE)
|
||||||
|
CONSOLE_ECHO("\tTry regenerating it using the command: bot_nav_analyze\n");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CONSOLE_ECHO("Navigation map loaded.\n");
|
// Determine the scenario for the current map (e.g., bomb defuse, hostage rescue etc)
|
||||||
|
DetermineMapScenario();
|
||||||
|
|
||||||
|
#ifdef REGAMEDLL_ADD
|
||||||
|
GenerateSpawnPointsFromNavData();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the map entities to determine the game scenario and define important zones.
|
||||||
|
void CCSBotManager::DetermineMapScenario()
|
||||||
|
{
|
||||||
m_zoneCount = 0;
|
m_zoneCount = 0;
|
||||||
m_gameScenario = SCENARIO_DEATHMATCH;
|
m_gameScenario = SCENARIO_DEATHMATCH;
|
||||||
|
|
||||||
@ -1459,6 +1509,59 @@ void CCSBotManager::ValidateMapData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tell all bots that the given nav data no longer exists
|
||||||
|
// This function is called when a part of the map or the nav data is destroyed
|
||||||
|
void CCSBotManager::OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead)
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||||
|
|
||||||
|
if (!UTIL_IsValidPlayer(pPlayer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!pPlayer->IsBot())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Notify the bot about the destroyed nav data
|
||||||
|
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
|
||||||
|
pBot->OnDestroyNavDataNotify(navNotifyType, dead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the map analysis process has completed
|
||||||
|
// This function makes sure all bots are removed from the map analysis process
|
||||||
|
// and are reset to normal bot behavior. It also reloads the navigation map
|
||||||
|
// and triggers a game restart after the analysis is completed
|
||||||
|
void CCSBotManager::AnalysisCompleted()
|
||||||
|
{
|
||||||
|
// Ensure that all bots are no longer involved in map analysis and start their normal process
|
||||||
|
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
|
||||||
|
|
||||||
|
if (!UTIL_IsValidPlayer(pPlayer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!pPlayer->IsBot())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
|
||||||
|
pBot->StartNormalProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isLearningMap = false;
|
||||||
|
m_isMapDataLoaded = false;
|
||||||
|
m_isAnalysisRequested = false;
|
||||||
|
|
||||||
|
// Try to reload the navigation map from the file
|
||||||
|
if (LoadNavigationMap())
|
||||||
|
{
|
||||||
|
// Initiate a game restart in 3 seconds
|
||||||
|
CVAR_SET_FLOAT("sv_restart", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
|
bool CCSBotManager::AddBot(const BotProfile *profile, BotProfileTeamType team)
|
||||||
{
|
{
|
||||||
if (!AreBotsAllowed())
|
if (!AreBotsAllowed())
|
||||||
|
@ -56,13 +56,16 @@ public:
|
|||||||
virtual bool IsImportantPlayer(CBasePlayer *pPlayer) const; // return true if pPlayer is important to scenario (VIP, bomb carrier, etc)
|
virtual bool IsImportantPlayer(CBasePlayer *pPlayer) const; // return true if pPlayer is important to scenario (VIP, bomb carrier, etc)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ValidateMapData();
|
bool LoadNavigationMap();
|
||||||
|
void DetermineMapScenario();
|
||||||
void OnFreeEntPrivateData(CBaseEntity *pEntity);
|
void OnFreeEntPrivateData(CBaseEntity *pEntity);
|
||||||
|
void OnDestroyNavDataNotify(NavNotifyDestroyType navNotifyType, void *dead);
|
||||||
bool IsLearningMap() const { return m_isLearningMap; }
|
bool IsLearningMap() const { return m_isLearningMap; }
|
||||||
void SetLearningMapFlag() { m_isLearningMap = true; }
|
void SetLearningMapFlag() { m_isLearningMap = true; }
|
||||||
bool IsAnalysisRequested() const { return m_isAnalysisRequested; }
|
bool IsAnalysisRequested() const { return m_isAnalysisRequested; }
|
||||||
void RequestAnalysis() { m_isAnalysisRequested = true; }
|
void RequestAnalysis() { m_isAnalysisRequested = true; }
|
||||||
void AckAnalysisRequest() { m_isAnalysisRequested = false; }
|
void AckAnalysisRequest() { m_isAnalysisRequested = false; }
|
||||||
|
void AnalysisCompleted();
|
||||||
|
|
||||||
// difficulty levels
|
// difficulty levels
|
||||||
static BotDifficultyType GetDifficultyLevel()
|
static BotDifficultyType GetDifficultyLevel()
|
||||||
@ -269,6 +272,4 @@ inline bool AreBotsAllowed()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintAllEntities();
|
void PrintAllEntities();
|
||||||
#ifdef REGAMEDLL_ADD
|
void GenerateSpawnPointsFromNavData();
|
||||||
void GetSpawnPositions();
|
|
||||||
#endif
|
|
||||||
|
@ -1003,7 +1003,7 @@ CBasePlayer *CCSBot::FindMostDangerousThreat()
|
|||||||
return currentThreat;
|
return currentThreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we are a sniper and we see a sniper threat, attack it unless
|
// if we are a sniper and we see a sniper threat, attack it unless
|
||||||
// there are other close enemies facing me
|
// there are other close enemies facing me
|
||||||
if (IsSniper() && sniperThreat)
|
if (IsSniper() && sniperThreat)
|
||||||
{
|
{
|
||||||
|
@ -844,7 +844,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
|||||||
#ifdef REGAMEDLL_ADD
|
#ifdef REGAMEDLL_ADD
|
||||||
// there's no team on FFA mode
|
// there's no team on FFA mode
|
||||||
if (teamonly && CSGameRules()->IsFreeForAll() && (pPlayer->m_iTeam == CT || pPlayer->m_iTeam == TERRORIST))
|
if (teamonly && CSGameRules()->IsFreeForAll() && (pPlayer->m_iTeam == CT || pPlayer->m_iTeam == TERRORIST))
|
||||||
teamonly = FALSE;
|
teamonly = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// team only
|
// team only
|
||||||
@ -1001,7 +1001,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
|||||||
if (gpGlobals->deathmatch != 0.0f && CSGameRules()->m_VoiceGameMgr.PlayerHasBlockedPlayer(pReceiver, pPlayer))
|
if (gpGlobals->deathmatch != 0.0f && CSGameRules()->m_VoiceGameMgr.PlayerHasBlockedPlayer(pReceiver, pPlayer))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (teamonly
|
if (teamonly
|
||||||
#ifdef REGAMEDLL_FIXES
|
#ifdef REGAMEDLL_FIXES
|
||||||
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) != GR_TEAMMATE
|
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) != GR_TEAMMATE
|
||||||
#else
|
#else
|
||||||
@ -1020,7 +1020,7 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pReceiver->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY
|
if ((pReceiver->m_iIgnoreGlobalChat == IGNOREMSG_ENEMY
|
||||||
#ifdef REGAMEDLL_FIXES
|
#ifdef REGAMEDLL_FIXES
|
||||||
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) == GR_TEAMMATE
|
&& CSGameRules()->PlayerRelationship(pPlayer, pReceiver) == GR_TEAMMATE
|
||||||
#else
|
#else
|
||||||
@ -3833,11 +3833,6 @@ void EXT_FUNC ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
|
|||||||
|
|
||||||
#ifdef REGAMEDLL_ADD
|
#ifdef REGAMEDLL_ADD
|
||||||
CSGameRules()->ServerActivate();
|
CSGameRules()->ServerActivate();
|
||||||
|
|
||||||
if (LoadNavigationMap() == NAV_OK)
|
|
||||||
{
|
|
||||||
GetSpawnPositions();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +174,9 @@ cvar_t freezetime_duck = { "mp_freezetime_duck", "1", 0, 1.0f,
|
|||||||
cvar_t freezetime_jump = { "mp_freezetime_jump", "1", 0, 1.0f, nullptr };
|
cvar_t freezetime_jump = { "mp_freezetime_jump", "1", 0, 1.0f, nullptr };
|
||||||
cvar_t jump_height = { "mp_jump_height", "45", FCVAR_SERVER, 45.0f, nullptr };
|
cvar_t jump_height = { "mp_jump_height", "45", FCVAR_SERVER, 45.0f, nullptr };
|
||||||
|
|
||||||
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
|
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
|
||||||
|
|
||||||
cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr };
|
cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr };
|
||||||
|
|
||||||
cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr };
|
cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr };
|
||||||
cvar_t defuser_allocation = { "mp_defuser_allocation", "0", 0, 0.0f, nullptr };
|
cvar_t defuser_allocation = { "mp_defuser_allocation", "0", 0, 0.0f, nullptr };
|
||||||
|
@ -5594,7 +5594,9 @@ CTSpawn:
|
|||||||
// The terrorist spawn points
|
// The terrorist spawn points
|
||||||
else if (g_pGameRules->IsDeathmatch() && m_iTeam == TERRORIST)
|
else if (g_pGameRules->IsDeathmatch() && m_iTeam == TERRORIST)
|
||||||
{
|
{
|
||||||
|
#ifdef REGAMEDLL_ADD
|
||||||
TSpawn:
|
TSpawn:
|
||||||
|
#endif
|
||||||
pSpot = g_pLastTerroristSpawn;
|
pSpot = g_pLastTerroristSpawn;
|
||||||
|
|
||||||
if (SelectSpawnSpot("info_player_deathmatch", pSpot))
|
if (SelectSpawnSpot("info_player_deathmatch", pSpot))
|
||||||
|
@ -1464,7 +1464,7 @@ void UTIL_Remove(CBaseEntity *pEntity)
|
|||||||
pEntity->pev->targetname = 0;
|
pEntity->pev->targetname = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOXREF BOOL UTIL_IsValidEntity(edict_t *pent)
|
BOOL UTIL_IsValidEntity(edict_t *pent)
|
||||||
{
|
{
|
||||||
if (!pent || pent->free || (pent->v.flags & FL_KILLME))
|
if (!pent || pent->free || (pent->v.flags & FL_KILLME))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -71,6 +71,13 @@ enum NavAttributeType
|
|||||||
NAV_NO_JUMP = 0x08, // inhibit discontinuity jumping
|
NAV_NO_JUMP = 0x08, // inhibit discontinuity jumping
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum NavNotifyDestroyType
|
||||||
|
{
|
||||||
|
NAV_NOTIFY_DESTROY_AREA,
|
||||||
|
NAV_NOTIFY_DESTROY_SPOT,
|
||||||
|
NAV_NOTIFY_DESTROY_SPOT_ENCOUNTER
|
||||||
|
};
|
||||||
|
|
||||||
enum NavDirType
|
enum NavDirType
|
||||||
{
|
{
|
||||||
NORTH = 0,
|
NORTH = 0,
|
||||||
|
@ -72,17 +72,29 @@ NOXREF void buildGoodSizedList()
|
|||||||
|
|
||||||
void DestroyHidingSpots()
|
void DestroyHidingSpots()
|
||||||
{
|
{
|
||||||
// remove all hiding spot references from the nav areas
|
|
||||||
for (auto area : TheNavAreaList)
|
|
||||||
area->m_hidingSpotList.clear();
|
|
||||||
|
|
||||||
HidingSpot::m_nextID = 0;
|
|
||||||
|
|
||||||
// free all the HidingSpots
|
// free all the HidingSpots
|
||||||
for (auto spot : TheHidingSpotList)
|
for (HidingSpot *spot : TheHidingSpotList)
|
||||||
|
{
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_SPOT, spot);
|
||||||
delete spot;
|
delete spot;
|
||||||
|
}
|
||||||
|
|
||||||
TheHidingSpotList.clear();
|
TheHidingSpotList.clear();
|
||||||
|
|
||||||
|
// remove all hiding spot references from the nav areas
|
||||||
|
for (CNavArea *area : TheNavAreaList)
|
||||||
|
{
|
||||||
|
area->m_hidingSpotList.clear();
|
||||||
|
|
||||||
|
// free all the HidingSpots in area
|
||||||
|
for (SpotEncounter &e : area->m_spotEncounterList)
|
||||||
|
e.spotList.clear();
|
||||||
|
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_SPOT_ENCOUNTER, area);
|
||||||
|
area->m_spotEncounterList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
HidingSpot::m_nextID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use when loading from a file
|
// For use when loading from a file
|
||||||
@ -249,6 +261,9 @@ CNavArea::CNavArea(CNavNode *nwNode, class CNavNode *neNode, class CNavNode *seN
|
|||||||
// Destructor
|
// Destructor
|
||||||
CNavArea::~CNavArea()
|
CNavArea::~CNavArea()
|
||||||
{
|
{
|
||||||
|
// tell all bots that this area no longer exists
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_AREA, this);
|
||||||
|
|
||||||
// if we are resetting the system, don't bother cleaning up - all areas are being destroyed
|
// if we are resetting the system, don't bother cleaning up - all areas are being destroyed
|
||||||
if (m_isReset)
|
if (m_isReset)
|
||||||
return;
|
return;
|
||||||
@ -344,6 +359,7 @@ void CNavArea::FinishMerge(CNavArea *adjArea)
|
|||||||
|
|
||||||
// remove subsumed adjacent area
|
// remove subsumed adjacent area
|
||||||
TheNavAreaList.remove(adjArea);
|
TheNavAreaList.remove(adjArea);
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_AREA, this);
|
||||||
delete adjArea;
|
delete adjArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,6 +552,7 @@ bool CNavArea::SplitEdit(bool splitAlongX, float splitEdge, CNavArea **outAlpha,
|
|||||||
|
|
||||||
// remove original area
|
// remove original area
|
||||||
TheNavAreaList.remove(this);
|
TheNavAreaList.remove(this);
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_AREA, this);
|
||||||
delete this;
|
delete this;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -868,6 +885,7 @@ bool CNavArea::MergeEdit(CNavArea *adj)
|
|||||||
|
|
||||||
// remove subsumed adjacent area
|
// remove subsumed adjacent area
|
||||||
TheNavAreaList.remove(adj);
|
TheNavAreaList.remove(adj);
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_AREA, adj);
|
||||||
delete adj;
|
delete adj;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -900,6 +918,9 @@ void DestroyNavigationMap()
|
|||||||
{
|
{
|
||||||
CNavArea::m_isReset = true;
|
CNavArea::m_isReset = true;
|
||||||
|
|
||||||
|
// destroy all hiding spots
|
||||||
|
DestroyHidingSpots();
|
||||||
|
|
||||||
// remove each element of the list and delete them
|
// remove each element of the list and delete them
|
||||||
while (!TheNavAreaList.empty())
|
while (!TheNavAreaList.empty())
|
||||||
{
|
{
|
||||||
@ -913,8 +934,8 @@ void DestroyNavigationMap()
|
|||||||
// destroy ladder representations
|
// destroy ladder representations
|
||||||
DestroyLadders();
|
DestroyLadders();
|
||||||
|
|
||||||
// destroy all hiding spots
|
// cleanup from previous analysis
|
||||||
DestroyHidingSpots();
|
CleanupApproachAreaAnalysisPrep();
|
||||||
|
|
||||||
// destroy navigation nodes created during map learning
|
// destroy navigation nodes created during map learning
|
||||||
CNavNode *node, *next;
|
CNavNode *node, *next;
|
||||||
@ -2828,6 +2849,22 @@ SpotEncounter *CNavArea::GetSpotEncounter(const CNavArea *from, const CNavArea *
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if a SpotEncounter is present in the list of encounters for the given CNavArea
|
||||||
|
bool CNavArea::HasSpotEncounter(const SpotEncounter *encounter)
|
||||||
|
{
|
||||||
|
SpotEncounter *e;
|
||||||
|
|
||||||
|
for (SpotEncounterList::iterator iter = m_spotEncounterList.begin(); iter != m_spotEncounterList.end(); iter++)
|
||||||
|
{
|
||||||
|
e = &(*iter);
|
||||||
|
|
||||||
|
if (e == encounter)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Add spot encounter data when moving from area to area
|
// Add spot encounter data when moving from area to area
|
||||||
void CNavArea::AddSpotEncounters(const class CNavArea *from, NavDirType fromDir, const CNavArea *to, NavDirType toDir)
|
void CNavArea::AddSpotEncounters(const class CNavArea *from, NavDirType fromDir, const CNavArea *to, NavDirType toDir)
|
||||||
{
|
{
|
||||||
@ -3968,6 +4005,7 @@ void EditNavAreas(NavEditCmdType cmd)
|
|||||||
case EDIT_DELETE:
|
case EDIT_DELETE:
|
||||||
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
EMIT_SOUND_DYN(ENT(pLocalPlayer->pev), CHAN_ITEM, "buttons/blip1.wav", 1, ATTN_NORM, 0, 100);
|
||||||
TheNavAreaList.remove(area);
|
TheNavAreaList.remove(area);
|
||||||
|
TheCSBots()->OnDestroyNavDataNotify(NAV_NOTIFY_DESTROY_AREA, area);
|
||||||
delete area;
|
delete area;
|
||||||
return;
|
return;
|
||||||
case EDIT_ATTRIB_CROUCH:
|
case EDIT_ATTRIB_CROUCH:
|
||||||
|
@ -273,6 +273,7 @@ public:
|
|||||||
void ComputeHidingSpots(); // analyze local area neighborhood to find "hiding spots" in this area - for map learning
|
void ComputeHidingSpots(); // analyze local area neighborhood to find "hiding spots" in this area - for map learning
|
||||||
void ComputeSniperSpots(); // analyze local area neighborhood to find "sniper spots" in this area - for map learning
|
void ComputeSniperSpots(); // analyze local area neighborhood to find "sniper spots" in this area - for map learning
|
||||||
|
|
||||||
|
bool HasSpotEncounter(const SpotEncounter *encounter);
|
||||||
SpotEncounter *GetSpotEncounter(const CNavArea *from, const CNavArea *to); // given the areas we are moving between, return the spots we will encounter
|
SpotEncounter *GetSpotEncounter(const CNavArea *from, const CNavArea *to); // given the areas we are moving between, return the spots we will encounter
|
||||||
void ComputeSpotEncounters(); // compute spot encounter data - for map learning
|
void ComputeSpotEncounters(); // compute spot encounter data - for map learning
|
||||||
|
|
||||||
|
@ -623,6 +623,13 @@ bool SaveNavigationMap(const char *filename)
|
|||||||
area->Save(fd, version);
|
area->Save(fd, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that all data is flushed to disk
|
||||||
|
#ifdef WIN32
|
||||||
|
_commit(fd);
|
||||||
|
#else
|
||||||
|
fsync(fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
_close(fd);
|
_close(fd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -932,7 +932,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Precise</FloatingPointModel>
|
||||||
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
||||||
<AdditionalOptions Condition="'$(PlatformToolset)' == 'v140_xp' OR '$(PlatformToolset)' == 'v141_xp'">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions Condition="'$(PlatformToolset)' == 'v140_xp' OR '$(PlatformToolset)' == 'v141_xp'">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
@ -969,7 +969,7 @@
|
|||||||
<Optimization>Full</Optimization>
|
<Optimization>Full</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>REGAMEDLL_ADD;REGAMEDLL_API;REGAMEDLL_FIXES;REGAMEDLL_SSE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;UNICODE_FIXES;BUILD_LATEST;BUILD_LATEST_FIXES;CLIENT_WEAPONS;USE_QSTRING;_CRT_SECURE_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<FloatingPointModel>Fast</FloatingPointModel>
|
<FloatingPointModel>Precise</FloatingPointModel>
|
||||||
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
||||||
<AdditionalOptions Condition="'$(PlatformToolset)' == 'v140_xp' OR '$(PlatformToolset)' == 'v141_xp'">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions Condition="'$(PlatformToolset)' == 'v140_xp' OR '$(PlatformToolset)' == 'v141_xp'">/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
@ -1102,6 +1102,7 @@
|
|||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
|
||||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
|
<FloatingPointModel>Precise</FloatingPointModel>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user