Fixed detection mp_freeforall for regamedll.

Added missing addon entities for regamedll.
Fixed bots keep adding to game event when there is now spawn points left on map.
Reduced a little bot difficulty at higher levels.
This commit is contained in:
jeefo 2019-05-13 21:41:14 +03:00
commit 5a7dbc2463
8 changed files with 110 additions and 30 deletions

View file

@ -607,7 +607,7 @@ public:
return;
}
#ifdef PLATFORM_WIN32
FreeLibrary ((HMODULE)m_ptr);
FreeLibrary (static_cast <HMODULE> (m_ptr));
#else
dlclose (m_ptr);
#endif

View file

@ -99,6 +99,7 @@ struct LangComprarer {
class Engine : public Singleton <Engine> {
private:
int m_drawModels[DRAW_NUM];
int m_spawnCount[TEAM_UNASSIGNED];
// bot client command
char m_arguments[256];
@ -243,6 +244,11 @@ public:
return m_startEntity;
}
// get spawn count for team
inline int getSpawnCount (int team) {
return m_spawnCount[team];
}
// gets the player team
inline int getTeam (edict_t *ent) {
extern Client g_clients[MAX_ENGINE_PLAYERS];

View file

@ -55,11 +55,12 @@ enum GameFlags {
GAME_LEGACY = (1 << 3), // counter-strike 1.3-1.5 with/without steam
GAME_MOBILITY = (1 << 4), // additional flag that bot is running on android (additional flag)
GAME_OFFICIAL_CSBOT = (1 << 5), // additional flag that indicates official cs bots are in game
GAME_METAMOD = (1 << 6), // game running under metamod
GAME_METAMOD = (1 << 6), // game running under meta\mod
GAME_CSDM = (1 << 7), // csdm mod currently in use
GAME_CSDM_FFA = (1 << 8), // csdm mod with ffa mode
GAME_SUPPORT_SVC_PINGS = (1 << 9), // on that game version we can fake bots pings
GAME_SUPPORT_BOT_VOICE = (1 << 10) // on that game version we can use chatter
GAME_REGAMEDLL = (1 << 9), // server dll is a regamedll
GAME_SUPPORT_SVC_PINGS = (1 << 10), // on that game version we can fake bots pings
GAME_SUPPORT_BOT_VOICE = (1 << 11) // on that game version we can use chatter
};
// bot menu ids
@ -1297,6 +1298,7 @@ private:
float m_entityUpdateTime; // time to update intresting entities
int m_lastWinner; // the team who won previous round
int m_lastDifficulty; // last bots difficulty
bool m_leaderChoosen[MAX_TEAM_COUNT]; // is team leader choose theese round
bool m_economicsGood[MAX_TEAM_COUNT]; // is team able to buy anything
@ -1371,6 +1373,7 @@ public:
void listBots (void);
void setWeaponMode (int selection);
void updateTeamEconomics (int team, bool setTrue = false);
void updateBotDifficulties (void);
static void execGameEntity (entvars_t *vars);

View file

@ -201,6 +201,8 @@ bool Bot::lookupEnemies (void) {
edict_t *player, *newEnemy = nullptr;
float nearestDistance = cr::square (m_viewDistance);
extern ConVar yb_whose_your_daddy;
// clear suspected flag
if (!engine.isNullEntity (m_enemy) && (m_states & STATE_SEEING_ENEMY)) {
m_states &= ~STATE_SUSPECT_ENEMY;
@ -272,8 +274,8 @@ bool Bot::lookupEnemies (void) {
m_aimFlags |= AIM_ENEMY;
m_states |= STATE_SEEING_ENEMY;
if (newEnemy == m_enemy) {
// if enemy is still visible and in field of view, keep it keep track of when we last saw an enemy
if (newEnemy == m_enemy) {
m_seeEnemyTime = engine.timebase ();
// zero out reaction time
@ -284,12 +286,12 @@ bool Bot::lookupEnemies (void) {
return true;
}
else {
if (m_seeEnemyTime + 3.0 < engine.timebase () && (m_hasC4 || hasHostage () || !engine.isNullEntity (m_targetEntity))) {
if (m_seeEnemyTime + 3.0f < engine.timebase () && (m_hasC4 || hasHostage () || !engine.isNullEntity (m_targetEntity))) {
pushRadioMessage (RADIO_ENEMY_SPOTTED);
}
m_targetEntity = nullptr; // stop following when we see an enemy...
if (rng.getInt (0, 100) < m_difficulty * 25) {
if (yb_whose_your_daddy.boolean ()) {
m_enemySurpriseTime = m_actualReactionTime * 0.5f;
}
else {

View file

@ -28,6 +28,7 @@ Engine::Engine (void) {
memset (m_arguments, 0, sizeof (m_arguments));
memset (m_drawModels, 0, sizeof (m_drawModels));
memset (m_spawnCount, 0, sizeof (m_spawnCount));
m_cvars.clear ();
}
@ -70,6 +71,9 @@ void Engine::levelInitialize (void) {
m_localEntity = nullptr;
m_spawnCount[TEAM_COUNTER] = 0;
m_spawnCount[TEAM_TERRORIST] = 0;
// go thru the all entities on map, and do whatever we're want
for (int i = 0; i < g_pGlobals->maxEntities; i++) {
@ -101,6 +105,8 @@ void Engine::levelInitialize (void) {
ent->v.rendermode = kRenderTransAlpha; // set its render mode to transparency
ent->v.renderamt = 127; // set its transparency amount
ent->v.effects |= EF_NODRAW;
m_spawnCount[TEAM_COUNTER]++;
}
else if (strcmp (classname, "info_player_deathmatch") == 0) {
g_engfuncs.pfnSetModel (ent, ENGINE_STR ("models/player/terror/terror.mdl"));
@ -108,6 +114,8 @@ void Engine::levelInitialize (void) {
ent->v.rendermode = kRenderTransAlpha; // set its render mode to transparency
ent->v.renderamt = 127; // set its transparency amount
ent->v.effects |= EF_NODRAW;
m_spawnCount[TEAM_TERRORIST]++;
}
else if (strcmp (classname, "info_vip_start") == 0) {
@ -1280,5 +1288,5 @@ float LightMeasure::getLightLevel (const Vector &point) {
}
float LightMeasure::getSkyColor (void) {
return (sv_skycolor_r.flt () + sv_skycolor_g.flt () + sv_skycolor_b.flt ()) / 3;
return sv_skycolor_r.flt () + sv_skycolor_g.flt () + sv_skycolor_b.flt ();
}

View file

@ -2247,18 +2247,22 @@ void StartFrame (void) {
// calculate light levels for all waypoints if needed
waypoints.initLightLevels ();
if (g_gameFlags & GAME_METAMOD) {
if (g_gameFlags & (GAME_METAMOD | GAME_REGAMEDLL)) {
static auto dmActive = g_engfuncs.pfnCVarGetPointer ("csdm_active");
static auto freeForAll = g_engfuncs.pfnCVarGetPointer ("mp_freeforall");
if (dmActive && freeForAll) {
// csdm is only with amxx and metamod
if (dmActive) {
if (dmActive->value > 0.0f) {
g_gameFlags |= GAME_CSDM;
}
else if (g_gameFlags & GAME_CSDM) {
g_gameFlags &= ~GAME_CSDM;
}
}
// but this can be provided by regamedll
if (freeForAll) {
if (freeForAll->value > 0.0f) {
g_gameFlags |= GAME_CSDM_FFA;
}
@ -3031,8 +3035,9 @@ SHARED_LIBRARAY_EXPORT void Meta_Init (void) {
Library *LoadCSBinary (void) {
const char *modname = engine.getModName ();
if (!modname)
if (!modname) {
return nullptr;
}
#if defined(PLATFORM_WIN32)
const char *libs[] = {"mp.dll", "cs.dll"};
@ -3042,6 +3047,22 @@ Library *LoadCSBinary (void) {
const char *libs[] = {"cs.dylib"};
#endif
auto libCheck = [] (Library *lib, const char *modname, const char *dll) {
// try to load gamedll
if (!lib->isValid ()) {
logEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", dll, modname);
return false;
}
auto ent = lib->resolve <entity_func_t> ("trigger_random_unique");
// detect regamedll by addon entity they provide
if (ent != nullptr) {
g_gameFlags |= GAME_REGAMEDLL;
}
return true;
};
// search the libraries inside game dlls directory
for (size_t i = 0; i < cr::arrsize (libs); i++) {
auto *path = format ("%s/dlls/%s", modname, libs[i]);
@ -3058,18 +3079,24 @@ Library *LoadCSBinary (void) {
if (g_gameFlags & GAME_METAMOD) {
return nullptr;
}
return new Library (path);
}
else {
Library *game = new Library (path);
// try to load gamedll
if (!game->isValid ()) {
logEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", libs[i], modname);
auto game = new Library (path);
// verify dll is OK
if (!libCheck (game, modname, libs[i])) {
delete game;
return nullptr;
}
return game;
}
else {
auto game = new Library (path);
// verify dll is OK
if (!libCheck (game, modname, libs[i])) {
delete game;
return nullptr;
}
// detect if we're running modern game
auto entity = game->resolve <entity_func_t> ("weapon_famas");
@ -3159,8 +3186,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
delete g_gameLib;
}
#else
g_gameLib = LoadCSBinary ();
{
g_gameLib = LoadCSBinary (); {
if (!g_gameLib && !(g_gameFlags & GAME_METAMOD)) {
logEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", engine.getModName ());
return;
@ -3178,6 +3204,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
else if (g_gameFlags & GAME_CSTRIKE16) {
gameVersionStr.assign ("v1.6");
}
if (g_gameFlags & GAME_XASH_ENGINE) {
gameVersionStr.append (" @ Xash3D Engine");
@ -3191,6 +3218,10 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
gameVersionStr.append (" (BV)");
}
if (g_gameFlags & GAME_REGAMEDLL) {
gameVersionStr.append (" (RE)");
}
if (g_gameFlags & GAME_SUPPORT_SVC_PINGS) {
gameVersionStr.append (" (SVC)");
}
@ -3357,6 +3388,7 @@ LINK_ENTITY (info_teleport_destination)
LINK_ENTITY (info_vip_start)
LINK_ENTITY (infodecal)
LINK_ENTITY (item_airtank)
LINK_ENTITY (item_airbox)
LINK_ENTITY (item_antidote)
LINK_ENTITY (item_assaultsuit)
LINK_ENTITY (item_battery)
@ -3382,6 +3414,8 @@ LINK_ENTITY (path_track)
LINK_ENTITY (player)
LINK_ENTITY (player_loadsaved)
LINK_ENTITY (player_weaponstrip)
LINK_ENTITY (point_clientcommand)
LINK_ENTITY (point_servercommand)
LINK_ENTITY (soundent)
LINK_ENTITY (spark_shower)
LINK_ENTITY (speaker)
@ -3402,7 +3436,11 @@ LINK_ENTITY (trigger_monsterjump)
LINK_ENTITY (trigger_multiple)
LINK_ENTITY (trigger_once)
LINK_ENTITY (trigger_push)
LINK_ENTITY (trigger_random)
LINK_ENTITY (trigger_random_time)
LINK_ENTITY (trigger_random_unique)
LINK_ENTITY (trigger_relay)
LINK_ENTITY (trigger_setorigin)
LINK_ENTITY (trigger_teleport)
LINK_ENTITY (trigger_transition)
LINK_ENTITY (weapon_ak47)

View file

@ -31,6 +31,7 @@ ConVar mp_autoteambalance ("mp_autoteambalance", nullptr, VT_NOREGISTER);
BotManager::BotManager (void) {
// this is a bot manager class constructor
m_lastDifficulty = 0;
m_lastWinner = -1;
m_deathMsgSent = false;
@ -385,6 +386,10 @@ void BotManager::maintainQuota (void) {
if (m_quotaMaintainTime > engine.timebase ()) {
return;
}
// not a best place for this, but whatever
updateBotDifficulties ();
yb_quota.set (cr::clamp <int> (yb_quota.integer (), 0, engine.maxClients ()));
int totalHumansInGame = getHumansCount ();
@ -417,9 +422,10 @@ void BotManager::maintainQuota (void) {
else {
desiredBotCount = cr::min <int> (desiredBotCount, maxClients - humanPlayersInGame);
}
int maxSpawnCount = engine.getSpawnCount (TEAM_TERRORIST) + engine.getSpawnCount (TEAM_COUNTER);
// add bots if necessary
if (desiredBotCount > botsInGame) {
if (desiredBotCount > botsInGame && botsInGame < maxSpawnCount) {
createRandom ();
}
else if (desiredBotCount < botsInGame) {
@ -825,6 +831,23 @@ void BotManager::updateTeamEconomics (int team, bool forceGoodEconomics) {
}
}
void BotManager::updateBotDifficulties (void) {
int difficulty = yb_difficulty.integer ();
if (difficulty != m_lastDifficulty) {
// sets new difficulty for all bots
for (int i = 0; i < engine.maxClients (); i++) {
auto bot = m_bots[i];
if (bot != nullptr) {
m_bots[i]->m_difficulty = difficulty;
}
}
m_lastDifficulty = difficulty;
}
}
void BotManager::destroy (void) {
// this function free all bots slots (used on server shutdown)