ReGameDLL_CS/regamedll/dlls/tutor_cs_tutor.h
2019-09-23 04:09:58 +07:00

426 lines
14 KiB
C++

/*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#pragma once
#include <map>
enum TutorMessageClass
{
TUTORMESSAGECLASS_NORMAL = 0,
TUTORMESSAGECLASS_EXAMINE,
};
enum TutorMessageType
{
TUTORMESSAGETYPE_DEFAULT = BIT(0), // icon info | color green
TUTORMESSAGETYPE_FRIEND_DEATH = BIT(1), // icon skull | color red
TUTORMESSAGETYPE_ENEMY_DEATH = BIT(2), // icon skull | color blue
TUTORMESSAGETYPE_SCENARIO = BIT(3), // icon info | color yellow
TUTORMESSAGETYPE_BUY = BIT(4), // icon info | color green
TUTORMESSAGETYPE_CAREER = BIT(5), // icon info | color green
TUTORMESSAGETYPE_HINT = BIT(6), // icon info | color green
TUTORMESSAGETYPE_INGAME_HINT = BIT(7), // icon info | color green
TUTORMESSAGETYPE_END_GAME = BIT(8), // icon info | color yellow
TUTORMESSAGETYPE_LAST,
TUTORMESSAGETYPE_ALL = (TUTORMESSAGETYPE_DEFAULT | TUTORMESSAGETYPE_FRIEND_DEATH | TUTORMESSAGETYPE_ENEMY_DEATH | TUTORMESSAGETYPE_SCENARIO | TUTORMESSAGETYPE_BUY | TUTORMESSAGETYPE_CAREER | TUTORMESSAGETYPE_HINT | TUTORMESSAGETYPE_INGAME_HINT | TUTORMESSAGETYPE_END_GAME)
};
enum TutorMessageInterruptFlag
{
TUTORMESSAGEINTERRUPTFLAG_DEFAULT = 0,
TUTORMESSAGEINTERRUPTFLAG_NOW_DAMMIT,
};
enum TutorMessageKeepOldType
{
TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD = 0,
TUTORMESSAGEKEEPOLDTYPE_KEEP_OLD,
TUTORMESSAGEKEEPOLDTYPE_UPDATE_CONTENT,
};
struct TutorMessage
{
char *m_text;
unsigned char m_priority;
unsigned char m_duration;
TutorMessageKeepOldType m_keepOld;
TutorMessageClass m_class;
unsigned char m_decay;
TutorMessageType m_type;
int m_lifetime;
TutorMessageInterruptFlag m_interruptFlag;
int m_duplicateID;
float m_examineStartTime;
int m_timesShown;
float m_minDisplayTimeOverride;
float m_minRepeatInterval;
float m_lastCloseTime;
};
struct TutorMessageEventParam
{
char *m_data;
TutorMessageEventParam *m_next;
};
enum TutorMessageID
{
YOU_FIRED_A_SHOT,
YOU_SHOULD_RELOAD,
YOU_ARE_OUT_OF_AMMO,
YOU_KILLED_A_TEAMMATE,
YOU_KILLED_PLAYER,
YOU_KILLED_PLAYER_ONE_LEFT,
YOU_KILLED_LAST_ENEMY,
YOU_KILLED_PLAYER_HEADSHOT,
YOU_KILLED_PLAYER_HEADSHOT_ONE_LEFT,
YOU_KILLED_LAST_ENEMY_HEADSHOT,
YOU_DIED,
YOU_DIED_HEADSHOT,
YOU_FELL_TO_YOUR_DEATH,
YOU_WERE_JUST_HURT,
YOU_ARE_BLIND_FROM_FLASHBANG,
YOU_ATTACKED_TEAMMATE,
BUY_TIME_BEGIN,
BOMB_PLANTED_T,
BOMB_PLANTED_CT,
TEAMMATE_KILLED,
TEAMMATE_KILLED_ONE_LEFT,
LAST_TEAMMATE_KILLED,
ENEMY_KILLED,
ENEMY_KILLED_ONE_LEFT,
LAST_ENEMY_KILLED,
YOU_SPAWNED,
YOU_SEE_FRIEND,
YOU_SEE_ENEMY,
YOU_SEE_FRIEND_CORPSE,
YOU_SEE_ENEMY_CORPSE,
YOU_SEE_LOOSE_BOMB_T,
YOU_SEE_LOOSE_BOMB_CT,
YOU_SEE_BOMB_CARRIER_T,
YOU_SEE_BOMB_CARRIER_CT,
YOU_SEE_PLANTED_BOMB_T,
YOU_SEE_PLANTED_BOMB_CT,
YOU_ARE_BOMB_CARRIER,
YOU_SEE_LOOSE_WEAPON,
YOU_SEE_LOOSE_DEFUSER,
YOU_SEE_BOMBSITE_T,
YOU_SEE_BOMBSITE_CT,
YOU_SEE_BOMBSITE_T_BOMB,
YOU_SEE_HOSTAGE_T,
YOU_SEE_HOSTAGE_CT,
YOU_SEE_HOSTAGE_CT_EXAMINE,
YOU_USED_HOSTAGE_MORE_LEFT,
YOU_USED_HOSTAGE_NO_MORE_LEFT,
ALL_HOSTAGES_FOLLOWING_T,
ALL_HOSTAGES_FOLLOWING_CT,
HOSTAGE_RESCUED_T,
HOSTAGE_RESCUED_CT,
YOU_RESCUED_HOSTAGE,
YOU_ARE_IN_BOMBSITE_T,
YOU_ARE_IN_BOMBSITE_CT,
YOU_ARE_IN_BOMBSITE_T_BOMB,
ALL_HOSTAGES_RESCUED_T,
ALL_HOSTAGES_RESCUED_CT,
YOU_DAMAGED_HOSTAGE,
YOU_KILLED_HOSTAGE,
ALL_HOSTAGES_DEAD,
YOU_HAVE_BEEN_SHOT_AT,
TIME_RUNNING_OUT_DE_T,
TIME_RUNNING_OUT_DE_CT,
TIME_RUNNING_OUT_CS_T,
TIME_RUNNING_OUT_CS_CT,
DEFUSING_WITHOUT_KIT,
BOMB_DEFUSED_T,
BOMB_DEFUSED_CT,
YOU_DEFUSED_BOMB,
BOMB_EXPLODED_T,
BOMB_EXPLODED_CT,
ROUND_START_DE_T,
ROUND_START_DE_CT,
ROUND_START_CS_T,
ROUND_START_CS_CT,
ROUND_OVER,
ROUND_DRAW,
CT_WIN,
T_WIN,
DEATH_CAMERA_START,
RADIO_COVER_ME,
RADIO_YOU_TAKE_THE_POINT,
RADIO_HOLD_THIS_POSITION,
RADIO_REGROUP_TEAM,
RADIO_FOLLOW_ME,
RADIO_TAKING_FIRE,
RADIO_GO_GO_GO,
RADIO_TEAM_FALL_BACK,
RADIO_STICK_TOGETHER_TEAM,
RADIO_GET_IN_POSITION_AND_WAIT,
RADIO_STORM_THE_FRONT,
RADIO_REPORT_IN_TEAM,
RADIO_AFFIRMATIVE,
RADIO_ENEMY_SPOTTED,
RADIO_NEED_BACKUP,
RADIO_SECTOR_CLEAR,
RADIO_IN_POSITION,
RADIO_REPORTING_IN,
RADIO_GET_OUT_OF_THERE,
RADIO_NEGATIVE,
RADIO_ENEMY_DOWN,
BUY_NEED_PRIMARY,
BUY_NEED_PRIMARY_AMMO,
BUY_NEED_SECONDARY_AMMO,
BUY_NEED_ARMOR,
BUY_NEED_DEFUSE_KIT,
BUY_NEED_GRENADE,
CAREER_TASK_DONE_MORE_LEFT,
CAREER_TASK_DONE_ONE_LEFT,
CAREER_TASK_DONE_ALL_DONE,
HINT_BEGIN,
HINT_1,
HINT_2,
HINT_3,
HINT_4,
HINT_5,
HINT_10,
HINT_11,
HINT_12,
HINT_13,
HINT_14,
HINT_15,
HINT_20,
HINT_21,
HINT_22,
HINT_23,
HINT_24,
HINT_25,
HINT_26,
HINT_30,
HINT_31,
HINT_32,
HINT_33,
HINT_34,
HINT_40,
HINT_50,
HINT_51,
HINT_52,
HINT_53,
HINT_BOMB_START = 139,
HINT_60 = 139,
HINT_61 = 140,
HINT_BOMB_END = 140,
HINT_HOSTAGE_START = 141,
HINT_70 = 141,
HINT_71,
HINT_72,
HINT_73 = 144,
HINT_HOSTAGE_END = 144,
HINT_END,
INGAME_HINT_BEGIN,
INGAME_HINT_1,
INGAME_HINT_2,
INGAME_HINT_END,
TUTOR_NUM_MESSAGES
};
typedef std::map<std::string, TutorMessage *> TutorMessageMap;
typedef TutorMessageMap::iterator TutorMessageMapIter;
struct ClientCorpseStruct
{
Vector m_position;
int m_team;
};
typedef std::vector<ClientCorpseStruct *> ClientCorpseList;
typedef ClientCorpseList::iterator ClientCorpseListIter;
class CCSTutor: public CBaseTutor
{
public:
CCSTutor();
struct PlayerDeathStruct
{
bool m_hasBeenShown;
TutorMessageEvent *m_event;
};
virtual ~CCSTutor();
virtual void TutorThink(float time);
virtual void PurgeMessages();
virtual void CallEventHandler(GameEventType event, CBaseEntity *pEntity, CBaseEntity *pOther);
virtual void ShowTutorMessage(TutorMessageEvent *event);
virtual void HandleShotFired(Vector source, Vector target);
virtual TutorMessage *GetTutorMessageDefinition(int messageID);
void CreateAndAddEventToList(TutorMessageID mid, CBaseEntity *pEntity = nullptr, CBaseEntity *pOther = nullptr);
TutorMessageEvent *CreateTutorMessageEvent(TutorMessageID mid, CBaseEntity *pEntity = nullptr, CBaseEntity *pOther = nullptr);
void AddToEventList(TutorMessageEvent *event);
void DeleteEventFromEventList(TutorMessageEvent *event);
void ClearEventList();
void ClearCurrentEvent(bool closeWindow = true, bool processDeathsForEvent = true);
void DeleteEvent(TutorMessageEvent *event);
bool ShouldShowMessageEvent(TutorMessageEvent *event, float time);
bool ShouldUpdateCurrentMessage(TutorMessageID messageID);
void ComputeDisplayTimesForMessage();
void UpdateCurrentMessage(TutorMessageEvent *event);
void ConstructMessageAndDisplay();
void LookupHotKey(TutorMessageID mid, int paramNum, wchar_t *buf, int buflen);
void CheckForWindowClose(float time);
void CheckForContentUpdate();
bool HasCurrentWindowBeenActiveLongEnough(float time);
void CheckForInterruptingMessageEvent(float time);
void CheckForInactiveEvents(float time);
void CancelEvent(TutorMessageID mid);
void ProcessShownDeathsForEvent(TutorMessageEvent *event);
void TransferDeathEvents(TutorMessageEvent *oldEvent, TutorMessageEvent *newEvent);
TutorMessageEvent *GetTutorMessageUpdateEvent();
bool GetDuplicateMessagesFromEventList(TutorMessageEvent *&event1, TutorMessageEvent *&event2);
bool IsBombMap();
bool IsHostageMap();
public:
void HandleWeaponFired(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleWeaponFiredOnEmpty(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleWeaponReloaded(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandlePlayerDied(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandlePlayerSpawned(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleClientCorpseSpawned(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandlePlayerTookDamage(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandlePlayerBlindedByFlashbang(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBuyTimeStart(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandlePlayerLeftBuyZone(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBombPlanted(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRoundStart(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBombDefused(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBombExploded(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleHostageUsed(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleHostageRescued(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleHostageDamaged(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleHostageKilled(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleAllHostagesRescued(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBeingShotAt(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRoundDraw(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleCTWin(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleTWin(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleDeathCameraStart(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBombDefusing(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioCoverMe(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioYouTakeThePoint(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioHoldThisPosition(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioRegroupTeam(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioFollowMe(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioTakingFire(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioGoGoGo(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioTeamFallBack(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioStickTogetherTeam(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioGetInPositionAndWait(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioStormTheFront(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioReportInTeam(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioAffirmative(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioEnemySpotted(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioNeedBackup(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioSectorClear(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioInPosition(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioReportingIn(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioGetOutOfThere(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioNegative(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleRadioEnemyDown(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleBuyMenuOpenned(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleAutoBuy(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNotBuyingAnything(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuyPrimaryWeapon(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuyPrimaryAmmo(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuySecondaryAmmo(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuyArmor(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuyDefuseKit(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleNeedToBuyGrenade(CBaseEntity *pEntity, CBaseEntity *pOther);
void HandleCareerTaskDone(CBaseEntity *pEntity, CBaseEntity *pOther);
void GetNumPlayersAliveOnTeams(int &numT, int &numCT);
void CheckForBombViewable();
void CheckForLooseWeaponViewable();
void CheckForLooseDefuserViewable();
void CheckForBombsiteViewable();
TutorMessageID CheckForInBombZone();
void CheckForHostageViewable();
void CheckForTimeRunningOut();
void CheckForAllHostagesDead();
bool CheckForAllHostagesFollowingSomeone();
void CheckHintMessages(float time);
void CheckInGameHintMessages(float time);
void CheckExamineMessages(float time);
void CheckForNeedToReload(bool isPassiveCheck = false);
bool CanLocalPlayerBuyStuff();
void CheckBuyZoneMessages();
bool IsBombPlantedInBombsite(CBaseEntity *bombTarget);
bool IsBombPlantedInBombZone(const char *pszBombZone);
void ReadTutorMessageFile();
void ApplyPersistentDecay();
CBaseEntity *GetEntityForMessageID(int messageID, CBaseEntity *last = nullptr);
void ResetPlayerDeathInfo();
void ConstructRecentDeathsList(TeamName team, char *buf, int buflen, TutorMessageEvent *event);
private:
static const char *m_TutorIdentifierList[];
float m_nextViewableCheckTime;
TutorMessageMap m_messageMap;
TutorMessageID m_currentlyShownMessageID;
float m_currentlyShownMessageCloseTime;
float m_currentlyShownMessageStartTime;
float m_currentlyShownMessageMinimumCloseTime;
TutorMessageEvent *m_currentMessageEvent;
TutorMessageEvent *m_lastScenarioEvent;
TutorMessageID m_lastHintShown;
TutorMessageID m_lastInGameHintShown;
ClientCorpseList m_clientCorpseList;
int m_messageTypeMask;
bool m_haveSpawned;
PlayerDeathStruct m_playerDeathInfo[MAX_CLIENTS];
};
void ParseMessageParameters(char *&messageData, TutorMessage *ret);
TutorMessage *ConstructTutorMessage(char *&messageData, TutorMessage *defaults);
void ReadDefaultValues(char *&messageData, TutorMessage *defaults);
// custom operator++
inline TutorMessageID operator++(TutorMessageID &iter, int)
{
// bounds checking
if (iter == TUTOR_NUM_MESSAGES)
{
return YOU_FIRED_A_SHOT;
}
iter = static_cast<TutorMessageID>(static_cast<int>(iter) + 1);
return iter;
}