cs16-client-legacy/dlls/observer.cpp
2015-12-27 14:32:17 +03:00

517 lines
12 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#include "stdafx.h"
#include "cbase.h"
#include "player.h"
#include "weapons.h"
#include "game.h"
#include "pm_shared.h"
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
extern int gmsgCrosshair;
extern int gmsgCurWeapon;
extern int gmsgStatusIcon;
extern int gmsgSetFOV;
extern int gmsgSpecHealth2;
extern int gmsgNVGToggle;
int GetForceCamera(void)
{
int retVal;
if (!fadetoblack.value)
{
retVal = (int)CVAR_GET_FLOAT("mp_forcechasecam");
if (retVal == FORCECAMERA_SPECTATE_ANYONE)
retVal = (int)CVAR_GET_FLOAT("mp_forcecamera");
}
else
retVal = FORCECAMERA_ONLY_FRIST_PERSON;
return retVal;
}
CBaseEntity *CBasePlayer::Observer_IsValidTarget(int iTarget, bool bOnlyTeam)
{
if (iTarget > gpGlobals->maxClients || iTarget < 1)
return NULL;
CBasePlayer *pEnt = (CBasePlayer *)UTIL_PlayerByIndex(iTarget);
if (!pEnt || pEnt == this || pEnt->has_disconnected || pEnt->IsObserver() || (pEnt->pev->effects & EF_NODRAW) || pEnt->m_iTeam == TEAM_UNASSIGNED || (bOnlyTeam && pEnt->m_iTeam != m_iTeam))
return NULL;
return pEnt;
}
void UpdateClientEffects(CBasePlayer *pObserver, int oldMode);
void CBasePlayer::Observer_FindNextPlayer(bool bReverse, char *name)
{
int iStart;
int iCurrent;
int iDir;
bool bForceSameTeam;
CBasePlayer *pPlayer;
if (m_flNextFollowTime && gpGlobals->time < m_flNextFollowTime)
return;
m_flNextFollowTime = gpGlobals->time + 0.25;
iStart = m_hObserverTarget ? ENTINDEX(m_hObserverTarget->edict()) : ENTINDEX(edict());
iCurrent = iStart;
m_hObserverTarget = NULL;
iDir = bReverse ? -1 : 1;
bForceSameTeam = (GetForceCamera() != FORCECAMERA_SPECTATE_ANYONE && m_iTeam != TEAM_SPECTATOR);
do
{
iCurrent += iDir;
if (iCurrent > gpGlobals->maxClients)
iCurrent = 1;
else if (iCurrent < 1)
iCurrent = gpGlobals->maxClients;
m_hObserverTarget = Observer_IsValidTarget(iCurrent, bForceSameTeam);
if (m_hObserverTarget)
{
if (!name)
break;
pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(ENTINDEX(m_hObserverTarget->edict()));
if (!strcmp(name, STRING(pPlayer->pev->netname)))
break;
}
}
while (iCurrent != iStart);
if (m_hObserverTarget)
{
UTIL_SetOrigin(pev, m_hObserverTarget->pev->origin);
MESSAGE_BEGIN(MSG_ONE, gmsgSpecHealth2, NULL, pev);
WRITE_BYTE(min(0, m_hObserverTarget->pev->health));
WRITE_BYTE(ENTINDEX(m_hObserverTarget->edict()));
MESSAGE_END();
if (pev->iuser1 != OBS_ROAMING)
pev->iuser2 = ENTINDEX(m_hObserverTarget->edict());
UpdateClientEffects(this, pev->iuser1);
}
}
void UpdateClientEffects(CBasePlayer *pObserver, int oldMode)
{
bool clearProgress = false;
bool clearBlindness = false;
bool blindnessOk = fadetoblack.value == 0 ? true : false;
bool clearNightvision = false;
if (oldMode == OBS_IN_EYE && pObserver->pev->iuser1 != OBS_IN_EYE)
{
clearProgress = true;
clearBlindness = true;
clearNightvision = true;
}
if (pObserver->pev->iuser1 == OBS_IN_EYE)
{
clearProgress = true;
clearBlindness = true;
clearNightvision = true;
if (pObserver->m_hObserverTarget->IsPlayer())
{
CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(ENTINDEX(pObserver->m_hObserverTarget->edict()));
if (pPlayer)
{
if (pPlayer->m_progressStart != 0)
{
if (pPlayer->m_progressEnd > pPlayer->m_progressStart)
{
if (pPlayer->m_progressEnd > gpGlobals->time)
{
float percentRemaining = gpGlobals->time - pPlayer->m_progressStart;
pObserver->SetProgressBarTime2(pPlayer->m_progressEnd - pPlayer->m_progressStart, percentRemaining);
clearProgress = false;
}
}
}
}
if (blindnessOk)
{
if (pPlayer)
{
if (pPlayer->m_blindStartTime != 0)
{
if (pPlayer->m_blindFadeTime != 0)
{
float fadeTime, holdTime, alpha, ratio;
float endTime = pPlayer->m_blindFadeTime + pPlayer->m_blindHoldTime + pPlayer->m_blindStartTime;
if (endTime > gpGlobals->time)
{
clearBlindness = false;
fadeTime = pPlayer->m_blindFadeTime;
alpha = pPlayer->m_blindAlpha;
holdTime = pPlayer->m_blindHoldTime + pPlayer->m_blindStartTime - gpGlobals->time;
if (holdTime <= 0)
{
holdTime = 0;
ratio = (endTime - gpGlobals->time) / pPlayer->m_blindFadeTime;
alpha = pPlayer->m_blindAlpha * ratio;
fadeTime = ratio * fadeTime;
}
UTIL_ScreenFade(pObserver, Vector(255, 255, 255), fadeTime, holdTime, alpha, 0);
}
}
}
}
}
clearNightvision = false;
if (pPlayer->m_bNightVisionOn != pObserver->m_bNightVisionOn)
{
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
WRITE_BYTE(pPlayer->m_bNightVisionOn != false);
MESSAGE_END();
pObserver->m_bNightVisionOn = pPlayer->m_bNightVisionOn;
}
}
}
if (clearProgress)
pObserver->SetProgressBarTime(0);
if (blindnessOk && clearBlindness)
UTIL_ScreenFade(pObserver, Vector(0, 0, 0), 0.001, 0, 0, 0);
if (clearNightvision)
{
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, NULL, pObserver->pev);
WRITE_BYTE(0);
MESSAGE_END();
pObserver->m_bNightVisionOn = false;
}
}
void CBasePlayer::Observer_HandleButtons(void)
{
if (m_flNextObserverInput > gpGlobals->time)
return;
if (m_afButtonPressed & IN_JUMP)
{
if (pev->iuser1 == OBS_CHASE_LOCKED)
Observer_SetMode(OBS_IN_EYE);
else if (pev->iuser1 == OBS_CHASE_FREE)
Observer_SetMode(OBS_IN_EYE);
else if (pev->iuser1 == OBS_IN_EYE)
Observer_SetMode(OBS_ROAMING);
else if (pev->iuser1 == OBS_ROAMING)
Observer_SetMode(OBS_MAP_FREE);
else if (pev->iuser1 == OBS_MAP_FREE)
Observer_SetMode(OBS_MAP_CHASE);
else
Observer_SetMode(m_bObserverAutoDirector ? OBS_CHASE_LOCKED : OBS_CHASE_FREE);
m_flNextObserverInput = gpGlobals->time + 0.2;
}
if (m_afButtonPressed & IN_ATTACK)
{
Observer_FindNextPlayer(false);
m_flNextObserverInput = gpGlobals->time + 0.2;
}
if (m_afButtonPressed & IN_ATTACK2)
{
Observer_FindNextPlayer(true);
m_flNextObserverInput = gpGlobals->time + 0.2;
}
}
void CBasePlayer::Observer_CheckTarget(void)
{
int iPlayerIndex;
CBasePlayer *pEnt;
int lastMode;
if (pev->iuser1 == OBS_ROAMING && m_bWasFollowing == false)
return;
if (m_bWasFollowing == true)
{
Observer_FindNextPlayer(false);
if (m_hObserverTarget)
Observer_SetMode(m_iObserverLastMode);
return;
}
if (m_hObserverTarget == NULL)
Observer_FindNextPlayer(false);
if (m_hObserverTarget)
{
iPlayerIndex = ENTINDEX(ENT(m_hObserverTarget->pev));
pEnt = (CBasePlayer *)UTIL_PlayerByIndex(iPlayerIndex);
if (!pEnt || pEnt->pev->deadflag == DEAD_RESPAWNABLE || (pEnt->pev->effects & EF_NODRAW))
{
Observer_FindNextPlayer(false);
}
else
{
if (pEnt->pev->deadflag == DEAD_DEAD && gpGlobals->time > pEnt->m_fDeadTime + 2)
{
Observer_FindNextPlayer(false);
if (m_hObserverTarget == NULL)
{
lastMode = pev->iuser1;
Observer_SetMode(OBS_ROAMING);
m_iObserverLastMode = lastMode;
m_bWasFollowing = true;
}
}
}
}
else
{
lastMode = pev->iuser1;
Observer_SetMode(OBS_ROAMING);
m_iObserverLastMode = lastMode;
}
}
void CBasePlayer::Observer_CheckProperties(void)
{
if (pev->iuser1 == OBS_IN_EYE && m_hObserverTarget != NULL)
{
CBasePlayer *target = (CBasePlayer *)UTIL_PlayerByIndex(ENTINDEX(ENT(m_hObserverTarget->pev)));
if (!target)
return;
int weapon = target->m_pActiveItem ? target->m_pActiveItem->m_iId : 0;
if (m_iFOV != target->m_iFOV || m_iObserverWeapon != weapon)
{
m_iClientFOV = m_iFOV = target->m_iFOV;
MESSAGE_BEGIN(MSG_ONE, gmsgSetFOV, NULL, pev);
WRITE_BYTE(m_iFOV);
MESSAGE_END();
m_iObserverWeapon = weapon;
MESSAGE_BEGIN(MSG_ONE, gmsgCurWeapon, NULL, pev);
WRITE_BYTE(1);
WRITE_BYTE(m_iObserverWeapon);
WRITE_BYTE(0);
MESSAGE_END();
}
int targetBombState = STATUSICON_HIDE;
if (target->m_bHasC4)
{
if (target->m_signals.GetState() & SIGNAL_BOMB)
targetBombState = STATUSICON_FLASH;
else
targetBombState = STATUSICON_SHOW;
}
if (m_iObserverC4State != targetBombState)
{
m_iObserverC4State = targetBombState;
if (targetBombState)
{
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(m_iObserverC4State);
WRITE_STRING("c4");
WRITE_BYTE(0);
WRITE_BYTE(160);
WRITE_BYTE(0);
MESSAGE_END();
}
else
{
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(STATUSICON_HIDE);
WRITE_STRING("c4");
MESSAGE_END();
}
}
if (m_bObserverHasDefuser != target->m_bHasDefuser)
{
m_bObserverHasDefuser = target->m_bHasDefuser;
if (target->m_bHasDefuser)
{
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(STATUSICON_SHOW);
WRITE_STRING("defuser");
WRITE_BYTE(0);
WRITE_BYTE(160);
WRITE_BYTE(0);
MESSAGE_END();
}
else
{
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(STATUSICON_HIDE);
WRITE_STRING("defuser");
MESSAGE_END();
}
}
return;
}
m_iFOV = 90;
if (m_iObserverWeapon)
{
m_iObserverWeapon = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgCurWeapon, NULL, pev);
WRITE_BYTE(1);
WRITE_BYTE(m_iObserverWeapon);
WRITE_BYTE(0);
MESSAGE_END();
}
if (m_iObserverC4State)
{
m_iObserverC4State = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(0);
WRITE_STRING("c4");
MESSAGE_END();
}
if (m_bObserverHasDefuser)
{
m_bObserverHasDefuser = false;
MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, NULL, pev);
WRITE_BYTE(0);
WRITE_STRING("defuser");
MESSAGE_END();
}
}
void CBasePlayer::Observer_SetMode(int iMode)
{
int forcecamera;
int oldMode;
char modemsg[16];
if (iMode == pev->iuser1)
return;
forcecamera = GetForceCamera();
if (iMode < OBS_CHASE_LOCKED || iMode > OBS_MAP_CHASE)
iMode = OBS_IN_EYE;
oldMode = pev->iuser1;
if (m_iTeam != TEAM_SPECTATOR)
{
if (forcecamera == FORCECAMERA_SPECTATE_ONLY_TEAM)
{
if (iMode == OBS_ROAMING)
iMode = OBS_MAP_FREE;
}
else if (forcecamera == FORCECAMERA_ONLY_FRIST_PERSON)
iMode = OBS_IN_EYE;
}
if (m_hObserverTarget)
{
CBasePlayer *pEnt = (CBasePlayer *)((CBaseEntity *)m_hObserverTarget);
if (pEnt == this || !pEnt || pEnt->has_disconnected || pEnt->IsObserver() || (pEnt->pev->effects & EF_NODRAW) || (forcecamera != FORCECAMERA_SPECTATE_ANYONE && pEnt->m_iTeam != m_iTeam))
m_hObserverTarget = NULL;
}
pev->iuser1 = iMode;
if (iMode != OBS_ROAMING)
{
if (m_hObserverTarget == NULL)
{
Observer_FindNextPlayer(false);
if (m_hObserverTarget == NULL)
{
ClientPrint(pev, HUD_PRINTCENTER, "#Spec_NoTarget");
pev->iuser1 = OBS_ROAMING;
}
}
}
if (pev->iuser1 != OBS_ROAMING)
pev->iuser2 = ENTINDEX(ENT(m_hObserverTarget->pev));
else
pev->iuser2 = 0;
pev->iuser3 = 0;
if (m_hObserverTarget)
UTIL_SetOrigin(pev, m_hObserverTarget->pev->origin);
MESSAGE_BEGIN(MSG_ONE, gmsgCrosshair, NULL, pev);
WRITE_BYTE((iMode == OBS_ROAMING) ? 1 : 0);
MESSAGE_END();
UpdateClientEffects(this, oldMode);
sprintf(modemsg, "#Spec_Mode%i", pev->iuser1);
ClientPrint(pev, HUD_PRINTCENTER, modemsg);
m_iObserverLastMode = iMode;
m_bWasFollowing = false;
}