Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions regamedll/dlls/API/CAPI_Impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,19 @@ bool CReGameApi::BGetIGameRules(const char *pchVersion) const
return false;
}

void CReGameApi::QueueHudMessage(int client, const struct hudtextparms_s &textparms, const char *pMessage)
{
if (client == 0)
{
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
g_HudQueue.QueueMessage(i, textparms, pMessage);
}
}
else
{
g_HudQueue.QueueMessage(client, textparms, pMessage);
}
}

EXPOSE_SINGLE_INTERFACE(CReGameApi, IReGameApi, VRE_GAMEDLL_API_VERSION);
1 change: 1 addition & 0 deletions regamedll/dlls/API/CAPI_Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,4 +1116,5 @@ class CReGameApi: public IReGameApi {
EXT_FUNC virtual AmmoInfoStruct *GetAmmoInfoEx(const char *ammoName);
EXT_FUNC virtual bool BGetICSEntity(const char *pchVersion) const;
EXT_FUNC virtual bool BGetIGameRules(const char *pchVersion) const;
EXT_FUNC virtual void QueueHudMessage(int client, const struct hudtextparms_s &textparms, const char *pMessage);
};
61 changes: 60 additions & 1 deletion regamedll/dlls/client.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "precompiled.h"
#include "weapons.h"
#include "gamerules.h"

int gmsgWeapPickup = 0;
int gmsgHudText = 0;
Expand Down Expand Up @@ -3910,7 +3912,7 @@ void EXT_FUNC PlayerPostThink(edict_t *pEntity)

void EXT_FUNC ParmsNewLevel()
{
;
g_HudQueue.Reset();
}

void EXT_FUNC ParmsChangeLevel()
Expand All @@ -3924,6 +3926,60 @@ void EXT_FUNC ParmsChangeLevel()
}
}

extern cvar_t entity_gc;

void CollectGarbage()
{
if (entity_gc.value <= 0.0f)
return;

// Check if we are near the max entities limit
if (NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE))
return;

int count = 0;
// We iterate from oldest (lowest index) to newest
for (int i = 1; i < gpGlobals->maxEntities; i++)
{
edict_t *pEdict = INDEXENT(i);
if (!pEdict || pEdict->free)
continue;

CBaseEntity *pEntity = CBaseEntity::Instance(pEdict);
if (!pEntity)
continue;

if (FClassnameIs(pEdict, "weaponbox"))
{
CWeaponBox *pBox = (CWeaponBox *)pEntity;
if (pBox->m_bIsBomb)
continue; // DO NOT remove the C4!

UTIL_Remove(pEntity);
count++;
}
else if (FClassnameIs(pEdict, "weapon_shield"))
{
UTIL_Remove(pEntity);
count++;
}
else if (FClassnameIs(pEdict, "gib"))
{
UTIL_Remove(pEntity);
count++;
}

// Stop if we cleared enough entities (e.g., 50 entities) to avoid lagging the server by doing too much at once
if (count >= 50)
break;
}

if (count > 0)
{
ALERT(at_console, "Garbage Collector: Removed %d old entities to prevent server crash.\n", count);
}
}

void EXT_FUNC StartFrame()
{
if (g_pGameRules)
Expand All @@ -3933,6 +3989,9 @@ void EXT_FUNC StartFrame()
return;
}

CollectGarbage();

g_HudQueue.Think();
CLocalNav::Think();

gpGlobals->teamplay = 1.0f;
Expand Down
2 changes: 2 additions & 0 deletions regamedll/dlls/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cvar_t fragsleft = { "mp_fragsleft", "0", FCVAR_SERVER | FCVAR_UNLOG
cvar_t timeleft = { "mp_timeleft", "0", FCVAR_SERVER | FCVAR_UNLOGGED, 0.0f, nullptr };

cvar_t friendlyfire = { "mp_friendlyfire", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t entity_gc = { "mp_entity_gc", "1", 0, 0.0f, nullptr };
cvar_t infiniteAmmo = { "mp_infinite_ammo", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t infiniteGrenades = { "mp_infinite_grenades", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t allowmonsters = { "mp_allowmonsters", "0", FCVAR_SERVER, 0.0f, nullptr };
Expand Down Expand Up @@ -279,6 +280,7 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&displaysoundlist);
CVAR_REGISTER(&timelimit);
CVAR_REGISTER(&friendlyfire);
CVAR_REGISTER(&entity_gc);

#ifdef BUILD_LATEST
CVAR_REGISTER(&infiniteAmmo);
Expand Down
1 change: 1 addition & 0 deletions regamedll/dlls/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extern cvar_t fadetoblack;
extern cvar_t fragsleft;
extern cvar_t timeleft;
extern cvar_t friendlyfire;
extern cvar_t entity_gc;
extern cvar_t infiniteAmmo;
extern cvar_t infiniteGrenades;
extern cvar_t allowmonsters;
Expand Down
Empty file added regamedll/dlls/hud_queue.cpp
Empty file.
145 changes: 113 additions & 32 deletions regamedll/dlls/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,47 +592,128 @@ void UTIL_ScreenFade(CBaseEntity *pEntity, const Vector &color, float fadeTime,
UTIL_ScreenFadeWrite(fade, pEntity);
}

CHudMessageQueue g_HudQueue;

CHudMessageQueue::CHudMessageQueue() {
Reset();
}

void CHudMessageQueue::Reset() {
for (int i = 0; i < 33; i++) {
for (int j = 0; j < NUM_HUD_CHANNELS; j++) {
m_players[i].channelFreeTime[j] = 0.0f;
}
for (int j = 0; j < MAX_HUD_QUEUE; j++) {
m_players[i].messages[j].inUse = false;
}
}
}

void CHudMessageQueue::QueueMessage(int client, const hudtextparms_t &textparms, const char *pMessage) {
if (client < 1 || client >= 33) return;

int freeSlot = -1;
for (int i = 0; i < MAX_HUD_QUEUE; i++) {
if (!m_players[client].messages[i].inUse) {
freeSlot = i;
break;
}
}

if (freeSlot == -1) {
return;
}

m_players[client].messages[freeSlot].textparms = textparms;
Q_strlcpy(m_players[client].messages[freeSlot].message, pMessage, sizeof(m_players[client].messages[freeSlot].message));
m_players[client].messages[freeSlot].inUse = true;
}

void CHudMessageQueue::Think() {
float currentTime = gpGlobals->time;

for (int i = 1; i <= gpGlobals->maxClients; i++) {
CBaseEntity *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer || !pPlayer->IsNetClient())
continue;

for (int j = 0; j < MAX_HUD_QUEUE; j++) {
if (!m_players[i].messages[j].inUse)
continue;

hudtextparms_t parms = m_players[i].messages[j].textparms;

int targetChannel = parms.channel - 1;
if (parms.channel <= 0 || parms.channel > NUM_HUD_CHANNELS) {
int bestChannel = 0;
float oldestTime = m_players[i].channelFreeTime[0];
for (int c = 1; c < NUM_HUD_CHANNELS; c++) {
if (m_players[i].channelFreeTime[c] < oldestTime) {
oldestTime = m_players[i].channelFreeTime[c];
bestChannel = c;
}
}
targetChannel = bestChannel;
parms.channel = bestChannel + 1;
}

if (currentTime >= m_players[i].channelFreeTime[targetChannel]) {
UTIL_HudMessage(pPlayer, parms, m_players[i].messages[j].message);
m_players[i].channelFreeTime[targetChannel] = currentTime + parms.fadeinTime + parms.holdTime + parms.fadeoutTime + 0.2f;

m_players[i].messages[j].inUse = false;
}
}
}
}

void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage)
{
if (!pEntity || !pEntity->IsNetClient())
return;

MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, nullptr, pEntity->edict());
WRITE_BYTE(TE_TEXTMESSAGE);
WRITE_BYTE(textparms.channel & 0xFF);
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13)));
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13)));
WRITE_BYTE(textparms.effect);
WRITE_BYTE(textparms.r1);
WRITE_BYTE(textparms.g1);
WRITE_BYTE(textparms.b1);
WRITE_BYTE(textparms.a1);
WRITE_BYTE(textparms.r2);
WRITE_BYTE(textparms.g2);
WRITE_BYTE(textparms.b2);
WRITE_BYTE(textparms.a2);
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8)));
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8)));
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8)));

if (textparms.effect == 2)
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8)));

if (!pMessage)
WRITE_STRING(" ");
WRITE_BYTE(TE_TEXTMESSAGE);
WRITE_BYTE(textparms.channel & 0xFF);

WRITE_SHORT(FixedSigned16(textparms.x, 1 << 13));
WRITE_SHORT(FixedSigned16(textparms.y, 1 << 13));
WRITE_BYTE(textparms.effect);

WRITE_BYTE(textparms.r1);
WRITE_BYTE(textparms.g1);
WRITE_BYTE(textparms.b1);
WRITE_BYTE(textparms.a1);

WRITE_BYTE(textparms.r2);
WRITE_BYTE(textparms.g2);
WRITE_BYTE(textparms.b2);
WRITE_BYTE(textparms.a2);

WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, 1 << 8));
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, 1 << 8));
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, 1 << 8));

if (textparms.effect == 2)
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, 1 << 8));

if (!pMessage)
{
WRITE_STRING(" ");
}
else
{
if (Q_strlen(pMessage) >= 512)
{
char tmp[512];
Q_strlcpy(tmp, pMessage);
WRITE_STRING(tmp);
}
else
{
if (Q_strlen(pMessage) >= 512)
{
char tmp[512];
Q_strlcpy(tmp, pMessage);
WRITE_STRING(tmp);
}
else
{
WRITE_STRING(pMessage);
}
WRITE_STRING(pMessage);
}
}
MESSAGE_END();
}

Expand Down
30 changes: 30 additions & 0 deletions regamedll/dlls/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,36 @@ void UTIL_ScreenFadeBuild(ScreenFade &fade, const Vector &color, float fadeTime,
void UTIL_ScreenFadeWrite(const ScreenFade &fade, CBaseEntity *pEntity);
void UTIL_ScreenFadeAll(const Vector &color, float fadeTime, float fadeHold, int alpha, int flags);
void UTIL_ScreenFade(CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold = 0.0f, int alpha = 0, int flags = 0);
// ----------------------------------------------------
// Native HUD Messages Queue
// ----------------------------------------------------
#define MAX_HUD_QUEUE 10
#define NUM_HUD_CHANNELS 4

struct QueuedHudMessage_t {
hudtextparms_t textparms;
char message[512];
bool inUse;
};

class CHudMessageQueue {
public:
CHudMessageQueue();

void QueueMessage(int client, const hudtextparms_t &textparms, const char *pMessage);
void Think();
void Reset();

private:
struct PlayerHudQueue {
QueuedHudMessage_t messages[MAX_HUD_QUEUE];
float channelFreeTime[NUM_HUD_CHANNELS];
};
PlayerHudQueue m_players[33];
};

extern CHudMessageQueue g_HudQueue;

void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage);
void UTIL_HudMessageAll(const hudtextparms_t &textparms, const char *pMessage);
void UTIL_ClientPrintAll(int msg_dest, const char *msg_name, const char *param1 = nullptr, const char *param2 = nullptr, const char *param3 = nullptr, const char *param4 = nullptr);
Expand Down
1 change: 1 addition & 0 deletions regamedll/public/regamedll/regamedll_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ class IReGameApi {
virtual struct AmmoInfoStruct *GetAmmoInfoEx(const char *ammoName) = 0;
virtual bool BGetICSEntity(const char *pchVersion) const = 0;
virtual bool BGetIGameRules(const char *pchVersion) const = 0;
virtual void QueueHudMessage(int client, const struct hudtextparms_s &textparms, const char *pMessage) = 0;
};

#define VRE_GAMEDLL_API_VERSION "VRE_GAMEDLL_API_VERSION001"
Loading