ReGameDLL_CS/regamedll/dlls/tutor_base_tutor.cpp

381 lines
8.0 KiB
C++
Raw Normal View History

2015-06-30 12:46:07 +03:00
#include "precompiled.h"
2017-10-12 17:50:56 +03:00
CBaseTutor *TheTutor = nullptr;
2015-06-30 12:46:07 +03:00
2015-08-20 13:35:01 +03:00
TutorMessageEvent::TutorMessageEvent(int mid, int duplicateID, float time, float lifetime, int priority)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
m_messageID = mid;
m_duplicateID = duplicateID;
m_activationTime = time;
m_lifetime = lifetime;
m_priority = priority;
2017-10-12 17:50:56 +03:00
m_paramList = nullptr;
2015-08-20 13:35:01 +03:00
m_numParameters = 0;
2017-10-12 17:50:56 +03:00
m_next = nullptr;
2015-06-30 12:46:07 +03:00
}
TutorMessageEvent::~TutorMessageEvent()
2015-08-20 13:35:01 +03:00
{
;
}
2015-06-30 12:46:07 +03:00
2015-08-20 13:35:01 +03:00
bool TutorMessageEvent::IsActive(float time)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return (m_lifetime + m_activationTime >= time);
2015-06-30 12:46:07 +03:00
}
int TutorMessageEvent::GetPriority()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return m_priority;
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
float TutorMessageEvent::GetTimeActive(float time)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return (time - m_activationTime);
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
void TutorMessageEvent::SetActivationTime(float time)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
m_activationTime = time;
2015-06-30 12:46:07 +03:00
}
int TutorMessageEvent::GetID()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return m_messageID;
2015-06-30 12:46:07 +03:00
}
int TutorMessageEvent::GetDuplicateID()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return m_duplicateID;
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
void TutorMessageEvent::SetNext(TutorMessageEvent *next)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
m_next = next;
2015-06-30 12:46:07 +03:00
}
TutorMessageEvent *TutorMessageEvent::GetNext()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return m_next;
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
void TutorMessageEvent::AddParameter(char *str)
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
if (str == nullptr)
2015-08-20 13:35:01 +03:00
return;
TutorMessageEventParam *param = new TutorMessageEventParam;
2017-10-12 17:50:56 +03:00
param->m_next = nullptr;
2015-08-20 13:35:01 +03:00
param->m_data = new char[Q_strlen(str) + 1];
if (param->m_data)
2015-08-20 13:35:01 +03:00
{
Q_strcpy(param->m_data, str);
param->m_data[Q_strlen(str)] = '\0';
2017-10-12 17:50:56 +03:00
m_numParameters++;
2015-08-20 13:35:01 +03:00
if (m_paramList)
2015-08-20 13:35:01 +03:00
{
TutorMessageEventParam *temp = m_paramList;
while (temp->m_next)
temp = temp->m_next;
temp->m_next = param;
}
else
m_paramList = param;
}
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
char *TutorMessageEvent::GetNextParameter(char *buf, int buflen)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
TutorMessageEventParam *param = m_paramList;
2017-10-12 17:50:56 +03:00
if (!param)
{
return nullptr;
}
2015-08-20 13:35:01 +03:00
m_numParameters--;
m_paramList = param->m_next;
Q_strncpy(buf, param->m_data, buflen);
#ifdef REGAMEDLL_FIXES
buf[buflen] = '\0';
#endif
2015-08-20 13:35:01 +03:00
delete param;
return buf;
2015-06-30 12:46:07 +03:00
}
int TutorMessageEvent::GetNumParameters()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
return m_numParameters;
2015-06-30 12:46:07 +03:00
}
CBaseTutor::CBaseTutor()
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
m_eventList = nullptr;
2015-06-30 12:46:07 +03:00
m_deadAirStartTime = 0;
m_roundStartTime = 0;
}
CBaseTutor::~CBaseTutor()
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
TutorMessageEvent *event = m_eventList;
while (event)
2015-08-20 13:35:01 +03:00
{
TutorMessageEvent *temp = event;
event = event->GetNext();
delete temp;
}
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
void CBaseTutor::OnEvent(GameEventType event, CBaseEntity *pEntity, CBaseEntity *pOther)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
CallEventHandler(event, pEntity, pOther);
CheckForStateTransition(event, pEntity, pOther);
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
void CBaseTutor::ShotFired(Vector source, Vector target)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
HandleShotFired(source, target);
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
void CBaseTutor::CheckForStateTransition(GameEventType event, CBaseEntity *pEntity, CBaseEntity *pOther)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (m_stateSystem->UpdateState(event, pEntity, pOther))
2015-08-20 13:35:01 +03:00
{
2015-06-30 12:46:07 +03:00
DisplayNewStateDescriptionToPlayer();
2015-08-20 13:35:01 +03:00
}
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
void CBaseTutor::StartFrame(float time)
2015-06-30 12:46:07 +03:00
{
TutorThink(time);
}
2017-11-22 20:27:55 +03:00
void CBaseTutor::DisplayMessageToPlayer(CBasePlayer *pPlayer, int id, const char *szMessage, TutorMessageEvent *event)
2015-08-20 13:35:01 +03:00
{
TutorMessage *definition;
int numArgs;
char param[512];
numArgs = event->GetNumParameters();
definition = GetTutorMessageDefinition(event->GetID());
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN(MSG_ONE, gmsgTutorText, nullptr, pPlayer->pev);
2015-08-20 13:35:01 +03:00
WRITE_STRING(szMessage);
WRITE_BYTE(numArgs);
2017-10-12 17:50:56 +03:00
for (int arg = 0; arg < numArgs; arg++)
2015-08-20 13:35:01 +03:00
{
char *str = event->GetNextParameter(param, sizeof(param));
if (str)
2015-08-20 13:35:01 +03:00
WRITE_STRING(str);
else
WRITE_STRING("");
}
WRITE_SHORT(id);
2017-11-22 20:27:55 +03:00
WRITE_SHORT(pPlayer->IsAlive() == FALSE);
2015-08-20 13:35:01 +03:00
if (definition)
2015-08-20 13:35:01 +03:00
WRITE_SHORT(definition->m_type);
else
WRITE_SHORT(TUTORMESSAGETYPE_DEFAULT);
MESSAGE_END();
m_deadAirStartTime = -1.0f;
if (definition)
2015-08-20 13:35:01 +03:00
{
if (gpGlobals->time - m_roundStartTime > 1.0f)
{
switch (definition->m_type)
{
case TUTORMESSAGETYPE_FRIEND_DEATH:
2017-11-22 20:27:55 +03:00
EMIT_SOUND_DYN(ENT(pPlayer->pev), CHAN_ITEM, "events/friend_died.wav", VOL_NORM, ATTN_NORM, 0, 120);
2015-08-20 13:35:01 +03:00
break;
case TUTORMESSAGETYPE_ENEMY_DEATH:
2017-11-22 20:27:55 +03:00
EMIT_SOUND_DYN(ENT(pPlayer->pev), CHAN_ITEM, "events/enemy_died.wav", VOL_NORM, ATTN_NORM, 0, 85);
2015-08-20 13:35:01 +03:00
break;
default:
2017-11-22 20:27:55 +03:00
EMIT_SOUND_DYN(ENT(pPlayer->pev), CHAN_ITEM, "events/tutor_msg.wav", VOL_NORM, ATTN_NORM, 0, 100);
2015-08-20 13:35:01 +03:00
break;
}
}
if (definition->m_decay)
{
REGISTER_TUTOR_MESSAGE_SHOWN(id);
}
}
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
NOXREF void CBaseTutor::DrawLineToEntity(CBasePlayer *pPlayer, int entindex, int id)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN(MSG_ONE, gmsgTutorLine, nullptr, pPlayer->pev);
2015-06-30 12:46:07 +03:00
WRITE_SHORT(entindex);
WRITE_SHORT(id);
MESSAGE_END();
}
void CBaseTutor::DisplayNewStateDescriptionToPlayer()
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
if (!pLocalPlayer)
{
2015-06-30 12:46:07 +03:00
return;
2017-10-12 17:50:56 +03:00
}
2015-06-30 12:46:07 +03:00
2017-10-12 17:50:56 +03:00
auto desc = m_stateSystem->GetCurrentStateString();
2015-06-30 12:46:07 +03:00
if (!desc)
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN(MSG_ONE, gmsgTutorState, nullptr, pLocalPlayer->pev);
WRITE_STRING(nullptr);
2015-06-30 12:46:07 +03:00
MESSAGE_END();
}
}
void CBaseTutor::CloseCurrentWindow()
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
if (pLocalPlayer)
2015-06-30 12:46:07 +03:00
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN(MSG_ONE, gmsgTutorClose, nullptr, pLocalPlayer->pev);
2015-06-30 12:46:07 +03:00
MESSAGE_END();
m_deadAirStartTime = gpGlobals->time;
}
}
2017-11-22 20:27:55 +03:00
void CBaseTutor::CalculatePathForObjective(CBaseEntity *pPlayer)
2015-06-30 12:46:07 +03:00
{
2015-08-20 13:35:01 +03:00
;
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
bool CBaseTutor::IsEntityInViewOfPlayer(CBaseEntity *pEntity, CBasePlayer *pPlayer)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (!pEntity || !pPlayer)
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
if (cv_tutor_view_distance.value < (pEntity->pev->origin - pPlayer->pev->origin).Length())
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
if (pPlayer->FInViewCone(pEntity))
2015-08-20 13:35:01 +03:00
{
TraceResult result;
2017-11-22 20:27:55 +03:00
Vector eye = pPlayer->pev->view_ofs + pPlayer->pev->origin;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
UTIL_TraceLine(eye, pEntity->pev->origin, ignore_monsters, ignore_glass, pPlayer->pev->pContainingEntity, &result);
2015-08-20 13:35:01 +03:00
if (result.flFraction == 1.0f)
{
return true;
}
}
return false;
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
bool CBaseTutor::IsPlayerLookingAtPosition(Vector *origin, CBasePlayer *pPlayer)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (!origin || !pPlayer)
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
if (cv_tutor_look_distance.value < (*origin - pPlayer->pev->origin).Length())
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
if (pPlayer->IsLookingAtPosition(origin, cv_tutor_look_angle.value))
2015-08-20 13:35:01 +03:00
{
TraceResult result;
2017-11-22 20:27:55 +03:00
Vector eye = pPlayer->pev->origin + pPlayer->pev->view_ofs;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
UTIL_TraceLine(eye, *origin, ignore_monsters, ignore_glass, ENT(pPlayer->pev), &result);
2015-08-20 13:35:01 +03:00
if (result.flFraction == 1.0f)
return true;
}
return false;
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
bool CBaseTutor::IsPlayerLookingAtEntity(CBaseEntity *pEntity, CBasePlayer *pPlayer)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (!pEntity || !pPlayer)
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
UTIL_MakeVectors(pPlayer->pev->v_angle);
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
Vector srcVec = pPlayer->pev->view_ofs + pPlayer->pev->origin;
2015-08-20 13:35:01 +03:00
Vector destVec = gpGlobals->v_forward * cv_tutor_look_distance.value + srcVec;
TraceResult result;
2017-11-22 20:27:55 +03:00
UTIL_TraceLine(srcVec, destVec, dont_ignore_monsters, ignore_glass, ENT(pPlayer->pev), &result);
2015-08-20 13:35:01 +03:00
if (result.pHit)
2015-08-20 13:35:01 +03:00
{
2017-11-22 20:27:55 +03:00
if (!FNullEnt(result.pHit) && CBaseEntity::Instance(result.pHit) == pEntity)
2015-08-20 13:35:01 +03:00
{
return true;
}
}
return false;
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
bool CBaseTutor::IsBombsiteInViewOfPlayer(CBaseEntity *pEntity, CBasePlayer *pPlayer)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (!pEntity || !pPlayer)
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
Vector bombSiteCenter = pEntity->Center();
if (cv_tutor_view_distance.value < (bombSiteCenter - pPlayer->pev->origin).Length())
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
if (pPlayer->FInViewCone(pEntity))
2015-08-20 13:35:01 +03:00
{
TraceResult result;
2017-11-22 20:27:55 +03:00
Vector eye = pPlayer->pev->origin + pPlayer->pev->view_ofs;
2015-08-20 13:35:01 +03:00
2017-11-22 20:27:55 +03:00
UTIL_TraceLine(eye, bombSiteCenter, ignore_monsters, ignore_glass, ENT(pPlayer->pev), &result);
2015-08-20 13:35:01 +03:00
if (result.flFraction == 1.0f)
{
return true;
}
}
return false;
2015-06-30 12:46:07 +03:00
}
2017-11-22 20:27:55 +03:00
bool CBaseTutor::IsEntityInBombsite(CBaseEntity *bombsite, CBaseEntity *pEntity)
2015-06-30 12:46:07 +03:00
{
2017-11-22 20:27:55 +03:00
if (!bombsite || !pEntity)
2015-08-20 13:35:01 +03:00
return false;
2017-11-22 20:27:55 +03:00
return bombsite->Intersects(pEntity);
2015-06-30 12:46:07 +03:00
}
2015-08-20 13:35:01 +03:00
bool CBaseTutor::DoMessagesHaveSameID(int id1, int id2)
{
if (id1 == id2)
return true;
TutorMessage *message1 = GetTutorMessageDefinition(id1);
TutorMessage *message2 = GetTutorMessageDefinition(id2);
if (!message1 || !message2)
2015-08-20 13:35:01 +03:00
return false;
if (message1->m_duplicateID && message2->m_duplicateID)
return true;
return false;
}