Ai
1 Star 0 Fork 0

yoyojacky/CSMoE

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
tutor_cs_tutor.cpp 69.37 KB
一键复制 编辑 原始数据 按行查看 历史
萌殇小白白๑ 提交于 2019-09-30 17:51 +08:00 . pch support
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "saverestore.h"
#include "globals.h"
#include "game.h"
#include "bot_include.h"
namespace sv {
/*
* Globals initialization
*/
const char *TutorIdentifierList[] =
{
"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_60",
"HINT_61",
"HINT_70",
"HINT_71",
"HINT_72",
"HINT_73",
"HINT_END",
"INGAME_HINT_BEGIN",
"INGAME_HINT_1",
"INGAME_HINT_2",
"INGAME_HINT_3"
};
CCSTutor::CCSTutor()
{
m_stateSystem = new CCSTutorStateSystem;
m_nextViewableCheckTime = invalid_time_point;
m_currentlyShownMessageID = TUTOR_NUM_MESSAGES;
m_currentMessageEvent = NULL;
m_messageTypeMask = TUTORMESSAGETYPE_ALL;
m_lastScenarioEvent = NULL;
m_haveSpawned = false;
m_lastHintShown = HINT_BEGIN;
m_lastInGameHintShown = INGAME_HINT_BEGIN;
ReadTutorMessageFile();
ApplyPersistentDecay();
ResetPlayerDeathInfo();
}
CCSTutor::~CCSTutor()
{
std::for_each(m_messageMap.begin(), m_messageMap.end(),
std::bind(std::default_delete<TutorMessage>(),
std::bind(std::mem_fn(&decltype(m_messageMap)::value_type::second), std::placeholders::_1)
)
);
m_messageMap.clear();
if (m_stateSystem != NULL)
{
delete m_stateSystem;
}
if (m_currentMessageEvent != NULL)
{
DeleteEvent(m_currentMessageEvent);
m_currentMessageEvent = NULL;
}
if (m_lastScenarioEvent != NULL)
{
DeleteEvent(m_lastScenarioEvent);
m_lastScenarioEvent = NULL;
}
ClearCurrentEvent();
ClearEventList();
}
void ParseMessageParameters(char *&messageData, TutorMessage *ret)
{
char *token;
while (true)
{
messageData = MP_COM_Parse((char *)messageData);
token = MP_COM_GetToken();
if (!messageData || !Q_stricmp(token, "End"))
{
break;
}
if (!Q_stricmp(token, "String"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_text = Q_strdup(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "Duration"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_duration = Q_atoi(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "Priority"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_priority = Q_atoi(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "KeepOld"))
{
messageData = MP_COM_Parse((char *)messageData);
token = MP_COM_GetToken();
if (!Q_stricmp(token, "true"))
{
ret->m_keepOld = TUTORMESSAGEKEEPOLDTYPE_KEEP_OLD;
}
else if (!Q_stricmp(token, "updatecontent"))
{
ret->m_keepOld = TUTORMESSAGEKEEPOLDTYPE_UPDATE_CONTENT;
}
else
{
ret->m_keepOld = TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD;
}
}
else if (!Q_stricmp(token, "Class"))
{
messageData = MP_COM_Parse((char *)messageData);
if (!Q_stricmp(MP_COM_GetToken(), "Examine"))
{
ret->m_class = TUTORMESSAGECLASS_EXAMINE;
}
else
{
ret->m_class = TUTORMESSAGECLASS_NORMAL;
}
}
else if (!Q_stricmp(token, "Decay"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_decay = Q_atoi(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "Type"))
{
messageData = MP_COM_Parse((char *)messageData);
token = MP_COM_GetToken();
if (!Q_stricmp(token, "FriendDeath"))
{
ret->m_type = TUTORMESSAGETYPE_FRIEND_DEATH;
}
else if (!Q_stricmp(token, "EnemyDeath"))
{
ret->m_type = TUTORMESSAGETYPE_ENEMY_DEATH;
}
else if (!Q_stricmp(token, "Scenario"))
{
ret->m_type = TUTORMESSAGETYPE_SCENARIO;
}
else if (!Q_stricmp(token, "Buy"))
{
ret->m_type = TUTORMESSAGETYPE_BUY;
}
else if (!Q_stricmp(token, "Career"))
{
ret->m_type = TUTORMESSAGETYPE_CAREER;
}
else if (!Q_stricmp(token, "Hint"))
{
ret->m_type = TUTORMESSAGETYPE_HINT;
}
else if (!Q_stricmp(token, "InGameHint"))
{
ret->m_type = TUTORMESSAGETYPE_INGAME_HINT;
}
else if (!Q_stricmp(token, "EndGame"))
{
ret->m_type = TUTORMESSAGETYPE_END_GAME;
}
else
{
ret->m_type = TUTORMESSAGETYPE_DEFAULT;
}
}
else if (!Q_stricmp(token, "Lifetime"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_lifetime = Q_atoi(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "DuplicateID"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_duplicateID = Q_atoi(MP_COM_GetToken());
}
else if (!Q_stricmp(token, "Interrupt"))
{
messageData = MP_COM_Parse((char *)messageData);
if (!Q_stricmp(MP_COM_GetToken(), "Now"))
{
ret->m_interruptFlag = TUTORMESSAGEINTERRUPTFLAG_NOW_DAMMIT;
}
else
{
ret->m_interruptFlag = TUTORMESSAGEINTERRUPTFLAG_DEFAULT;
}
}
else if (!Q_stricmp(token, "MinDisplayTimeOverride"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_minDisplayTimeOverride = Q_atof(MP_COM_GetToken()) * 1s;
}
else if (!Q_stricmp(token, "MinRepeatInterval"))
{
messageData = MP_COM_Parse((char *)messageData);
ret->m_minRepeatInterval = Q_atof(MP_COM_GetToken()) * 1s;
}
}
}
TutorMessage *ConstructTutorMessage(char *&messageData, TutorMessage *defaults)
{
TutorMessage *ret = new TutorMessage;
ret->m_text = NULL;
ret->m_duplicateID = defaults->m_duplicateID;
ret->m_keepOld = defaults->m_keepOld;
ret->m_duration = defaults->m_duration;
ret->m_priority = defaults->m_priority;
ret->m_class = defaults->m_class;
ret->m_type = defaults->m_type;
ret->m_decay = defaults->m_decay;
ret->m_lifetime = defaults->m_lifetime;
ret->m_interruptFlag = defaults->m_interruptFlag;
ret->m_minDisplayTimeOverride = defaults->m_minDisplayTimeOverride;
ret->m_minRepeatInterval = defaults->m_minRepeatInterval;
ret->m_examineStartTime = invalid_time_point;
ret->m_timesShown = 0;
ret->m_lastCloseTime = invalid_time_point;
ParseMessageParameters(messageData, ret);
return ret;
}
void ReadDefaultValues(char *&messageData, TutorMessage *defaults)
{
ParseMessageParameters(messageData, defaults);
}
void CCSTutor::ReadTutorMessageFile()
{
int messageFileLen = 0;
char *messageFile;
char *messageData;
TutorMessage defaultMessage;
messageFile = messageData = (char *)LOAD_FILE_FOR_ME("tutordata.txt", &messageFileLen);
if (!messageFile)
{
if (g_bIsCzeroGame)
{
CONSOLE_ECHO("Warning: Cannot access tutor message file tutordata.txt\n");
}
return;
}
defaultMessage.m_duplicateID = 0;
defaultMessage.m_keepOld = TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD;
defaultMessage.m_duration = 1;
defaultMessage.m_priority = 0;
defaultMessage.m_class = TUTORMESSAGECLASS_NORMAL;
defaultMessage.m_type = TUTORMESSAGETYPE_DEFAULT;
defaultMessage.m_decay = 10;
defaultMessage.m_lifetime = 10;
defaultMessage.m_interruptFlag = TUTORMESSAGEINTERRUPTFLAG_DEFAULT;
defaultMessage.m_minDisplayTimeOverride = zero_duration;
defaultMessage.m_minRepeatInterval = zero_duration;
while (true)
{
messageData = MP_COM_Parse(messageData);
if (!messageData)
{
break;
}
char *token = MP_COM_GetToken();
if (!Q_stricmp(token, "TutorMessage"))
{
messageData = MP_COM_Parse(messageData);
token = MP_COM_GetToken();
TutorMessage *tm = ConstructTutorMessage(messageData, &defaultMessage);
m_messageMap.emplace(token, tm);
}
else if (!Q_stricmp(token, "Defaults"))
{
ReadDefaultValues(messageData, &defaultMessage);
}
}
FREE_FILE(messageFile);
}
void CCSTutor::ApplyPersistentDecay()
{
for (TutorMessageID mid = YOU_FIRED_A_SHOT; mid < TUTOR_NUM_MESSAGES; mid++)
{
TutorMessage *definition = GetTutorMessageDefinition(mid);
if (definition != NULL)
{
int timesShown = GET_TIMES_TUTOR_MESSAGE_SHOWN(mid);
if (timesShown != -1)
{
definition->m_timesShown = timesShown;
}
}
}
}
bool CCSTutor::HasCurrentWindowBeenActiveLongEnough(time_point_t time)
{
return (m_currentlyShownMessageID < 0 || m_currentlyShownMessageID >= TUTOR_NUM_MESSAGES || time > m_currentlyShownMessageMinimumCloseTime);
}
bool CCSTutor::ShouldShowMessageEvent(TutorMessageEvent *event, time_point_t time)
{
if (event == NULL)
{
return false;
}
TutorMessage *message = GetTutorMessageDefinition(event->GetID());
if (message == NULL)
{
return false;
}
if (message->m_class == TUTORMESSAGECLASS_NORMAL)
{
if (message->m_decay)
{
if (message->m_timesShown >= message->m_decay)
return false;
}
}
if (!(m_messageTypeMask & message->m_type) || (time - message->m_lastCloseTime < message->m_minRepeatInterval))
{
return false;
}
if (HasCurrentWindowBeenActiveLongEnough(time))
{
return true;
}
if (message->m_interruptFlag != TUTORMESSAGEINTERRUPTFLAG_NOW_DAMMIT)
{
return false;
}
TutorMessage *current = GetTutorMessageDefinition(m_currentlyShownMessageID);
if (current == NULL || (DoMessagesHaveSameID(event->GetID(), m_currentlyShownMessageID) && current->m_keepOld != TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD))
{
return false;
}
if (message->m_priority > current->m_priority
|| message->m_priority == current->m_priority
|| m_currentMessageEvent->GetTimeActive(time) < event->GetTimeActive(time))
{
return true;
}
return false;
}
void CCSTutor::CheckForInterruptingMessageEvent(time_point_t time)
{
bool newEvent = false;
TutorMessageEvent *event = m_eventList;
TutorMessage *oldMessage = GetTutorMessageDefinition(m_currentlyShownMessageID);
TutorMessageEvent *oldEvent = m_currentMessageEvent;
if (event == NULL)
{
return;
}
while (event != NULL)
{
if (ShouldShowMessageEvent(event, time))
{
newEvent = true;
ShowTutorMessage(event);
}
event = event->GetNext();
}
if (!newEvent)
{
return;
}
if (oldEvent != NULL)
{
ProcessShownDeathsForEvent(event);
DeleteEvent(oldEvent);
}
CloseCurrentWindow();
if (oldMessage != NULL)
{
oldMessage->m_lastCloseTime = time;
}
DeleteEventFromEventList(m_currentMessageEvent);
ConstructMessageAndDisplay();
}
void CCSTutor::TutorThink(time_point_t time)
{
if (m_nextViewableCheckTime <= time)
{
CheckForBombViewable();
CheckForLooseWeaponViewable();
CheckForLooseDefuserViewable();
CheckForTimeRunningOut();
CheckForBombsiteViewable();
CheckForHostageViewable();
CheckExamineMessages(time);
CheckHintMessages(time);
CheckInGameHintMessages(time);
CheckForNeedToReload(true);
if (m_haveSpawned && CanLocalPlayerBuyStuff())
{
m_messageTypeMask = TUTORMESSAGETYPE_BUY;
CreateAndAddEventToList(BUY_TIME_BEGIN);
m_haveSpawned = false;
}
if (CanLocalPlayerBuyStuff() && m_messageTypeMask == TUTORMESSAGETYPE_BUY)
{
CheckBuyZoneMessages();
}
else
{
if (!CanLocalPlayerBuyStuff() && m_messageTypeMask == TUTORMESSAGETYPE_BUY)
{
OnEvent(EVENT_PLAYER_LEFT_BUY_ZONE);
}
}
m_nextViewableCheckTime = cv_tutor_viewable_check_interval.value * 1s + time;
}
CheckForInactiveEvents(time);
CheckForWindowClose(time);
CheckForContentUpdate();
CheckForInterruptingMessageEvent(time);
}
void CCSTutor::CheckForWindowClose(time_point_t time)
{
if (m_currentlyShownMessageID < 0 || m_currentlyShownMessageID >= 150 || time <= m_currentlyShownMessageCloseTime)
{
return;
}
TutorMessageEvent *event = GetTutorMessageUpdateEvent();
if (event == NULL)
{
ClearCurrentEvent();
return;
}
UpdateCurrentMessage(event);
DeleteEventFromEventList(event);
}
void CCSTutor::CheckForContentUpdate()
{
if (m_currentlyShownMessageID < 0 || m_currentlyShownMessageID >= 150)
{
return;
}
TutorMessage *definition = GetTutorMessageDefinition(m_currentlyShownMessageID);
if (definition == NULL || definition->m_keepOld != TUTORMESSAGEKEEPOLDTYPE_UPDATE_CONTENT)
{
return;
}
TutorMessageEvent *event = GetTutorMessageUpdateEvent();
if (event != NULL)
{
UpdateCurrentMessage(event);
DeleteEventFromEventList(event);
}
}
void CCSTutor::ClearCurrentEvent(bool closeWindow, bool processDeathsForEvent)
{
TutorMessage *oldMessage = GetTutorMessageDefinition(m_currentlyShownMessageID);
if (oldMessage != NULL)
{
oldMessage->m_lastCloseTime = gpGlobals->time;
}
if (processDeathsForEvent)
{
ProcessShownDeathsForEvent(m_currentMessageEvent);
}
if (closeWindow)
{
CloseCurrentWindow();
}
m_currentlyShownMessageID = TUTOR_NUM_MESSAGES;
m_currentlyShownMessageCloseTime = invalid_time_point;
m_currentlyShownMessageMinimumCloseTime = invalid_time_point;
if (m_currentMessageEvent != NULL)
{
DeleteEvent(m_currentMessageEvent);
m_currentMessageEvent = NULL;
}
}
void CCSTutor::ProcessShownDeathsForEvent(TutorMessageEvent *event)
{
if (event == NULL)
{
return;
}
for (size_t i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
{
if (m_playerDeathInfo[i].m_event == event)
{
m_playerDeathInfo[i].m_hasBeenShown = true;
m_playerDeathInfo[i].m_event = NULL;
}
}
}
TutorMessageEvent *CCSTutor::GetTutorMessageUpdateEvent()
{
TutorMessage *definition = GetTutorMessageDefinition(m_currentlyShownMessageID);
if (definition == NULL || definition->m_keepOld == TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD)
{
return NULL;
}
for (TutorMessageEvent *event = m_eventList; event != NULL; event = event->GetNext())
{
if (DoMessagesHaveSameID(event->GetID(), m_currentlyShownMessageID))
{
return event;
}
}
return NULL;
}
bool CCSTutor::GetDuplicateMessagesFromEventList(TutorMessageEvent *&event1, TutorMessageEvent *&event2)
{
for (event1 = m_eventList; event1 != NULL; event1 = event1->GetNext())
{
for (event2 = event1->GetNext(); event2 != NULL; event2 = event2->GetNext())
{
if (DoMessagesHaveSameID(event1->GetID(), event2->GetID()))
{
return true;
}
}
}
return false;
}
void CCSTutor::CheckForInactiveEvents(time_point_t time)
{
TutorMessageEvent *event = m_eventList;
while (event != NULL)
{
if (!event->IsActive(time))
{
TutorMessageEvent *temp = event->GetNext();
DeleteEventFromEventList(event);
DeleteEvent(event);
event = temp;
}
else
event = event->GetNext();
}
TutorMessageEvent *event1 = NULL;
TutorMessageEvent *event2 = NULL;
bool foundDup = GetDuplicateMessagesFromEventList(event1, event2);
if (foundDup)
{
if (event1->GetTimeActive(time) < event2->GetTimeActive(time))
{
TransferDeathEvents(event2, event1);
DeleteEventFromEventList(event2);
DeleteEvent(event2);
}
else
{
TransferDeathEvents(event1, event2);
DeleteEventFromEventList(event1);
DeleteEvent(event1);
}
}
}
void CCSTutor::CancelEvent(TutorMessageID mid)
{
if (m_currentlyShownMessageID == mid)
{
ClearCurrentEvent();
}
TutorMessageEvent *event = m_eventList;
while (event != NULL)
{
TutorMessageEvent *temp = event->GetNext();
if (event->GetID() == mid)
{
DeleteEventFromEventList(event);
DeleteEvent(event);
}
event = temp;
}
if (m_lastScenarioEvent != NULL && m_lastScenarioEvent->GetID() == mid)
{
DeleteEvent(m_lastScenarioEvent);
m_lastScenarioEvent = NULL;
}
}
NOXREF void CCSTutor::LookupHotKey(TutorMessageID mid, int paramNum, wchar_t *buf, int buflen)
{
#ifdef _WIN32
_snwprintf(buf, buflen - 1, L"KEY%d", paramNum);
#endif // _WIN32
}
TutorMessageEvent *CCSTutor::CreateTutorMessageEvent(TutorMessageID mid, CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer;
TutorMessage *message;
TutorMessageEvent *event;
char enemyList[2048];
char teammateList[2048];
localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
{
return NULL;
}
message = GetTutorMessageDefinition(mid);
if (message == NULL)
{
return NULL;
}
event = new TutorMessageEvent
(
mid,
message->m_duplicateID,
gpGlobals->time,
std::chrono::seconds (message->m_lifetime),
message->m_priority
);
if (event != NULL)
{
switch (mid)
{
case YOU_KILLED_PLAYER_ONE_LEFT:
case YOU_KILLED_LAST_ENEMY:
case YOU_KILLED_PLAYER_HEADSHOT_ONE_LEFT:
case YOU_KILLED_LAST_ENEMY_HEADSHOT:
case ENEMY_KILLED_ONE_LEFT:
case LAST_ENEMY_KILLED:
{
switch (localPlayer->m_iTeam)
{
case CT:
ConstructRecentDeathsList(TERRORIST, enemyList, sizeof(enemyList), event);
event->AddParameter(enemyList);
break;
case TERRORIST:
ConstructRecentDeathsList(CT, teammateList, sizeof(teammateList), event);
event->AddParameter(teammateList);
break;
default:
break;
}
break;
}
case YOU_KILLED_PLAYER:
case YOU_KILLED_PLAYER_HEADSHOT:
case ENEMY_KILLED:
{
int numT;
int numCT;
char numTStr[16];
char numCTStr[16];
GetNumPlayersAliveOnTeams(numT, numCT);
Q_snprintf(numTStr, sizeof(numTStr), "%i", numT);
Q_snprintf(numCTStr, sizeof(numCTStr), "%i", numCT);
switch (localPlayer->m_iTeam)
{
case CT:
event->AddParameter(numCTStr);
ConstructRecentDeathsList(TERRORIST, enemyList, sizeof(enemyList), event);
event->AddParameter(enemyList);
break;
case TERRORIST:
event->AddParameter(numTStr);
ConstructRecentDeathsList(CT, teammateList, sizeof(teammateList), event);
event->AddParameter(teammateList);
break;
default:
break;
}
break;
}
case CAREER_TASK_DONE_MORE_LEFT:
{
char numLeftStr[16];
int numtasks = 0;
if (TheCareerTasks != NULL)
{
numtasks = TheCareerTasks->GetNumRemainingTasks();
}
Q_sprintf(numLeftStr, "%d", numtasks);
event->AddParameter(numLeftStr);
break;
}
case YOU_KILLED_A_TEAMMATE:
case TEAMMATE_KILLED_ONE_LEFT:
case LAST_TEAMMATE_KILLED:
ConstructRecentDeathsList(localPlayer->m_iTeam, enemyList, sizeof(enemyList), event);
event->AddParameter(enemyList);
break;
case TEAMMATE_KILLED:
{
int numT;
int numCT;
char numTStr[16];
char numCTStr[16];
GetNumPlayersAliveOnTeams(numT, numCT);
if (localPlayer->IsAlive())
{
switch (localPlayer->m_iTeam)
{
case CT:
numCT--;
break;
case TERRORIST:
numT--;
break;
default:
break;
}
}
Q_snprintf(numTStr, sizeof(numTStr), "%i", numT);
Q_snprintf(numCTStr, sizeof(numCTStr), "%i", numCT);
switch (localPlayer->m_iTeam)
{
case CT:
event->AddParameter(numCTStr);
break;
case TERRORIST:
event->AddParameter(numTStr);
break;
default:
break;
}
ConstructRecentDeathsList(localPlayer->m_iTeam, teammateList, sizeof(teammateList), event);
event->AddParameter(teammateList);
break;
}
default:
break;
}
}
return event;
}
void CCSTutor::AddToEventList(TutorMessageEvent *event)
{
if (event != NULL)
{
event->SetNext(m_eventList);
m_eventList = event;
}
}
void CCSTutor::CreateAndAddEventToList(TutorMessageID mid, CBaseEntity *entity, CBaseEntity *other)
{
TutorMessageEvent *event;
TutorMessage *message;
event = CreateTutorMessageEvent(mid, entity, other);
if (event != NULL)
{
message = GetTutorMessageDefinition(mid);
if (message != NULL && message->m_type == TUTORMESSAGETYPE_SCENARIO)
{
if (m_lastScenarioEvent != NULL)
{
DeleteEvent(m_lastScenarioEvent);
m_lastScenarioEvent = NULL;
}
m_lastScenarioEvent = CreateTutorMessageEvent(mid, entity, other);
}
AddToEventList(event);
}
}
void CCSTutor::DeleteEventFromEventList(TutorMessageEvent *event)
{
if (event == NULL)
{
return;
}
TutorMessageEvent *temp = m_eventList;
if (temp != event)
{
if (temp != NULL)
{
while (event != temp->GetNext())
{
temp = temp->GetNext();
if (temp == NULL)
{
return;
}
}
if (temp != NULL && temp->GetNext() == event)
{
temp->SetNext(temp->GetNext()->GetNext());
}
}
}
else
m_eventList = m_eventList->GetNext();
}
void CCSTutor::ClearEventList()
{
while (m_eventList != NULL)
{
TutorMessageEvent *temp = m_eventList;
m_eventList = m_eventList->GetNext();
DeleteEvent(temp);
}
}
void CCSTutor::DeleteEvent(TutorMessageEvent *event)
{
for (size_t i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
{
if (m_playerDeathInfo[i].m_event == event)
{
m_playerDeathInfo[i].m_event = NULL;
}
}
if (event != NULL)
{
delete event;
}
}
void CCSTutor::PurgeMessages()
{
ClearCurrentEvent();
ClearEventList();
if (m_lastScenarioEvent != NULL)
{
DeleteEvent(m_lastScenarioEvent);
m_lastScenarioEvent = NULL;
}
}
// TODO(MoeMod): time fix here?
void CCSTutor::ComputeDisplayTimesForMessage()
{
TutorMessage *message = GetTutorMessageDefinition(m_currentlyShownMessageID);
if (!message)
{
m_currentlyShownMessageCloseTime = gpGlobals->time;
return;
}
m_currentlyShownMessageCloseTime = message->m_duration * 1s + gpGlobals->time;
duration_t minCloseTime = cv_tutor_message_minimum_display_time.value * 1s;
int stringLength = GET_LOCALIZED_STRING_LENGTH(message->m_text);
duration_t minShowTime = stringLength * cv_tutor_message_character_display_time_coefficient.value * 1s;
if (minShowTime > minCloseTime)
{
minCloseTime = minShowTime;
}
if (message->m_minDisplayTimeOverride <= minCloseTime)
{
message->m_minDisplayTimeOverride = minCloseTime;
}
m_currentlyShownMessageMinimumCloseTime = message->m_minDisplayTimeOverride + gpGlobals->time;
if (m_currentlyShownMessageMinimumCloseTime > m_currentlyShownMessageCloseTime)
{
m_currentlyShownMessageCloseTime = m_currentlyShownMessageMinimumCloseTime;
}
}
NOXREF bool CCSTutor::ShouldUpdateCurrentMessage(TutorMessageID messageID)
{
if (DoMessagesHaveSameID(messageID, m_currentlyShownMessageID))
{
TutorMessage *definition = GetTutorMessageDefinition(messageID);
if (definition != NULL && definition->m_keepOld != TUTORMESSAGEKEEPOLDTYPE_DONT_KEEP_OLD)
{
return true;
}
}
return false;
}
void CCSTutor::UpdateCurrentMessage(TutorMessageEvent *event)
{
TransferDeathEvents(m_currentMessageEvent, event);
if (m_currentMessageEvent != NULL)
{
DeleteEvent(m_currentMessageEvent);
m_currentMessageEvent = NULL;
}
m_currentlyShownMessageID = (TutorMessageID)event->GetID();
m_currentMessageEvent = event;
TutorMessage *definition = GetTutorMessageDefinition(event->GetID());
if (definition != NULL)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
m_currentlyShownMessageCloseTime = definition->m_duration * 1s + gpGlobals->time;
if (definition->m_keepOld == TUTORMESSAGEKEEPOLDTYPE_UPDATE_CONTENT)
{
CloseCurrentWindow();
DisplayMessageToPlayer(localPlayer, event->GetID(), definition->m_text, event);
}
}
}
}
void CCSTutor::ShowTutorMessage(TutorMessageEvent *event)
{
TutorMessageID mid = static_cast<TutorMessageID>(event->GetID());
if (mid < 0 || mid >= TUTOR_NUM_MESSAGES)
{
return;
}
TutorMessage *message = GetTutorMessageDefinition(mid);
if (message != NULL)
{
m_currentlyShownMessageID = mid;
m_currentMessageEvent = event;
m_currentlyShownMessageCloseTime = invalid_time_point;
m_currentlyShownMessageMinimumCloseTime = invalid_time_point;
}
}
void CCSTutor::ConstructMessageAndDisplay()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL && !localPlayer->IsBot())
{
TutorMessageID mid = static_cast<TutorMessageID>(m_currentMessageEvent->GetID());
if (mid < 0 || mid >= TUTOR_NUM_MESSAGES)
{
return;
}
TutorMessage *message = GetTutorMessageDefinition(mid);
if (message != NULL)
{
message->m_timesShown++;
ComputeDisplayTimesForMessage();
DisplayMessageToPlayer(localPlayer, mid, message->m_text, m_currentMessageEvent);
}
}
}
void CCSTutor::CallEventHandler(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
{
switch (event)
{
case EVENT_WEAPON_FIRED:
HandleWeaponFired(entity, other);
break;
case EVENT_WEAPON_FIRED_ON_EMPTY:
HandleWeaponFiredOnEmpty(entity, other);
break;
case EVENT_WEAPON_RELOADED:
HandleWeaponReloaded(entity, other);
break;
case EVENT_BEING_SHOT_AT:
HandleBeingShotAt(entity, other);
break;
case EVENT_PLAYER_BLINDED_BY_FLASHBANG:
HandlePlayerBlindedByFlashbang(entity, other);
break;
case EVENT_PLAYER_DIED:
HandlePlayerDied(entity, other);
break;
case EVENT_PLAYER_TOOK_DAMAGE:
HandlePlayerTookDamage(entity, other);
break;
case EVENT_HOSTAGE_DAMAGED:
HandleHostageDamaged(entity, other);
break;
case EVENT_HOSTAGE_KILLED:
HandleHostageKilled(entity, other);
break;
case EVENT_BOMB_PLANTED:
HandleBombPlanted(entity, other);
break;
case EVENT_BOMB_DEFUSING:
HandleBombDefusing(entity, other);
break;
case EVENT_BOMB_DEFUSED:
HandleBombDefused(entity, other);
break;
case EVENT_BOMB_EXPLODED:
HandleBombExploded(entity, other);
break;
case EVENT_HOSTAGE_USED:
HandleHostageUsed(entity, other);
break;
case EVENT_HOSTAGE_RESCUED:
HandleHostageRescued(entity, other);
break;
case EVENT_ALL_HOSTAGES_RESCUED:
HandleAllHostagesRescued(entity, other);
break;
case EVENT_TERRORISTS_WIN:
HandleTWin(entity, other);
break;
case EVENT_CTS_WIN:
HandleCTWin(entity, other);
break;
case EVENT_ROUND_DRAW:
HandleRoundDraw(entity, other);
break;
case EVENT_ROUND_START:
HandleRoundStart(entity, other);
break;
case EVENT_PLAYER_SPAWNED:
HandlePlayerSpawned(entity, other);
break;
case EVENT_PLAYER_LEFT_BUY_ZONE:
HandlePlayerLeftBuyZone(entity, other);
break;
case EVENT_DEATH_CAMERA_START:
HandleDeathCameraStart(entity, other);
break;
case EVENT_TUTOR_BUY_MENU_OPENNED:
HandleBuyMenuOpenned(entity, other);
break;
case EVENT_TUTOR_AUTOBUY:
HandleAutoBuy(entity, other);
break;
case EVENT_TUTOR_NOT_BUYING_ANYTHING:
HandleNotBuyingAnything(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_PRIMARY_WEAPON:
HandleNeedToBuyPrimaryWeapon(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_PRIMARY_AMMO:
HandleNeedToBuyPrimaryAmmo(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_SECONDARY_AMMO:
HandleNeedToBuySecondaryAmmo(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_ARMOR:
HandleNeedToBuyArmor(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_DEFUSE_KIT:
HandleNeedToBuyDefuseKit(entity, other);
break;
case EVENT_TUTOR_NEED_TO_BUY_GRENADE:
HandleNeedToBuyGrenade(entity, other);
break;
case EVENT_CAREER_TASK_DONE:
HandleCareerTaskDone(entity, other);
break;
case EVENT_RADIO_COVER_ME:
HandleRadioCoverMe(entity, other);
break;
case EVENT_RADIO_YOU_TAKE_THE_POINT:
HandleRadioYouTakeThePoint(entity, other);
break;
case EVENT_RADIO_HOLD_THIS_POSITION:
HandleRadioHoldThisPosition(entity, other);
break;
case EVENT_RADIO_REGROUP_TEAM:
HandleRadioRegroupTeam(entity, other);
break;
case EVENT_RADIO_FOLLOW_ME:
HandleRadioFollowMe(entity, other);
break;
case EVENT_RADIO_TAKING_FIRE:
HandleRadioTakingFire(entity, other);
break;
case EVENT_RADIO_GO_GO_GO:
HandleRadioGoGoGo(entity, other);
break;
case EVENT_RADIO_TEAM_FALL_BACK:
HandleRadioTeamFallBack(entity, other);
break;
case EVENT_RADIO_STICK_TOGETHER_TEAM:
HandleRadioStickTogetherTeam(entity, other);
break;
case EVENT_RADIO_GET_IN_POSITION_AND_WAIT:
HandleRadioGetInPositionAndWait(entity, other);
break;
case EVENT_RADIO_STORM_THE_FRONT:
HandleRadioStormTheFront(entity, other);
break;
case EVENT_RADIO_REPORT_IN_TEAM:
HandleRadioReportInTeam(entity, other);
break;
case EVENT_RADIO_AFFIRMATIVE:
HandleRadioAffirmative(entity, other);
break;
case EVENT_RADIO_ENEMY_SPOTTED:
HandleRadioEnemySpotted(entity, other);
break;
case EVENT_RADIO_NEED_BACKUP:
HandleRadioNeedBackup(entity, other);
break;
case EVENT_RADIO_SECTOR_CLEAR:
HandleRadioSectorClear(entity, other);
break;
case EVENT_RADIO_IN_POSITION:
HandleRadioInPosition(entity, other);
break;
case EVENT_RADIO_REPORTING_IN:
HandleRadioReportingIn(entity, other);
break;
case EVENT_RADIO_GET_OUT_OF_THERE:
HandleRadioGetOutOfThere(entity, other);
break;
case EVENT_RADIO_NEGATIVE:
HandleRadioNegative(entity, other);
break;
case EVENT_RADIO_ENEMY_DOWN:
HandleRadioEnemyDown(entity, other);
break;
default:
break;
}
}
void CCSTutor::HandleWeaponFired(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL && localPlayer->IsAlive())
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player == localPlayer)
{
CheckForNeedToReload();
}
}
}
void CCSTutor::HandleWeaponFiredOnEmpty(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == localPlayer)
{
CBasePlayerWeapon *currentWeapon = static_cast<CBasePlayerWeapon *>(player->m_pActiveItem);
if (currentWeapon != NULL && player->m_rgAmmo[currentWeapon->m_iPrimaryAmmoType] <= 0)
{
TutorMessage *message = GetTutorMessageDefinition(YOU_ARE_OUT_OF_AMMO);
if (message != NULL)
{
message->m_lastCloseTime = invalid_time_point;
}
CreateAndAddEventToList(YOU_ARE_OUT_OF_AMMO);
}
}
}
}
void CCSTutor::HandleWeaponReloaded(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == UTIL_GetLocalPlayer())
{
CancelEvent(YOU_SHOULD_RELOAD);
}
}
void CCSTutor::HandlePlayerDied(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
{
return;
}
CBasePlayer *victim = static_cast<CBasePlayer *>(entity);
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
if (victim != NULL && !victim->IsPlayer())
{
victim = NULL;
}
if (attacker != NULL && !attacker->IsPlayer())
{
attacker = NULL;
}
if (victim == localPlayer && !attacker)
{
if (localPlayer->m_bKilledByBomb)
{
CreateAndAddEventToList(YOU_DIED, entity, other);
}
else
{
CreateAndAddEventToList(YOU_FELL_TO_YOUR_DEATH);
}
}
if (!victim || !attacker)
return;
if (victim == attacker && victim == localPlayer)
{
CreateAndAddEventToList(YOU_DIED, entity, other);
return;
}
int numT, numCT;
GetNumPlayersAliveOnTeams(numT, numCT);
if (attacker == localPlayer)
{
if (victim->m_iTeam == attacker->m_iTeam)
{
CreateAndAddEventToList(YOU_KILLED_A_TEAMMATE, entity, other);
return;
}
if (victim->m_bHeadshotKilled)
{
switch (attacker->m_iTeam)
{
case CT:
{
switch (numT)
{
case 0:
CreateAndAddEventToList(YOU_KILLED_LAST_ENEMY_HEADSHOT, entity, other);
break;
case 1:
CreateAndAddEventToList(YOU_KILLED_PLAYER_HEADSHOT_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(YOU_KILLED_PLAYER_HEADSHOT, entity, other);
break;
}
break;
}
case TERRORIST:
{
switch (numCT)
{
case 0:
CreateAndAddEventToList(YOU_KILLED_LAST_ENEMY_HEADSHOT, entity, other);
break;
case 1:
CreateAndAddEventToList(YOU_KILLED_PLAYER_HEADSHOT_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(YOU_KILLED_PLAYER_HEADSHOT, entity, other);
break;
}
break;
}
default:
break;
}
}
else
{
switch (attacker->m_iTeam)
{
case CT:
{
switch (numT)
{
case 0:
CreateAndAddEventToList(YOU_KILLED_LAST_ENEMY, entity, other);
break;
case 1:
CreateAndAddEventToList(YOU_KILLED_PLAYER_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(YOU_KILLED_PLAYER, entity, other);
break;
}
break;
}
case TERRORIST:
{
switch (numCT)
{
case 0:
CreateAndAddEventToList(YOU_KILLED_LAST_ENEMY, entity, other);
break;
case 1:
CreateAndAddEventToList(YOU_KILLED_PLAYER_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(YOU_KILLED_PLAYER, entity, other);
break;
}
break;
}
default:
break;
}
}
}
else if (victim == localPlayer)
{
CreateAndAddEventToList(victim->m_bHeadshotKilled ? YOU_DIED_HEADSHOT : YOU_DIED, entity, other);
}
else if (victim->m_iTeam == localPlayer->m_iTeam)
{
switch (victim->m_iTeam)
{
case CT:
{
if (localPlayer->IsAlive())
{
if (numCT == 1)
{
CreateAndAddEventToList(LAST_TEAMMATE_KILLED, entity, other);
}
else if (numCT == 2)
{
CreateAndAddEventToList(TEAMMATE_KILLED_ONE_LEFT, entity, other);
}
else
{
CreateAndAddEventToList(TEAMMATE_KILLED, entity, other);
}
}
else
{
if (numCT == 1)
{
CreateAndAddEventToList(TEAMMATE_KILLED_ONE_LEFT, entity, other);
}
else if (numCT > 1)
{
CreateAndAddEventToList(TEAMMATE_KILLED, entity, other);
}
}
break;
}
case TERRORIST:
{
if (localPlayer->IsAlive())
{
if (numT == 1)
{
CreateAndAddEventToList(LAST_TEAMMATE_KILLED, entity, other);
}
else if (numT == 2)
{
CreateAndAddEventToList(TEAMMATE_KILLED_ONE_LEFT, entity, other);
}
else
{
CreateAndAddEventToList(TEAMMATE_KILLED, entity, other);
}
}
else
{
if (numT == 1)
{
CreateAndAddEventToList(TEAMMATE_KILLED_ONE_LEFT, entity, other);
}
else if (numT > 1)
{
CreateAndAddEventToList(TEAMMATE_KILLED, entity, other);
}
}
break;
}
default:
break;
}
}
else
{
switch (localPlayer->m_iTeam)
{
case CT:
{
switch (numT)
{
case 0:
CreateAndAddEventToList(LAST_ENEMY_KILLED, entity, other);
break;
case 1:
CreateAndAddEventToList(ENEMY_KILLED_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(ENEMY_KILLED, entity, other);
break;
}
break;
}
case TERRORIST:
{
switch (numCT)
{
case 0:
CreateAndAddEventToList(LAST_ENEMY_KILLED, entity, other);
break;
case 1:
CreateAndAddEventToList(ENEMY_KILLED_ONE_LEFT, entity, other);
break;
default:
CreateAndAddEventToList(ENEMY_KILLED, entity, other);
break;
}
break;
}
default:
break;
}
}
}
void CCSTutor::HandlePlayerTookDamage(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *victim = static_cast<CBasePlayer *>(entity);
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
if (victim != NULL && !victim->IsPlayer())
{
victim = NULL;
}
if (attacker != NULL && !attacker->IsPlayer())
{
attacker = NULL;
}
if (victim != NULL && victim == localPlayer)
{
CreateAndAddEventToList(YOU_WERE_JUST_HURT);
}
else if (attacker != NULL && victim != NULL && attacker == localPlayer && victim->m_iTeam == localPlayer->m_iTeam)
{
CreateAndAddEventToList(YOU_ATTACKED_TEAMMATE);
}
}
}
void CCSTutor::HandlePlayerBlindedByFlashbang(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == localPlayer)
{
CreateAndAddEventToList(YOU_ARE_BLIND_FROM_FLASHBANG);
}
}
}
void CCSTutor::HandlePlayerSpawned(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player->IsPlayer() && player == UTIL_GetLocalPlayer())
{
m_haveSpawned = true;
m_lastInGameHintShown = INGAME_HINT_BEGIN;
CreateAndAddEventToList(YOU_SPAWNED, entity, other);
}
}
NOXREF void CCSTutor::HandleClientCorpseSpawned(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player == NULL || !player->IsPlayer())
{
return;
}
ClientCorpseStruct *corpse = new ClientCorpseStruct;
corpse->m_position = player->pev->origin;
corpse->m_team = player->m_iTeam;
m_clientCorpseList.push_back(corpse);
}
void CCSTutor::HandleBuyMenuOpenned(CBaseEntity *entity, CBaseEntity *other)
{
if (m_currentlyShownMessageID == BUY_TIME_BEGIN)
{
ClearCurrentEvent();
CheckBuyZoneMessages();
}
}
void CCSTutor::HandleAutoBuy(CBaseEntity *entity, CBaseEntity *other)
{
if (m_currentlyShownMessageID == BUY_TIME_BEGIN)
{
ClearCurrentEvent();
}
}
NOXREF void CCSTutor::HandleBuyTimeStart(CBaseEntity *entity, CBaseEntity *other)
{
;
}
void CCSTutor::HandlePlayerLeftBuyZone(CBaseEntity *entity, CBaseEntity *other)
{
m_messageTypeMask = (TUTORMESSAGETYPE_DEFAULT | TUTORMESSAGETYPE_FRIEND_DEATH | TUTORMESSAGETYPE_ENEMY_DEATH | TUTORMESSAGETYPE_SCENARIO | TUTORMESSAGETYPE_CAREER | TUTORMESSAGETYPE_INGAME_HINT | TUTORMESSAGETYPE_END_GAME);
ClearEventList();
ClearCurrentEvent();
if (m_lastScenarioEvent != NULL)
{
m_lastScenarioEvent->SetActivationTime(gpGlobals->time);
AddToEventList(m_lastScenarioEvent);
m_lastScenarioEvent = NULL;
}
}
void CCSTutor::HandleBombPlanted(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *player = UTIL_GetLocalPlayer();
if (player == NULL)
{
return;
}
if (player->IsAlive() && player->m_iTeam == CT)
{
CreateAndAddEventToList(BOMB_PLANTED_CT, entity, other);
}
else
{
CreateAndAddEventToList(BOMB_PLANTED_T, entity, other);
}
}
void CCSTutor::HandleBombDefused(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *defuser = static_cast<CBasePlayer *>(entity);
if (defuser != NULL && defuser->IsPlayer() && defuser == localPlayer)
{
CreateAndAddEventToList(YOU_DEFUSED_BOMB);
}
else
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(BOMB_DEFUSED_CT);
break;
case TERRORIST:
CreateAndAddEventToList(BOMB_DEFUSED_T);
break;
default:
CreateAndAddEventToList(ROUND_OVER);
break;
}
}
}
}
void CCSTutor::HandleBombDefusing(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == localPlayer && !player->m_bHasDefuser)
{
CreateAndAddEventToList(DEFUSING_WITHOUT_KIT);
}
}
}
void CCSTutor::HandleBombExploded(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(BOMB_EXPLODED_CT);
break;
case TERRORIST:
CreateAndAddEventToList(BOMB_EXPLODED_T);
break;
default:
break;
}
}
}
void CCSTutor::HandleRoundStart(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *player = UTIL_GetLocalPlayer();
m_roundStartTime = gpGlobals->time;
if (player != NULL)
{
if (IsBombMap())
{
switch (player->m_iTeam)
{
case CT:
CreateAndAddEventToList(ROUND_START_DE_CT);
break;
case TERRORIST:
{
if (player->m_bHasC4)
CreateAndAddEventToList(YOU_ARE_BOMB_CARRIER, entity, other);
else
CreateAndAddEventToList(ROUND_START_DE_T);
break;
}
default:
break;
}
}
else if (IsHostageMap())
{
switch (player->m_iTeam)
{
case CT:
CreateAndAddEventToList(ROUND_START_CS_CT);
break;
case TERRORIST:
CreateAndAddEventToList(ROUND_START_CS_T);
break;
default:
break;
}
}
}
}
void CCSTutor::HandleBeingShotAt(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == localPlayer && localPlayer->IsAlive())
{
CreateAndAddEventToList(YOU_HAVE_BEEN_SHOT_AT, entity, other);
}
}
}
void CCSTutor::HandleHostageUsed(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *activator = static_cast<CBasePlayer *>(entity);
if (activator != NULL && activator->IsPlayer())
{
bool unusedHostages = !CheckForAllHostagesFollowingSomeone();
if (activator == localPlayer)
{
CreateAndAddEventToList(unusedHostages ? YOU_USED_HOSTAGE_MORE_LEFT : YOU_USED_HOSTAGE_NO_MORE_LEFT);
}
else if (!unusedHostages)
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(ALL_HOSTAGES_FOLLOWING_CT);
break;
case TERRORIST:
CreateAndAddEventToList(ALL_HOSTAGES_FOLLOWING_T);
break;
default:
break;
}
}
}
}
}
void CCSTutor::HandleHostageRescued(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *rescuer = static_cast<CBasePlayer *>(entity);
if (rescuer != NULL && rescuer->IsPlayer())
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList((localPlayer == rescuer) ? YOU_RESCUED_HOSTAGE : HOSTAGE_RESCUED_CT);
break;
case TERRORIST:
CreateAndAddEventToList(HOSTAGE_RESCUED_T);
break;
default:
break;
}
}
}
}
void CCSTutor::HandleAllHostagesRescued(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(ALL_HOSTAGES_RESCUED_CT);
break;
case TERRORIST:
CreateAndAddEventToList(ALL_HOSTAGES_RESCUED_T);
break;
default:
break;
}
}
}
void CCSTutor::HandleHostageDamaged(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
if (entity != NULL && attacker != NULL && attacker->IsPlayer() && localPlayer == attacker)
{
CreateAndAddEventToList(YOU_DAMAGED_HOSTAGE);
}
}
}
void CCSTutor::HandleHostageKilled(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CheckForAllHostagesDead();
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
if (entity != NULL && attacker != NULL && attacker->IsPlayer())
{
bool unusedHostages = CheckForAllHostagesFollowingSomeone();
if (localPlayer == attacker)
{
CreateAndAddEventToList(YOU_KILLED_HOSTAGE);
}
if (unusedHostages)
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(ALL_HOSTAGES_FOLLOWING_CT);
break;
case TERRORIST:
CreateAndAddEventToList(ALL_HOSTAGES_FOLLOWING_T);
break;
default:
break;
}
}
}
}
}
void CCSTutor::HandleRoundDraw(CBaseEntity *entity, CBaseEntity *other)
{
CHalfLifeMultiplay *mp = g_pGameRules;
if (mp->m_iTotalRoundsPlayed)
{
CreateAndAddEventToList(ROUND_DRAW);
}
ResetPlayerDeathInfo();
}
void CCSTutor::HandleCTWin(CBaseEntity *entith, CBaseEntity *other)
{
CreateAndAddEventToList(CT_WIN);
ResetPlayerDeathInfo();
}
void CCSTutor::HandleTWin(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(T_WIN);
ResetPlayerDeathInfo();
}
void CCSTutor::HandleDeathCameraStart(CBaseEntity *entity, CBaseEntity *other)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player != NULL && player->IsPlayer() && player == localPlayer)
{
m_messageTypeMask = (TUTORMESSAGETYPE_FRIEND_DEATH | TUTORMESSAGETYPE_ENEMY_DEATH | TUTORMESSAGETYPE_HINT | TUTORMESSAGETYPE_END_GAME);
CreateAndAddEventToList(DEATH_CAMERA_START);
}
}
}
void CCSTutor::HandleRadioCoverMe(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_COVER_ME, entity, other);
}
void CCSTutor::HandleRadioYouTakeThePoint(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_YOU_TAKE_THE_POINT, entity, other);
}
void CCSTutor::HandleRadioHoldThisPosition(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_HOLD_THIS_POSITION, entity, other);
}
void CCSTutor::HandleRadioRegroupTeam(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_REGROUP_TEAM, entity, other);
}
void CCSTutor::HandleRadioFollowMe(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_FOLLOW_ME, entity, other);
}
void CCSTutor::HandleRadioTakingFire(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_TAKING_FIRE, entity, other);
}
void CCSTutor::HandleRadioGoGoGo(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_GO_GO_GO, entity, other);
}
void CCSTutor::HandleRadioTeamFallBack(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_TEAM_FALL_BACK, entity, other);
}
void CCSTutor::HandleRadioStickTogetherTeam(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_STICK_TOGETHER_TEAM, entity, other);
}
void CCSTutor::HandleRadioGetInPositionAndWait(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_GET_IN_POSITION_AND_WAIT, entity, other);
}
void CCSTutor::HandleRadioStormTheFront(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_STORM_THE_FRONT, entity, other);
}
void CCSTutor::HandleRadioReportInTeam(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_REPORT_IN_TEAM, entity, other);
}
void CCSTutor::HandleRadioAffirmative(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_AFFIRMATIVE, entity, other);
}
void CCSTutor::HandleRadioEnemySpotted(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_ENEMY_SPOTTED, entity, other);
}
void CCSTutor::HandleRadioNeedBackup(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_NEED_BACKUP, entity, other);
}
void CCSTutor::HandleRadioSectorClear(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_SECTOR_CLEAR, entity, other);
}
void CCSTutor::HandleRadioInPosition(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_IN_POSITION, entity, other);
}
void CCSTutor::HandleRadioReportingIn(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_REPORTING_IN, entity, other);
}
void CCSTutor::HandleRadioGetOutOfThere(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_GET_OUT_OF_THERE, entity, other);
}
void CCSTutor::HandleRadioNegative(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_NEGATIVE, entity, other);
}
void CCSTutor::HandleRadioEnemyDown(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(RADIO_ENEMY_DOWN, entity, other);
}
void CCSTutor::HandleNotBuyingAnything(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_TIME_BEGIN, entity, other);
}
void CCSTutor::HandleNeedToBuyPrimaryWeapon(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_PRIMARY, entity, other);
}
void CCSTutor::HandleNeedToBuyPrimaryAmmo(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_PRIMARY_AMMO, entity, other);
}
void CCSTutor::HandleNeedToBuySecondaryAmmo(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_SECONDARY_AMMO, entity, other);
}
void CCSTutor::HandleNeedToBuyArmor(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_ARMOR, entity, other);
}
void CCSTutor::HandleNeedToBuyDefuseKit(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_DEFUSE_KIT, entity, other);
}
void CCSTutor::HandleNeedToBuyGrenade(CBaseEntity *entity, CBaseEntity *other)
{
CreateAndAddEventToList(BUY_NEED_GRENADE, entity, other);
}
void CCSTutor::HandleCareerTaskDone(CBaseEntity *entity, CBaseEntity *other)
{
int numTasksRemaining = 0;
if (TheCareerTasks != NULL && (numTasksRemaining = TheCareerTasks->GetNumRemainingTasks()) > 0)
CreateAndAddEventToList((numTasksRemaining == 1) ? CAREER_TASK_DONE_ONE_LEFT : CAREER_TASK_DONE_MORE_LEFT);
else
CreateAndAddEventToList(CAREER_TASK_DONE_ALL_DONE);
}
void CCSTutor::HandleShotFired(Vector source, Vector target)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
float d1, d, angle, FiringLineDistanceToPlayer;
d1 = (source - localPlayer->pev->origin).Length();
if (d1 > 32.0f)
{
d = (target - source).Length();
angle = d1 / d;
FiringLineDistanceToPlayer = sin(acos(angle)) * d1;
if (FiringLineDistanceToPlayer <= 3000.0f)
{
OnEvent(EVENT_BEING_SHOT_AT, localPlayer);
}
}
}
}
void CCSTutor::GetNumPlayersAliveOnTeams(int &numT, int &numCT)
{
numT = 0;
numCT = 0;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
if (player == NULL || !player->IsAlive())
{
continue;
}
switch (player->m_iTeam)
{
case CT:
numCT++;
break;
case TERRORIST:
numT++;
break;
default:
break;
}
}
}
void CCSTutor::CheckForLooseWeaponViewable()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
bool sawFirst = false;
CBaseEntity *weapon = NULL;
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_LOOSE_WEAPON);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
while ((weapon = UTIL_FindEntityByClassname(weapon, "weaponbox")) != NULL)
{
if (IsEntityInViewOfPlayer(weapon, localPlayer))
{
if (!sawFirst)
{
sawFirst = true;
CreateAndAddEventToList(YOU_SEE_LOOSE_WEAPON);
}
}
}
}
}
}
void CCSTutor::CheckForLooseDefuserViewable()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL && localPlayer->m_iTeam == CT)
{
bool sawFirst = false;
CBaseEntity *defuser = NULL;
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_LOOSE_DEFUSER);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
while ((defuser = UTIL_FindEntityByClassname(defuser, "item_thighpack")) != NULL)
{
if (IsEntityInViewOfPlayer(defuser, localPlayer))
{
if (!sawFirst)
{
sawFirst = true;
CreateAndAddEventToList(YOU_SEE_LOOSE_DEFUSER);
}
}
}
}
}
}
void CCSTutor::CheckForBombViewable()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
{
return;
}
CBaseEntity *bomb = UTIL_FindEntityByClassname(NULL, "grenade");
if (bomb != NULL && ((CGrenade *)bomb)->m_bIsC4 && IsEntityInViewOfPlayer(bomb, localPlayer))
{
switch (localPlayer->m_iTeam)
{
case CT:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_PLANTED_BOMB_CT);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_PLANTED_BOMB_CT);
}
break;
}
case TERRORIST:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_PLANTED_BOMB_T);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_PLANTED_BOMB_T);
}
break;
}
default:
break;
}
}
else
{
CBasePlayer *bombCarrier = NULL;
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
if (player && player->m_bHasC4)
{
bombCarrier = player;
break;
}
}
bomb = UTIL_FindEntityByClassname(NULL, "weapon_c4");
if (bomb != NULL && IsEntityInViewOfPlayer(bomb, localPlayer))
{
if (bombCarrier != NULL)
{
if (bombCarrier != localPlayer)
{
switch (localPlayer->m_iTeam)
{
case CT:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_BOMB_CARRIER_CT);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_BOMB_CARRIER_CT);
}
break;
}
case TERRORIST:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_BOMB_CARRIER_T);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_BOMB_CARRIER_T);
}
break;
}
default:
break;
}
}
}
else
{
switch (localPlayer->m_iTeam)
{
case CT:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_LOOSE_BOMB_CT);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_LOOSE_BOMB_CT);
}
break;
}
case TERRORIST:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_LOOSE_BOMB_T);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
{
CreateAndAddEventToList(YOU_SEE_LOOSE_BOMB_T);
}
break;
}
default:
break;
}
}
}
}
}
void CCSTutor::CheckForBombsiteViewable()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
{
return;
}
TutorMessageID mid = CheckForInBombZone();
if (mid == TUTOR_NUM_MESSAGES)
{
switch (localPlayer->m_iTeam)
{
case CT:
{
mid = YOU_SEE_BOMBSITE_CT;
break;
}
case TERRORIST:
{
if (localPlayer->m_bHasC4)
{
mid = YOU_SEE_BOMBSITE_T_BOMB;
}
else if (TheCSBots() == NULL || !TheCSBots()->IsBombPlanted())
{
mid = YOU_SEE_BOMBSITE_T;
}
break;
}
default:
break;
}
TutorMessage *definition = GetTutorMessageDefinition(mid);
if (definition == NULL || definition->m_class != TUTORMESSAGECLASS_EXAMINE)
{
bool sawFirst = false;
CBaseEntity *bombTarget = NULL;
while ((bombTarget = UTIL_FindEntityByClassname(bombTarget, "func_bomb_target")) != NULL)
{
if (IsBombPlantedInBombsite(bombTarget))
{
if (!sawFirst)
{
sawFirst = true;
CreateAndAddEventToList(mid);
break;
}
}
}
while ((bombTarget = UTIL_FindEntityByClassname(bombTarget, "info_bomb_target")) != NULL)
{
if (sawFirst)
break;
if (IsBombPlantedInBombsite(bombTarget))
{
if (!sawFirst)
{
sawFirst = true;
CreateAndAddEventToList(mid);
break;
}
}
}
}
}
else
CreateAndAddEventToList(mid);
}
TutorMessageID CCSTutor::CheckForInBombZone()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
TutorMessageID mid = TUTOR_NUM_MESSAGES;
if (localPlayer != NULL && localPlayer->m_iTeam == CT)
{
CBaseEntity *bombTarget = NULL;
while ((bombTarget = UTIL_FindEntityByClassname(bombTarget, "func_bomb_target")) != NULL)
{
if (IsBombPlantedInBombsite(bombTarget))
{
return YOU_SEE_PLANTED_BOMB_CT;
}
}
while ((bombTarget = UTIL_FindEntityByClassname(bombTarget, "info_bomb_target")) != NULL)
{
if (IsBombPlantedInBombsite(bombTarget))
{
return YOU_SEE_PLANTED_BOMB_CT;
}
}
}
return mid;
}
bool CCSTutor::IsBombPlantedInBombsite(CBaseEntity *bombTarget)
{
CGrenade *bomb = NULL;
while ((bomb = (CGrenade *)UTIL_FindEntityByClassname(bomb, "grenade")) != NULL)
{
if (bomb->m_bIsC4 && IsEntityInBombsite(bomb, bombTarget))
{
return true;
}
}
return false;
}
void CCSTutor::CheckForHostageViewable()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
return;
CBaseEntity *hostageEntity = NULL;
bool sawFirst = false;
while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
{
bool validHostage = false;
CHostage *hostage = static_cast<CHostage *>(hostageEntity);
if (hostage->pev->takedamage == DAMAGE_YES)
{
if (!hostage->IsFollowingSomeone())
validHostage = true;
}
if (hostage->IsValid() && validHostage && IsEntityInViewOfPlayer(hostage, localPlayer) && !sawFirst)
{
sawFirst = true;
switch (localPlayer->m_iTeam)
{
case CT:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_HOSTAGE_CT);
if (message != NULL && message->m_class == TUTORMESSAGECLASS_EXAMINE)
{
return;
}
CreateAndAddEventToList(YOU_SEE_HOSTAGE_CT);
break;
}
case TERRORIST:
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SEE_HOSTAGE_T);
if (message != NULL && message->m_class == TUTORMESSAGECLASS_EXAMINE)
{
return;
}
CreateAndAddEventToList(YOU_SEE_HOSTAGE_T);
break;
}
default:
break;
}
}
}
}
void CCSTutor::CheckForTimeRunningOut()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
CHalfLifeMultiplay *mpRules = g_pGameRules;
if (localPlayer == NULL || mpRules->IsFreezePeriod() || mpRules->TimeRemaining() > 30.0s)
{
return;
}
if (IsBombMap())
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(TIME_RUNNING_OUT_DE_CT);
break;
case TERRORIST:
CreateAndAddEventToList(TIME_RUNNING_OUT_DE_T);
break;
default:
break;
}
}
else if (IsHostageMap())
{
switch (localPlayer->m_iTeam)
{
case CT:
CreateAndAddEventToList(TIME_RUNNING_OUT_CS_CT);
break;
case TERRORIST:
CreateAndAddEventToList(TIME_RUNNING_OUT_CS_T);
break;
default:
break;
}
}
}
void CCSTutor::CheckForAllHostagesDead()
{
bool foundLiveOne = false;
CHostage *hostage = NULL;
while ((hostage = (CHostage *)UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL)
{
if (hostage->IsAlive())
{
foundLiveOne = true;
break;
}
}
if (!foundLiveOne)
{
CreateAndAddEventToList(ALL_HOSTAGES_DEAD);
}
}
bool CCSTutor::CheckForAllHostagesFollowingSomeone()
{
bool foundUnusedOne = false;
CHostage *hostage = NULL;
while ((hostage = (CHostage *)UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL)
{
if (hostage->pev->takedamage == DAMAGE_YES)
{
if (!hostage->IsFollowingSomeone())
{
foundUnusedOne = true;
break;
}
}
}
return foundUnusedOne ? false : true;
}
TutorMessage *CCSTutor::GetTutorMessageDefinition(int messageID)
{
if (messageID < 0 || messageID >= TUTOR_NUM_MESSAGES)
{
return nullptr;
}
TutorMessageMapIter iter = m_messageMap.find(TutorIdentifierList[messageID]);
if (iter != m_messageMap.end())
{
return (*iter).second;
}
return nullptr;
}
CBaseEntity *CCSTutor::GetEntityForMessageID(int messageID, CBaseEntity *last)
{
CBaseEntity *ret = NULL;
switch (messageID)
{
case YOU_SEE_FRIEND:
case YOU_SEE_ENEMY:
ret = UTIL_FindEntityByClassname(last, "player");
break;
case YOU_SEE_FRIEND_CORPSE:
{
// TODO: this code is noxref
// this code fucked my brain, in that pointer Vector * is passed through the CBaseEntity *
#if 1
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
if (!m_clientCorpseList.size())
{
return NULL;
}
ClientCorpseStruct *lastCorpse = NULL;
ClientCorpseListIter iter;
if (last)
{
iter = m_clientCorpseList.begin();
while (iter != m_clientCorpseList.end())
{
lastCorpse = (*iter);
if ((CBaseEntity *)lastCorpse == last)
break;
iter++;
}
while (iter != m_clientCorpseList.end())
{
ClientCorpseStruct *corpse = (*iter);
if (corpse->m_team == localPlayer->m_iTeam)
return (CBaseEntity *)&corpse->m_position;
iter++;
}
return nullptr;
}
else
return (CBaseEntity *)&m_clientCorpseList.front()->m_position;
}
#endif
break;
}
case YOU_SEE_LOOSE_BOMB_T:
case YOU_SEE_LOOSE_BOMB_CT:
case YOU_SEE_BOMB_CARRIER_T:
case YOU_SEE_BOMB_CARRIER_CT:
ret = UTIL_FindEntityByClassname(last, "weapon_c4");
break;
case YOU_SEE_PLANTED_BOMB_T:
case YOU_SEE_PLANTED_BOMB_CT:
ret = UTIL_FindEntityByClassname(last, "grenade");
break;
case YOU_SEE_LOOSE_WEAPON:
ret = UTIL_FindEntityByClassname(last, "weaponbox");
break;
case YOU_SEE_LOOSE_DEFUSER:
ret = UTIL_FindEntityByClassname(last, "item_thighpack");
break;
case YOU_SEE_HOSTAGE_T:
case YOU_SEE_HOSTAGE_CT:
case YOU_SEE_HOSTAGE_CT_EXAMINE:
ret = UTIL_FindEntityByClassname(last, "hostage_entity");
break;
}
return ret;
}
void CCSTutor::CheckHintMessages(time_point_t time)
{
if (m_deadAirStartTime == invalid_time_point || (time - m_deadAirStartTime <= duration_t(cv_tutor_hint_interval_time.value)))
{
return;
}
m_lastHintShown++;
bool confusingHint = false;
if (IsHostageMap())
{
if (m_lastHintShown > HINT_HOSTAGE_START)
{
confusingHint = true;
}
}
if (!confusingHint)
{
if (IsBombMap() && m_lastHintShown < HINT_END)
{
if (m_lastHintShown == HINT_END)
{
m_lastHintShown = HINT_1;
}
}
}
if (m_lastHintShown > HINT_END)
{
m_lastHintShown = HINT_1;
}
TutorMessage *message = GetTutorMessageDefinition(m_lastHintShown);
if (message != NULL)
{
CreateAndAddEventToList(m_lastHintShown);
}
}
void CCSTutor::CheckInGameHintMessages(time_point_t time)
{
if (m_deadAirStartTime == invalid_time_point || (time - m_deadAirStartTime <= duration_t(cv_tutor_hint_interval_time.value)))
{
return;
}
m_lastInGameHintShown++;
if (m_lastInGameHintShown <= INGAME_HINT_BEGIN || m_lastInGameHintShown >= INGAME_HINT_END)
{
return;
}
TutorMessage *message = GetTutorMessageDefinition(m_lastInGameHintShown);
if (message != NULL)
{
CreateAndAddEventToList(m_lastInGameHintShown);
}
}
void CCSTutor::CheckForNeedToReload(bool isPassiveCheck)
{
CBasePlayer *localPlayer;
CBasePlayerItem *currentItem;
CBasePlayerWeapon *currentWeapon;
ItemInfo itemInfo;
localPlayer = UTIL_GetLocalPlayer();
Q_memset(&itemInfo, 0, sizeof(itemInfo));
if (localPlayer == NULL || !localPlayer->IsPlayer())
{
return;
}
currentItem = localPlayer->m_pActiveItem;
if (currentItem == NULL || !currentItem->IsWeapon())
{
return;
}
currentWeapon = static_cast<CBasePlayerWeapon *>(currentItem);
currentWeapon->GetItemInfo(&itemInfo);
if (itemInfo.iSlot && itemInfo.iSlot != 1)
{
return;
}
if (localPlayer->m_rgAmmo[currentWeapon->m_iPrimaryAmmoType])
{
if (isPassiveCheck)
{
if (2 * currentWeapon->m_iClip < currentItem->iMaxClip() && !currentWeapon->m_fInReload)
{
CreateAndAddEventToList(YOU_SHOULD_RELOAD);
}
}
else
{
if (5 * currentWeapon->m_iClip < currentItem->iMaxClip() && !currentWeapon->m_fInReload)
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SHOULD_RELOAD);
if (message != NULL)
{
message->m_lastCloseTime = invalid_time_point;
}
CreateAndAddEventToList(YOU_SHOULD_RELOAD);
}
else
{
TutorMessage *message = GetTutorMessageDefinition(YOU_SHOULD_RELOAD);
if (message != NULL)
{
message->m_lastCloseTime = gpGlobals->time;
}
}
}
}
else if (!currentWeapon->m_iClip)
{
if (!isPassiveCheck)
{
TutorMessage *message = GetTutorMessageDefinition(YOU_ARE_OUT_OF_AMMO);
if (message != NULL)
{
message->m_lastCloseTime = invalid_time_point;
}
}
CreateAndAddEventToList(YOU_ARE_OUT_OF_AMMO);
}
}
void CCSTutor::CheckExamineMessages(time_point_t time)
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL)
return;
for (int i = 0; i < TUTOR_NUM_MESSAGES; ++i)
{
TutorMessage *message = GetTutorMessageDefinition(i);
if (message == NULL || message->m_class != TUTORMESSAGECLASS_EXAMINE)
continue;
CBaseEntity *entity = NULL;
bool isPlayerLooking = false;
while ((entity = GetEntityForMessageID(i, entity)) != NULL)
{
if (i == YOU_SEE_FRIEND_CORPSE || i == YOU_SEE_ENEMY_CORPSE)
{
if (IsPlayerLookingAtPosition((Vector *)entity, localPlayer))
{
isPlayerLooking = true;
break;
}
}
else if (i == YOU_SEE_HOSTAGE_CT_EXAMINE || i == YOU_SEE_FRIEND || i == YOU_SEE_ENEMY)
{
if (IsPlayerLookingAtEntity(entity, localPlayer))
{
isPlayerLooking = true;
break;
}
}
else if (IsPlayerLookingAtPosition(&entity->pev->origin, localPlayer))
{
isPlayerLooking = true;
break;
}
}
if (isPlayerLooking)
{
if (message->m_examineStartTime == invalid_time_point)
continue;
if (time - message->m_examineStartTime <= cv_tutor_examine_time.value * 1s)
continue;
bool validEntity = false;
if (i == YOU_SEE_FRIEND)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player->IsPlayer() && player->IsAlive() && player->m_iTeam == localPlayer->m_iTeam)
validEntity = true;
}
else if (i == YOU_SEE_ENEMY)
{
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
if (player->IsPlayer() && player->IsAlive() && player->m_iTeam == localPlayer->m_iTeam)
{
if ((player->m_iTeam != CT || localPlayer->m_iTeam == TERRORIST) && (player->m_iTeam != TERRORIST || localPlayer->m_iTeam == CT))
validEntity = true;
}
}
else if (i == YOU_SEE_HOSTAGE_CT_EXAMINE)
{
CHostage *hostage = static_cast<CHostage *>(entity);
if (entity->pev->takedamage == DAMAGE_YES)
{
if (!hostage->IsFollowingSomeone())
validEntity = true;
}
if (!hostage->IsValid() || !validEntity)
continue;
}
if (validEntity)
{
CreateAndAddEventToList((TutorMessageID)i, entity);
}
}
else
message->m_examineStartTime = invalid_time_point;
}
}
bool CCSTutor::CanLocalPlayerBuyStuff()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer != NULL)
{
return localPlayer->CanPlayerBuy();
}
return false;
}
void CCSTutor::CheckBuyZoneMessages()
{
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
if (localPlayer == NULL || m_currentlyShownMessageID == BUY_TIME_BEGIN)
{
return;
}
CBasePlayerWeapon *primary = static_cast<CBasePlayerWeapon *>(localPlayer->m_rgpPlayerItems[PRIMARY_WEAPON_SLOT]);
CBasePlayerWeapon *secondary = static_cast<CBasePlayerWeapon *>(localPlayer->m_rgpPlayerItems[PISTOL_SLOT]);
if (primary != NULL)
{
if (localPlayer->NeedsPrimaryAmmo() && localPlayer->CanAffordPrimaryAmmo())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_PRIMARY_AMMO);
return;
}
}
else
{
if (localPlayer->CanAffordPrimary())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_PRIMARY_WEAPON);
return;
}
}
if (secondary != NULL && localPlayer->NeedsSecondaryAmmo() && localPlayer->CanAffordSecondaryAmmo())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_SECONDARY_AMMO);
}
else if (localPlayer->NeedsArmor() && localPlayer->CanAffordArmor())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_ARMOR);
}
else if (localPlayer->NeedsDefuseKit() && localPlayer->CanAffordDefuseKit())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_DEFUSE_KIT);
}
else if (localPlayer->NeedsGrenade() && localPlayer->CanAffordGrenade())
{
TheTutor->OnEvent(EVENT_TUTOR_NEED_TO_BUY_GRENADE);
}
else
TheTutor->OnEvent(EVENT_TUTOR_NOT_BUYING_ANYTHING);
}
bool CCSTutor::IsHostageMap()
{
return UTIL_FindEntityByClassname(NULL, "hostage_entity") != NULL;
}
bool CCSTutor::IsBombMap()
{
CHalfLifeMultiplay *mpRules = g_pGameRules;
return mpRules->m_bMapHasBombTarget;
}
void CCSTutor::ResetPlayerDeathInfo()
{
for (size_t i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
{
m_playerDeathInfo[i].m_hasBeenShown = false;
m_playerDeathInfo[i].m_event = NULL;
}
}
void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, TutorMessageEvent *event)
{
if (!buf || !buflen)
{
return;
}
char scratch[32];
buf[0] = '\0';
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
if (pPlayer == NULL)
continue;
// ignore alive players
if (pPlayer->IsAlive())
continue;
if (pPlayer->m_iTeam != team)
continue;
Q_strcat(buf, " %n");
Q_sprintf(scratch, "%d\n", i);
Q_strcat(buf, scratch);
m_playerDeathInfo[i].m_event = event;
}
}
void CCSTutor::TransferDeathEvents(TutorMessageEvent *oldEvent, TutorMessageEvent *newEvent)
{
for (size_t i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
{
if (m_playerDeathInfo[i].m_event == oldEvent)
{
m_playerDeathInfo[i].m_event = newEvent;
}
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yoyojacky/CSMoE.git
git@gitee.com:yoyojacky/CSMoE.git
yoyojacky
CSMoE
CSMoE
master

搜索帮助