Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for secondary ammo and extra EF_ flags #934

Merged
merged 2 commits into from
Jan 31, 2024
Merged
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
5 changes: 5 additions & 0 deletions regamedll/common/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@
#define EF_FORCEVISIBILITY BIT(11) // force visibility
#define EF_OWNER_VISIBILITY BIT(12) // visibility for owner
#define EF_OWNER_NO_VISIBILITY BIT(13) // no visibility for owner
#define EF_NOSLERP BIT(14) // no slerp flag for this entity (addtofullpack)
#define EF_FOLLOWKEEPRENDER BIT(15) // the entity following will not copy the render (like it follows nothing)

// Custom flags that aren't handled by the client
#define EF_CUSTOM_BITS (EF_FORCEVISIBILITY | EF_OWNER_VISIBILITY | EF_OWNER_NO_VISIBILITY | EF_NOSLERP | EF_FOLLOWKEEPRENDER)

// state->eflags values
#define EFLAG_SLERP 1 // do studio interpolation of this entity
Expand Down
28 changes: 24 additions & 4 deletions regamedll/dlls/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void WriteSigonMessages()

#ifdef PLAY_GAMEDLL
// TODO: fix test demo
iFlags &= ~ITEM_FLAG_NOFIREUNDERWATER;
iFlags &= ~ITEM_FLAG_CUSTOM;
#endif

MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList);
Expand Down Expand Up @@ -4479,15 +4479,21 @@ BOOL EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, e

#ifdef REGAMEDLL_ADD
// don't send unhandled custom bits to client
state->effects &= ~(EF_FORCEVISIBILITY | EF_OWNER_VISIBILITY | EF_OWNER_NO_VISIBILITY);
state->effects &= ~EF_CUSTOM_BITS;

if (ent->v.skin == CONTENTS_LADDER &&
(host->v.iuser3 & PLAYER_PREVENT_CLIMB) == PLAYER_PREVENT_CLIMB) {
state->skin = CONTENTS_EMPTY;
}
#endif

if (!player && ent->v.animtime && !ent->v.velocity.x && !ent->v.velocity.y && !ent->v.velocity.z)
// add studio interpolation if non-player entity is moving (why?)
if (!player &&
#ifdef REGAMEDLL_ADD
// adds slerp (studio interpolation) if not set
!(ent->v.effects & EF_NOSLERP) &&
#endif
ent->v.animtime && !ent->v.velocity.x && !ent->v.velocity.y && !ent->v.velocity.z)
state->eflags |= EFLAG_SLERP;

state->scale = ent->v.scale;
Expand All @@ -4513,8 +4519,22 @@ BOOL EXT_FUNC AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, e

state->aiment = 0;

// following something
if (ent->v.aiment)
state->aiment = ENTINDEX(ent->v.aiment);
{
#ifdef REGAMEDLL_ADD
// if set, it will still follow the player with a bit of "delay", still looks fine (experimental)
if (ent->v.effects & EF_FOLLOWKEEPRENDER)
{
// will keep the current render entity values if it's set
state->movetype = MOVETYPE_NONE;
}
else
#endif
{
state->aiment = ENTINDEX(ent->v.aiment);
}
}

state->owner = 0;
if (ent->v.owner)
Expand Down
48 changes: 37 additions & 11 deletions regamedll/dlls/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,26 +1303,52 @@ CWeaponBox *EXT_FUNC __API_HOOK(CreateWeaponBox)(CBasePlayerItem *pItem, CBasePl
pWeaponBox->pev->nextthink = gpGlobals->time + lifeTime;
pWeaponBox->PackWeapon(pItem); // now pack all of the items in the lists

// pack the ammo
bool exhaustibleAmmo = (pItem->iFlags() & ITEM_FLAG_EXHAUSTIBLE) == ITEM_FLAG_EXHAUSTIBLE;
if ((exhaustibleAmmo || packAmmo) && pPlayerOwner)
// player is the ammo source
if (pPlayerOwner)
{
#ifndef REGAMEDLL_ADD
pWeaponBox->PackAmmo(MAKE_STRING(pItem->pszAmmo1()), pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()]);
#else
pWeaponBox->GiveAmmo(pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()], (char *)pItem->pszAmmo1(), pItem->iMaxAmmo1());
#endif
#ifndef REGAMEDLL_FIXES
// by removing ammo ONLY on exhaustible weapons (slot 4 and 5)
// you are allowing to duplicate ammo whenever:
// (1) you have 2 weapons sharing the same ammo type (e.g. mp5navy and glock)
// (2) you are dropping a weapon alive and pickup another (with same ammo type) without ammo
// and, logically, you throw your ammo with your gun with packing enabled
if (exhaustibleAmmo)
bool exhaustibleAmmo = (pItem->iFlags() & ITEM_FLAG_EXHAUSTIBLE) == ITEM_FLAG_EXHAUSTIBLE;

// pack the primary ammo
if (exhaustibleAmmo || packAmmo)
{
#ifndef REGAMEDLL_ADD
pWeaponBox->PackAmmo(MAKE_STRING(pItem->pszAmmo1()), pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()]);
#else
pWeaponBox->GiveAmmo(pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()], (char *)pItem->pszAmmo1(), pItem->iMaxAmmo1());
#endif

#ifndef REGAMEDLL_FIXES
if (exhaustibleAmmo)
#endif
{
pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
}
}

// (3rd party support) now that reapi can register custom ammo
#ifdef REGAMEDLL_ADD
// use this flag if you don't want the player harvesting this kind of ammo from dropped weapons
bool exhaustSecondaryAmmo = (pItem->iFlags() & ITEM_FLAG_EXHAUST_SECONDARYAMMO) == ITEM_FLAG_EXHAUST_SECONDARYAMMO;
int iSecondaryAmmoIndex = pItem->SecondaryAmmoIndex();

// pack secondary ammo now (must be valid too)
if ((exhaustibleAmmo || exhaustSecondaryAmmo || packAmmo) && iSecondaryAmmoIndex != -1)
{
pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
pWeaponBox->GiveAmmo(pPlayerOwner->m_rgAmmo[iSecondaryAmmoIndex], (char *)pItem->pszAmmo2(), pItem->iMaxAmmo2());

#ifndef REGAMEDLL_FIXES
if (exhaustibleAmmo)
#endif
{
pPlayerOwner->m_rgAmmo[iSecondaryAmmoIndex] = 0;
}
}
#endif
}

pWeaponBox->SetModel(modelName);
Expand Down
14 changes: 14 additions & 0 deletions regamedll/dlls/weapons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,9 +1259,19 @@ int CBasePlayerWeapon::AddToPlayer(CBasePlayer *pPlayer)
if (!m_iPrimaryAmmoType)
{
m_iPrimaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo1());
#ifndef REGAMEDLL_FIXES
m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2());
#endif
}

#ifdef REGAMEDLL_FIXES
// (3rd party support) if someone updates (or screws) the secondary ammo type later
if (!m_iSecondaryAmmoType)
{
m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2());
}
#endif

if (AddWeapon())
{
return CBasePlayerItem::AddToPlayer(pPlayer);
Expand Down Expand Up @@ -1587,7 +1597,11 @@ int CBasePlayerWeapon::PrimaryAmmoIndex()

int CBasePlayerWeapon::SecondaryAmmoIndex()
{
#ifdef REGAMEDLL_ADD
return m_iSecondaryAmmoType;
#else
return -1;
#endif
}

void CBasePlayerWeapon::Holster(int skiplocal)
Expand Down
16 changes: 10 additions & 6 deletions regamedll/dlls/weapons.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ const float MAX_DIST_RELOAD_SOUND = 512.0f;

#define MAX_WEAPONS 32

#define ITEM_FLAG_SELECTONEMPTY BIT(0)
#define ITEM_FLAG_NOAUTORELOAD BIT(1)
#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT(2)
#define ITEM_FLAG_LIMITINWORLD BIT(3)
#define ITEM_FLAG_EXHAUSTIBLE BIT(4) // A player can totally exhaust their ammo supply and lose this weapon
#define ITEM_FLAG_NOFIREUNDERWATER BIT(5)
#define ITEM_FLAG_SELECTONEMPTY BIT(0)
#define ITEM_FLAG_NOAUTORELOAD BIT(1)
#define ITEM_FLAG_NOAUTOSWITCHEMPTY BIT(2)
#define ITEM_FLAG_LIMITINWORLD BIT(3)
#define ITEM_FLAG_EXHAUSTIBLE BIT(4) // A player can totally exhaust their ammo supply and lose this weapon
#define ITEM_FLAG_NOFIREUNDERWATER BIT(5)
#define ITEM_FLAG_EXHAUST_SECONDARYAMMO BIT(6) // A player will exhaust weapon's secondary ammo supply if dropped (ITEM_FLAG_EXHAUSTIBLE does both)

// if someone has an idea for another flag pack it here, so client prediction will not be screwed (or something) if PLAY_GAMEDLL is defined
#define ITEM_FLAG_CUSTOM (ITEM_FLAG_NOFIREUNDERWATER | ITEM_FLAG_EXHAUST_SECONDARYAMMO)

#define WEAPON_IS_ONTARGET 0x40

Expand Down