Skip to content

Instantly share code, notes, and snippets.

@BSVino
Last active December 15, 2015 02:09
Show Gist options
  • Select an option

  • Save BSVino/5184877 to your computer and use it in GitHub Desktop.

Select an option

Save BSVino/5184877 to your computer and use it in GitHub Desktop.
static int pv_enter = 0;
static int pv_exit = 1;
void CSDKGameRules::CalculateSlowMoForPlayer(CSDKPlayer* pPlayer)
{
/*pv_enter should always be less than pv_exit.
If it isn't then it means this function is getting called asynchronously.
pv_enter and pv_exit are incremented at opposing sides of the function,
this is a cheap bid to increase the resolution of this diagnostic.*/
Assert (pv_enter < pv_exit);
if (!pPlayer)
return;
if (!pPlayer->IsAlive())
{
pPlayer->SetSlowMoType(SLOWMO_NONE);
return;
}
// If I activated slow then I get to keep my slow level.
if (pPlayer->GetSlowMoType() == SLOWMO_ACTIVATED)
return;
if (pPlayer->GetSlowMoType() == SLOWMO_STYLESKILL)
return;
// Players who haven't activated anything are at the whims of those who have.
if (gpGlobals->eLoadType == MapLoad_Background)
{
pPlayer->SetSlowMoType(SLOWMO_NONE);
return;
}
pv_enter++;
bool bOtherInSlow = false;
CUtlVector<CSDKPlayer*> apOthersInPVS;
CBaseEntity* pOther = NULL;
while ((pOther = UTIL_EntitiesInPVS(pPlayer, pOther)) != NULL)
{
CSDKPlayer* pOtherPlayer = ToSDKPlayer(pOther);
if (!pOtherPlayer)
continue;
if (pOtherPlayer == pPlayer)
continue;
apOthersInPVS.AddToTail(pOtherPlayer);
}
for (int i = 0; i < apOthersInPVS.Size(); i++)
{
CSDKPlayer* pOtherPlayer = apOthersInPVS[i];
if (!pOtherPlayer->IsAlive())
continue;
if (pOtherPlayer->GetSlowMoType() != SLOWMO_NONE)
{
bOtherInSlow = true;
break;
}
}
// If any of these players are in slow then I'm in slow too.
if (bOtherInSlow)
pPlayer->SetSlowMoType(SLOWMO_PASSIVE);
else
pPlayer->SetSlowMoType(SLOWMO_NONE);
pv_exit++;
}
void CSDKGameRules::PlayerSlowMoUpdate(CSDKPlayer* pPlayer)
{
if (!pPlayer)
return;
if (pPlayer->GetSlowMoType() == SLOWMO_NONE)
// I turned off my slow-mo. Circular activations are possible. Just re-calculate for all players.
ReCalculateSlowMo();
else
GiveSlowMoToNearbyPlayers(pPlayer);
}
static int pv_enter2 = 0;
static int pv_exit2 = 1;
void CSDKGameRules::GiveSlowMoToNearbyPlayers(CSDKPlayer* pPlayer)
{
/*pv_enter should always be less than pv_exit.
If it isn't then it means this function is getting called asynchronously.
pv_enter and pv_exit are incremented at opposing sides of the function,
this is a cheap bid to increase the resolution of this diagnostic.*/
Assert (pv_enter2 == 0);
pv_enter2 = 1;
if (!pPlayer)
{
pv_enter2 = 0;
return;
}
if (!pPlayer->IsAlive())
{
pPlayer->SetSlowMoType(SLOWMO_NONE);
pv_enter2 = 0;
return;
}
if (pPlayer->GetSlowMoType() == SLOWMO_NONE)
{
pv_enter2 = 0;
return;
}
// I have some slowmo on me. Pass it to other players nearby.
CUtlVector<CSDKPlayer*> apOthersInPVS;
CBaseEntity* pOther = NULL;
while ((pOther = UTIL_EntitiesInPVS(pPlayer, pOther)) != NULL)
{
CSDKPlayer* pOtherPlayer = ToSDKPlayer(pOther);
if (!pOtherPlayer)
continue;
if (pOtherPlayer == pPlayer)
continue;
// If they already have slow mo, we don't need to pass it to them.
if (pOtherPlayer->GetSlowMoType() == SLOWMO_STYLESKILL)
continue;
if (pOtherPlayer->GetSlowMoType() == SLOWMO_ACTIVATED)
continue;
if (pOtherPlayer->GetSlowMoType() == SLOWMO_PASSIVE)
continue;
apOthersInPVS.AddToTail(pOtherPlayer);
}
pv_enter2 = 0;
for (int i = 0; i < apOthersInPVS.Size(); i++)
{
CSDKPlayer* pOtherPlayer = apOthersInPVS[i];
// It could have been already done by a previous iteration of the recursion below.
if (pOtherPlayer->GetSlowMoType() != SLOWMO_NONE)
continue;
pOtherPlayer->SetSlowMoType(SLOWMO_PASSIVE);
GiveSlowMoToNearbyPlayers(pOtherPlayer); // --- We have to avoid this call ---
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment