diff --git a/sp/src/game/server/ai_expresserfollowup.cpp b/sp/src/game/server/ai_expresserfollowup.cpp index 759f5c46ac..6557570925 100644 --- a/sp/src/game/server/ai_expresserfollowup.cpp +++ b/sp/src/game/server/ai_expresserfollowup.cpp @@ -225,7 +225,7 @@ static CResponseQueue::CFollowupTargetSpec_t ResolveFollowupTargetToEntity( AICo ConVar chet_debug_idle( "chet_debug_idle", "0", FCVAR_ARCHIVE, "If set one, many debug prints to help track down the TLK_IDLE issue. Set two for super verbose info" ); // extern ConVar chet_debug_idle; -bool CAI_ExpresserWithFollowup::Speak( AIConcept_t &concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +bool CAI_ExpresserWithFollowup::Speak( AIConcept_t concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) { VPROF("CAI_Expresser::Speak"); if ( IsSpeechGloballySuppressed() ) @@ -261,7 +261,7 @@ bool CAI_ExpresserWithFollowup::Speak( AIConcept_t &concept, const char *modifie } } - SpeechMsg( GetOuter(), "%s (%x) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)concept, gpGlobals->curtime ); + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)concept, gpGlobals->curtime ); // Msg( "%s:%s to %s:%s\n", GetOuter()->GetDebugName(), concept.GetStringConcept(), criteria.GetValue(criteria.FindCriterionIndex("Subject")), pTarget ? pTarget->GetDebugName() : "none" ); bool spoke = SpeakDispatchResponse( concept, &result, &criteria, filter ); @@ -297,7 +297,7 @@ static float GetSpeechDurationForResponse( const AI_Response * RESTRICT response // Purpose: Dispatches the result // Input : *response - //----------------------------------------------------------------------------- -bool CAI_ExpresserWithFollowup::SpeakDispatchResponse( AIConcept_t &concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter ) +bool CAI_ExpresserWithFollowup::SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter ) { // This gives the chance for the other bot to respond. if ( !concept.GetSpeaker().IsValid() ) diff --git a/sp/src/game/server/ai_playerally.cpp b/sp/src/game/server/ai_playerally.cpp index 43b82ed4f8..f7594febaf 100644 --- a/sp/src/game/server/ai_playerally.cpp +++ b/sp/src/game/server/ai_playerally.cpp @@ -792,11 +792,11 @@ void CAI_PlayerAlly::PostSpeakDispatchResponse( AIConcept_t concept, AI_Response { if ( bSaidHelloToNPC ) { - Warning("Q&A: '%s' said Hello to '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), concept ); + Warning("Q&A: '%s' said Hello to '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), (const char*)concept ); } else { - Warning("Q&A: '%s' questioned '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), concept ); + Warning("Q&A: '%s' questioned '%s' (concept %s)\n", GetDebugName(), GetSpeechTarget()->GetDebugName(), (const char*)concept ); } NDebugOverlay::HorzArrow( GetAbsOrigin(), GetSpeechTarget()->GetAbsOrigin(), 8, 0, 255, 0, 64, true, duration ); } @@ -1022,11 +1022,11 @@ void CAI_PlayerAlly::AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomN } } - Assert( selection.pResponse ); SetSpeechTarget( selection.hSpeechTarget ); #ifdef NEW_RESPONSE_SYSTEM SpeakDispatchResponse( selection.concept.c_str(), &selection.Response ); #else + Assert( selection.pResponse ); SpeakDispatchResponse( selection.concept.c_str(), selection.pResponse ); #endif @@ -1078,11 +1078,11 @@ int CAI_PlayerAlly::SelectNonCombatSpeechSchedule() AISpeechSelection_t selection; if ( SelectNonCombatSpeech( &selection ) ) { - Assert( selection.pResponse ); SetSpeechTarget( selection.hSpeechTarget ); #ifdef NEW_RESPONSE_SYSTEM SetPendingSpeech( selection.concept.c_str(), &selection.Response ); #else + Assert( selection.pResponse ); SetPendingSpeech( selection.concept.c_str(), selection.pResponse ); #endif } diff --git a/sp/src/game/server/ai_speech.cpp b/sp/src/game/server/ai_speech.cpp index dafad41e4a..10e7fcfecb 100644 --- a/sp/src/game/server/ai_speech.cpp +++ b/sp/src/game/server/ai_speech.cpp @@ -1240,7 +1240,7 @@ char *CAI_Expresser::ParseApplyContext( const char *szContext ) { // If it's really 0, then this is a waste of time Warning("\"%s\" was detected by applyContext operators as an operable number, but it's not.\n", szValue); - return strdup(szContext); + return szContext; } // This is the existing value; will be operated upon and become the final assignment diff --git a/sp/src/game/server/ai_speech_new.cpp b/sp/src/game/server/ai_speech_new.cpp index e886ab8f1b..41fe618276 100644 --- a/sp/src/game/server/ai_speech_new.cpp +++ b/sp/src/game/server/ai_speech_new.cpp @@ -10,10 +10,10 @@ #include "ai_speech.h" #include "game.h" -#include "engine/ienginesound.h" -#include "keyvalues.h" +#include "engine/IEngineSound.h" +#include "KeyValues.h" #include "ai_basenpc.h" -#include "ai_criteria.h" +#include "AI_Criteria.h" #include "isaverestore.h" #include "sceneentity.h" #include "ai_speechqueue.h" @@ -575,7 +575,7 @@ void CAI_Expresser::GatherCriteria( AI_CriteriaSet * RESTRICT outputSet, const A // Output : AI_Response //----------------------------------------------------------------------------- // AI_Response *CAI_Expresser::SpeakFindResponse( AIConcept_t concept, const char *modifiers /*= NULL*/ ) -bool CAI_Expresser::FindResponse( AI_Response &outResponse, AIConcept_t &concept, AI_CriteriaSet *criteria ) +bool CAI_Expresser::FindResponse( AI_Response &outResponse, const AIConcept_t &concept, AI_CriteriaSet *criteria ) { VPROF("CAI_Expresser::FindResponse"); IResponseSystem *rs = GetOuter()->GetResponseSystem(); @@ -703,7 +703,7 @@ bool CAI_Expresser::FindResponse( AI_Response &outResponse, AIConcept_t &concept // NULL - // Output : bool : true on success, false on fail //----------------------------------------------------------------------------- -AI_Response *CAI_Expresser::SpeakFindResponse( AI_Response *result, AIConcept_t &concept, AI_CriteriaSet *criteria ) +AI_Response *CAI_Expresser::SpeakFindResponse( AI_Response *result, const AIConcept_t &concept, AI_CriteriaSet *criteria ) { Assert(response); @@ -808,7 +808,7 @@ AI_Response *CAI_Expresser::SpeakFindResponse( AI_Response *result, AIConcept_t // Purpose: Dispatches the result // Input : *response - //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t &concept, AI_Response *result, AI_CriteriaSet *criteria, IRecipientFilter *filter /* = NULL */ ) +bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response *result, AI_CriteriaSet *criteria, IRecipientFilter *filter /* = NULL */ ) { char response[ 256 ]; result->GetResponse( response, sizeof( response ) ); @@ -1068,21 +1068,21 @@ bool CAI_Expresser::FireEntIOFromResponse( char *response, CBaseEntity *pInitiat char *pszParam; char *strtokContext; - pszEntname = strtok_s( response, " ", &strtokContext ); + pszEntname = V_strtok_s( response, " ", &strtokContext ); if ( !pszEntname ) { Warning( "Response was entityio but had bad value %s\n", response ); return false; } - pszInput = strtok_s( NULL, " ", &strtokContext ); + pszInput = V_strtok_s( NULL, " ", &strtokContext ); if ( !pszInput ) { Warning( "Response was entityio but had bad value %s\n", response ); return false; } - pszParam = strtok_s( NULL, " ", &strtokContext ); + pszParam = V_strtok_s( NULL, " ", &strtokContext ); // poke entity io CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, pszEntname, pInitiator ); @@ -1231,7 +1231,7 @@ void CAI_Expresser::MarkResponseAsUsed( AI_Response *response ) // Input : concept - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- -bool CAI_Expresser::Speak( AIConcept_t &concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +bool CAI_Expresser::Speak( AIConcept_t concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) { concept.SetSpeaker(GetOuter()); AI_CriteriaSet criteria; @@ -1245,7 +1245,7 @@ bool CAI_Expresser::Speak( AIConcept_t &concept, const char *modifiers /*= NULL* //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool CAI_Expresser::Speak( AIConcept_t &concept, AI_CriteriaSet * RESTRICT criteria, char *pszOutResponseChosen , size_t bufsize , IRecipientFilter *filter ) +bool CAI_Expresser::Speak( const AIConcept_t &concept, AI_CriteriaSet * RESTRICT criteria, char *pszOutResponseChosen , size_t bufsize , IRecipientFilter *filter ) { VPROF("CAI_Expresser::Speak"); if ( IsSpeechGloballySuppressed() ) @@ -1260,7 +1260,7 @@ bool CAI_Expresser::Speak( AIConcept_t &concept, AI_CriteriaSet * RESTRICT crite return false; } - SpeechMsg( GetOuter(), "%s (%x) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)concept, gpGlobals->curtime ); + SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)", STRING(GetOuter()->GetEntityName()), GetOuter(), (const char*)concept, gpGlobals->curtime ); // Msg( "%s:%s to %s:%s\n", GetOuter()->GetDebugName(), concept.GetStringConcept(), criteria.GetValue(criteria.FindCriterionIndex("Subject")), pTarget ? pTarget->GetDebugName() : "none" ); bool spoke = SpeakDispatchResponse( concept, &result, criteria, filter ); @@ -1447,7 +1447,7 @@ bool CAI_Expresser::CanSpeakAfterMyself() } //------------------------------------- -bool CAI_Expresser::CanSpeakConcept( AIConcept_t concept ) +bool CAI_Expresser::CanSpeakConcept( const AIConcept_t &concept ) { // Not in history? int iter = m_ConceptHistories.Find( concept ); @@ -1479,14 +1479,14 @@ bool CAI_Expresser::CanSpeakConcept( AIConcept_t concept ) //------------------------------------- -bool CAI_Expresser::SpokeConcept( AIConcept_t concept ) +bool CAI_Expresser::SpokeConcept( const AIConcept_t &concept ) { return GetTimeSpokeConcept( concept ) != -1.f; } //------------------------------------- -float CAI_Expresser::GetTimeSpokeConcept( AIConcept_t concept ) +float CAI_Expresser::GetTimeSpokeConcept( const AIConcept_t &concept ) { int iter = m_ConceptHistories.Find( concept ); if ( iter == m_ConceptHistories.InvalidIndex() ) @@ -1498,7 +1498,7 @@ float CAI_Expresser::GetTimeSpokeConcept( AIConcept_t concept ) //------------------------------------- -void CAI_Expresser::SetSpokeConcept( AIConcept_t concept, AI_Response *response, bool bCallback ) +void CAI_Expresser::SetSpokeConcept( const AIConcept_t &concept, AI_Response *response, bool bCallback ) { int idx = m_ConceptHistories.Find( concept ); if ( idx == m_ConceptHistories.InvalidIndex() ) @@ -1523,7 +1523,7 @@ void CAI_Expresser::SetSpokeConcept( AIConcept_t concept, AI_Response *response, //------------------------------------- -void CAI_Expresser::ClearSpokeConcept( AIConcept_t concept ) +void CAI_Expresser::ClearSpokeConcept( const AIConcept_t &concept ) { m_ConceptHistories.Remove( concept ); } @@ -1560,7 +1560,7 @@ bool CAI_Expresser::IsValidResponse( ResponseType_t type, const char *pszValue ) CAI_TimedSemaphore *CAI_Expresser::GetMySpeechSemaphore( CBaseEntity *pNpc ) { if ( !pNpc->MyNPCPointer() ) - return false; + return NULL; return (pNpc->MyNPCPointer()->IsPlayerAlly() ? &g_AIFriendliesTalkSemaphore : &g_AIFoesTalkSemaphore ); } @@ -1573,16 +1573,23 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) if ( !DebuggingSpeech() ) return; + va_list arg_ptr; + + va_start(arg_ptr, pszFormat); + CFmtStr formatted; + formatted.sprintf_argv(pszFormat, arg_ptr); + va_end(arg_ptr); + if ( pFlex->MyNPCPointer() ) { - DevMsg( pFlex->MyNPCPointer(), CFmtStr( &pszFormat ) ); + DevMsg( pFlex->MyNPCPointer(), "%s", formatted.Get() ); } else { - CGMsg( 1, CON_GROUP_SPEECH_AI, CFmtStr( &pszFormat ) ); + CGMsg( 1, CON_GROUP_SPEECH_AI, "%s", formatted.Get() ); } - UTIL_LogPrintf( (char *) ( (const char *) CFmtStr( &pszFormat ) ) ); + UTIL_LogPrintf( "%s", formatted.Get() ); } //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/ai_speech_new.h b/sp/src/game/server/ai_speech_new.h index fec4f8c2f4..1882e66e9b 100644 --- a/sp/src/game/server/ai_speech_new.h +++ b/sp/src/game/server/ai_speech_new.h @@ -12,7 +12,7 @@ #include "soundflags.h" #include "AI_Criteria.h" -#include "ai_responsesystem.h" +#include "AI_ResponseSystem.h" #include "utldict.h" #include "ai_speechconcept.h" @@ -162,8 +162,8 @@ class CAI_Expresser : public ResponseRules::IResponseFilter // -------------------------------- - bool Speak( AIConcept_t &concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); - bool Speak( AIConcept_t &concept, AI_CriteriaSet *criteria, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + bool Speak( const AIConcept_t &concept, AI_CriteriaSet *criteria, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); // Given modifiers (which are colon-delimited strings), fill out a criteria set including this // character's contexts and the ones in the modifier. This lets us hang on to them after a call @@ -174,8 +174,8 @@ class CAI_Expresser : public ResponseRules::IResponseFilter // AI_Response *SpeakFindResponse( AIConcept_t &concept, AI_CriteriaSet *criteria ); // Find the appropriate response for the given concept. Return false if none found. // Fills out the response object that you provide. - bool FindResponse( AI_Response &outResponse, AIConcept_t &concept, AI_CriteriaSet *modifiers = NULL ); - virtual bool SpeakDispatchResponse( AIConcept_t &concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); + bool FindResponse( AI_Response &outResponse, const AIConcept_t &concept, AI_CriteriaSet *modifiers = NULL ); + virtual bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); float GetResponseDuration( AI_Response *response ); #ifdef MAPBASE @@ -206,11 +206,11 @@ class CAI_Expresser : public ResponseRules::IResponseFilter // -------------------------------- - bool CanSpeakConcept( AIConcept_t concept ); - bool SpokeConcept( AIConcept_t concept ); - float GetTimeSpokeConcept( AIConcept_t concept ); // returns -1 if never - void SetSpokeConcept( AIConcept_t concept, AI_Response *response, bool bCallback = true ); - void ClearSpokeConcept( AIConcept_t concept ); + bool CanSpeakConcept( const AIConcept_t &concept ); + bool SpokeConcept( const AIConcept_t &concept ); + float GetTimeSpokeConcept( const AIConcept_t &concept ); // returns -1 if never + void SetSpokeConcept( const AIConcept_t &concept, AI_Response *response, bool bCallback = true ); + void ClearSpokeConcept( const AIConcept_t &concept ); // -------------------------------- @@ -226,7 +226,7 @@ class CAI_Expresser : public ResponseRules::IResponseFilter bool ScriptSpeakRawScene( char const *soundname, float delay ) { return SpeakRawScene( soundname, delay, NULL ); } bool ScriptSpeakAutoGeneratedScene( char const *soundname, float delay ) { return SpeakAutoGeneratedScene( soundname, delay ); } int ScriptSpeakRawSentence( char const *pszSentence, float delay ) { return SpeakRawSentence( pszSentence, delay ); } - bool ScriptSpeak( char const *concept, const char *modifiers ) { return Speak( CAI_Concept( concept ), modifiers[0] != '\0' ? modifiers : NULL ); } + bool ScriptSpeak( char const *concept, const char *modifiers ) { return Speak( concept, modifiers[0] != '\0' ? modifiers : NULL ); } #endif // helper used in dealing with RESPONSE_ENTITYIO @@ -249,7 +249,7 @@ class CAI_Expresser : public ResponseRules::IResponseFilter void DumpHistories(); - void SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ); + void SpeechMsg( CBaseEntity *pFlex, PRINTF_FORMAT_STRING const char *pszFormat, ... ) FMTFUNCTION(3, 4); // -------------------------------- @@ -321,15 +321,15 @@ class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink // These two methods allow looking up a response and dispatching it to be two different steps #ifdef MAPBASE //AI_Response *SpeakFindResponse( AIConcept_t concept, const AI_CriteriaSet& modifiers ); - inline bool SpeakDispatchResponse( AIConcept_t concept, AI_Response &response, AI_CriteriaSet *criteria = NULL ) { return SpeakDispatchResponse( concept, &response, criteria ); } + inline bool SpeakDispatchResponse( const AIConcept_t &concept, AI_Response &response, AI_CriteriaSet *criteria = NULL ) { return SpeakDispatchResponse( concept, &response, criteria ); } #endif - bool SpeakFindResponse( AI_Response& outResponse, AIConcept_t concept, const char *modifiers = NULL ); + bool SpeakFindResponse( AI_Response& outResponse, const AIConcept_t &concept, const char *modifiers = NULL ); // AI_Response * SpeakFindResponse( AIConcept_t concept, const char *modifiers = NULL ); // AI_Response *SpeakFindResponse( AIConcept_t concept, AI_CriteriaSet *criteria ); // AI_Response *SpeakFindResponse( AIConcept_t concept ); // Find the appropriate response for the given concept. Return false if none found. // Fills out the response object that you provide. - bool FindResponse( AI_Response &outResponse, AIConcept_t &concept, AI_CriteriaSet *criteria = NULL ); + bool FindResponse( AI_Response &outResponse, const AIConcept_t &concept, AI_CriteriaSet *criteria = NULL ); bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria = NULL ); virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ) { return; } @@ -436,7 +436,7 @@ inline void CAI_ExpresserHost::GatherCriteria( AI_CriteriaSet *outputC //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakFindResponse(AI_Response& outResponse, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +inline bool CAI_ExpresserHost::SpeakFindResponse(AI_Response& outResponse, const AIConcept_t &concept, const char *modifiers /*= NULL*/ ) { AI_CriteriaSet criteria; GatherCriteria(&criteria, concept, modifiers); @@ -446,7 +446,7 @@ inline bool CAI_ExpresserHost::SpeakFindResponse(AI_Response& outRespo //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept, const char *modifiers /*= NULL*/ ) +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &concept, const char *modifiers /*= NULL*/ ) { return this->GetExpresser()->SpeakFindResponse( concept, modifiers ); } @@ -456,7 +456,7 @@ inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept, AI_CriteriaSet *criteria /*= NULL*/ ) +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &concept, AI_CriteriaSet *criteria /*= NULL*/ ) { return this->GetExpresser()->SpeakFindResponse( concept, criteria ); } @@ -467,7 +467,7 @@ inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t // class that generates a one off. //----------------------------------------------------------------------------- template -inline AI_Response * CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept ) +inline AI_Response * CAI_ExpresserHost::SpeakFindResponse( const AIConcept_t &concept ) { AI_CriteriaSet criteria; GatherCriteria( &criteria, concept, NULL ); @@ -479,7 +479,7 @@ inline AI_Response * CAI_ExpresserHost::SpeakFindResponse( AIConcept_t //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::FindResponse( AI_Response &outResponse, AIConcept_t &concept, AI_CriteriaSet *criteria ) +inline bool CAI_ExpresserHost::FindResponse( AI_Response &outResponse, const AIConcept_t &concept, AI_CriteriaSet *criteria ) { return this->GetExpresser()->FindResponse( outResponse, concept, criteria ); } @@ -512,9 +512,9 @@ inline float CAI_ExpresserHost::GetResponseDuration( AI_Response *resp //----------------------------------------------------------------------------- template inline void CAI_ExpresserHost::DispatchResponse( const char *conceptName ) - { - Speak( (AIConcept_t)conceptName ); - } +{ + Speak( AIConcept_t( conceptName ) ); +} //----------------------------------------------------------------------------- @@ -529,7 +529,7 @@ inline void CAI_ExpresserHost::DispatchResponse( const char *conceptNa template class CAI_ExpresserHostWithData : public CAI_ExpresserHost { - DECLARE_CLASS_NOFRIEND( CAI_ExpresserHostWithData, CAI_ExpresserHost ); + DECLARE_CLASS_NOFRIEND( CAI_ExpresserHostWithData, CAI_ExpresserHost ); public: CAI_ExpresserHostWithData( ) : m_pExpresser(NULL) {}; @@ -545,11 +545,11 @@ class CAI_ExpresserHostWithData : public CAI_ExpresserHost protected: EXPRESSER_TYPE *CreateExpresser( void ) { - AssertMsg1( m_pExpresser == NULL, "Tried to double-initialize expresser in %s\n", GetDebugName() ); + AssertMsg1( m_pExpresser == NULL, "Tried to double-initialize expresser in %s\n", this->GetDebugName() ); m_pExpresser = new EXPRESSER_TYPE(this); if ( !m_pExpresser) { - AssertMsg1( false, "Creating an expresser failed in %s\n", GetDebugName() ); + AssertMsg1( false, "Creating an expresser failed in %s\n", this->GetDebugName() ); return NULL; } @@ -667,8 +667,8 @@ class CAI_ExpresserWithFollowup : public CAI_Expresser CAI_ExpresserWithFollowup( CBaseFlex *pOuter = NULL ) : CAI_Expresser(pOuter), m_pPostponedFollowup(NULL) {}; - virtual bool Speak( AIConcept_t &concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); - virtual bool SpeakDispatchResponse( AIConcept_t &concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); + virtual bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria, IRecipientFilter *filter = NULL ); virtual void SpeakDispatchFollowup( AI_ResponseFollowup &followup ); virtual void OnSpeechFinished(); diff --git a/sp/src/game/server/effects.cpp b/sp/src/game/server/effects.cpp index 7b07e15709..cbe0519083 100644 --- a/sp/src/game/server/effects.cpp +++ b/sp/src/game/server/effects.cpp @@ -2511,7 +2511,7 @@ class CBreakableGibShooter : public CBaseEntity DECLARE_DATADESC(); public: - const char *GetRandomTemplateModel( CPointTemplate *pTemplate ); + int GetRandomTemplateModelIndex( CPointTemplate *pTemplate ); void Precache( void ); @@ -2560,19 +2560,16 @@ END_DATADESC() LINK_ENTITY_TO_CLASS( env_break_shooter, CBreakableGibShooter ); -const char *CBreakableGibShooter::GetRandomTemplateModel( CPointTemplate *pTemplate ) +int CBreakableGibShooter::GetRandomTemplateModelIndex( CPointTemplate *pTemplate ) { int iIndex = RandomInt( 0, pTemplate->GetNumTemplates() ); - char *iszTemplate = (char*)(STRING(Templates_FindByIndex(pTemplate->GetTemplateIndexForTemplate(iIndex)))); - - CEntityMapData entData( iszTemplate ); + const char *szTemplate = STRING(Templates_FindByIndex(pTemplate->GetTemplateIndexForTemplate(iIndex))); // This might seem a little messy, but I think it's cheaper than creating the entity. char szModel[MAPKEY_MAXLENGTH]; - if (!entData.ExtractValue("model", szModel)) - return NULL; + bool modelExtracted = MapEntity_ExtractValue(szTemplate, "model", szModel); - return strdup(szModel); + return modelinfo->GetModelIndex( modelExtracted ? szModel : NULL ); } void CBreakableGibShooter::Precache( void ) @@ -2604,7 +2601,7 @@ void CBreakableGibShooter::Shoot( void ) if (m_iModelType == MODELTYPE_BREAKABLECHUNKS) iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( GetModelName() ) ) ); else if (m_iModelType == MODELTYPE_TEMPLATE) - iModelIndex = modelinfo->GetModelIndex( GetRandomTemplateModel(pTemplate) ); + iModelIndex = GetRandomTemplateModelIndex( pTemplate ); // All objects except the first one in this run are marked as slaves... int slaveFlag = 0; diff --git a/sp/src/game/server/genericactor.cpp b/sp/src/game/server/genericactor.cpp index bb0dfe0bc7..8f60651996 100644 --- a/sp/src/game/server/genericactor.cpp +++ b/sp/src/game/server/genericactor.cpp @@ -277,7 +277,8 @@ bool CGenericActorCustom::KeyValue( const char *szKeyName, const char *szValue ) //----------------------------------------------------------------------------- void CGenericActorCustom::SpeakIfAllowed( const char *concept, AI_CriteriaSet *modifiers ) { - Speak( concept, modifiers ? *modifiers : AI_CriteriaSet() ); + AI_CriteriaSet empty; + Speak( concept, modifiers ? *modifiers : empty ); } //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/hl2/npc_zombie.cpp b/sp/src/game/server/hl2/npc_zombie.cpp index 2191b39436..83a6ed9e3b 100644 --- a/sp/src/game/server/hl2/npc_zombie.cpp +++ b/sp/src/game/server/hl2/npc_zombie.cpp @@ -1263,7 +1263,8 @@ void CZombieCustom::AttackSound( void ) //----------------------------------------------------------------------------- void CZombieCustom::SpeakIfAllowed(const char *concept, AI_CriteriaSet *modifiers) { - Speak( concept, modifiers ? *modifiers : AI_CriteriaSet() ); + AI_CriteriaSet empty; + Speak( concept, modifiers ? *modifiers : empty ); } //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/mapbase/ai_monitor.cpp b/sp/src/game/server/mapbase/ai_monitor.cpp index 754ff56d9b..fa11a20398 100644 --- a/sp/src/game/server/mapbase/ai_monitor.cpp +++ b/sp/src/game/server/mapbase/ai_monitor.cpp @@ -672,6 +672,33 @@ int CAI_Monitor::TranslateScheduleString(const char *schedName) return 0; } +template +static void SetForEachDelimited( CAI_Monitor &monitor, const char *szValue, const char *delimiters, void (CAI_Monitor::*setter)(int), Translator translator) +{ + char *value = strdup(szValue); + char *token = strtok(value, ":"); + while (token) + { + (monitor.*setter)(translator(token)); + + token = strtok(NULL, ":"); + } + free(value); +} + +template +struct CAI_MonitorTranslator +{ + CAI_Monitor &monitor; + + CAI_MonitorTranslator(CAI_Monitor &monitor) : monitor(monitor) {} + + int operator()(const char *value) + { + return (monitor.*translator)(value); + } +}; + //----------------------------------------------------------------------------- // Purpose: Cache user entity field values until spawn is called. // Input : szKeyName - Key to handle. @@ -688,13 +715,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue ) } else if (FStrEq(szKeyName, "Conditions")) { - char *token = strtok(strdup(szValue), ":"); - while (token) - { - SetCondition(TranslateConditionString(token)); - - token = strtok(NULL, ":"); - } + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetCondition, CAI_MonitorTranslator<&CAI_Monitor::TranslateConditionString>(*this)); } else if (FStrEq(szKeyName, "SchedulesSimple")) { @@ -703,13 +724,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue ) } else if (FStrEq(szKeyName, "Schedules")) { - char *token = strtok(strdup(szValue), ":"); - while (token) - { - SetSchedule(TranslateScheduleString(token)); - - token = strtok(NULL, ":"); - } + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetSchedule, CAI_MonitorTranslator<&CAI_Monitor::TranslateScheduleString>(*this)); } else if (FStrEq(szKeyName, "HintsSimple")) { @@ -718,13 +733,7 @@ bool CAI_Monitor::KeyValue( const char *szKeyName, const char *szValue ) } else if (FStrEq(szKeyName, "Hints")) { - char *token = strtok(strdup(szValue), ":"); - while (token) - { - SetHint(atoi(szValue)); - - token = strtok(NULL, ":"); - } + SetForEachDelimited(*this, szValue, ":", &CAI_Monitor::SetHint, atoi); } else return CBaseEntity::KeyValue( szKeyName, szValue ); diff --git a/sp/src/game/shared/ai_criteria_new.cpp b/sp/src/game/shared/ai_criteria_new.cpp index 31a5b1eff0..837c61aad7 100644 --- a/sp/src/game/shared/ai_criteria_new.cpp +++ b/sp/src/game/shared/ai_criteria_new.cpp @@ -6,14 +6,14 @@ // //===========================================================================// #include "cbase.h" -#include "ai_criteria.h" +#include "AI_Criteria.h" #ifdef GAME_DLL #include "ai_speech.h" #endif -#include -#include "engine/ienginesound.h" +#include +#include "engine/IEngineSound.h" // memdbgon must be the last include file in a .cpp file!!! #include diff --git a/sp/src/game/shared/ai_responsesystem_new.cpp b/sp/src/game/shared/ai_responsesystem_new.cpp index 4dbf822289..6c3301bb76 100644 --- a/sp/src/game/shared/ai_responsesystem_new.cpp +++ b/sp/src/game/shared/ai_responsesystem_new.cpp @@ -6,11 +6,11 @@ #include "cbase.h" -#include "soundemittersystem/isoundemittersystembase.h" -#include "ai_responsesystem.h" +#include "SoundEmitterSystem/isoundemittersystembase.h" +#include "AI_ResponseSystem.h" #include "igamesystem.h" -#include "ai_criteria.h" -#include +#include "AI_Criteria.h" +#include #include "filesystem.h" #include "utldict.h" #ifdef GAME_DLL diff --git a/sp/src/game/shared/ai_responsesystem_new.h b/sp/src/game/shared/ai_responsesystem_new.h index a558f79e70..9d2fff6b0c 100644 --- a/sp/src/game/shared/ai_responsesystem_new.h +++ b/sp/src/game/shared/ai_responsesystem_new.h @@ -13,7 +13,7 @@ #pragma once #endif -#include "ai_criteria.h" +#include "AI_Criteria.h" #include "../../public/responserules/response_types.h" // using ResponseRules::IResponseFilter; diff --git a/sp/src/game/shared/ai_speechconcept.h b/sp/src/game/shared/ai_speechconcept.h index 41a3cc60b8..3e375a0ad0 100644 --- a/sp/src/game/shared/ai_speechconcept.h +++ b/sp/src/game/shared/ai_speechconcept.h @@ -12,7 +12,7 @@ #pragma once #endif -#include "../../public/responserules/response_types.h" +#include "responserules/response_types.h" class CAI_Concept : public ResponseRules::CRR_Concept { diff --git a/sp/src/game/shared/mapbase/MapEdit.cpp b/sp/src/game/shared/mapbase/MapEdit.cpp index 326599648a..9ff1db6045 100644 --- a/sp/src/game/shared/mapbase/MapEdit.cpp +++ b/sp/src/game/shared/mapbase/MapEdit.cpp @@ -464,7 +464,7 @@ class CMapEdit : public CAutoGameSystemPerFrame { pNodeName = pName->GetName(); - const char *pInputName = NULL; + string_t pInputName = NULL_STRING; variant_t varInputParam; float flInputDelay = 0.0f; CBaseEntity *pActivator = NULL; @@ -480,7 +480,7 @@ class CMapEdit : public CAutoGameSystemPerFrame { // Input name case 0: - pInputName = inputparams; break; + pInputName = AllocPooledString(inputparams); break; // Input parameter case 1: varInputParam.SetString(AllocPooledString(inputparams)); break; @@ -500,9 +500,10 @@ class CMapEdit : public CAutoGameSystemPerFrame iter++; inputparams = strtok(NULL, ","); } + free(pszValue); DebugMsg("MapEdit Debug: Firing input %s on %s\n", pInputName, pNodeName); - g_EventQueue.AddEvent(pNodeName, pInputName, varInputParam, flInputDelay, pActivator, pCaller, iOutputID); + g_EventQueue.AddEvent(pNodeName, STRING(pInputName), varInputParam, flInputDelay, pActivator, pCaller, iOutputID); pName = pName->GetNextKey(); } diff --git a/sp/src/public/responserules/response_types.h b/sp/src/public/responserules/response_types.h index a3e8fea3a4..2e80cc5aae 100644 --- a/sp/src/public/responserules/response_types.h +++ b/sp/src/public/responserules/response_types.h @@ -65,16 +65,16 @@ namespace ResponseRules float followup_delay; // 20 const char *followup_target; // 24 -- to whom is this despatched? // AIConceptHandle_t hConcept; - const char *followup_entityiotarget; //< if this rule involves firing entity io - const char *followup_entityioinput; //< if this rule involves firing entity io + const char *followup_entityiotarget; //< if this rule involves firing entity io + const char *followup_entityioinput; //< if this rule involves firing entity io float followup_entityiodelay; bool bFired; - inline bool IsValid( void ) const { return (followup_concept && followup_contexts); } - inline void Invalidate() { followup_concept = NULL; followup_contexts = NULL; } - inline void SetFired( bool fired ) { bFired = fired; } - inline bool HasBeenFired() { return bFired; } - + inline bool IsValid( void ) const { return (followup_concept && followup_contexts); } + inline void Invalidate() { followup_concept = NULL; followup_contexts = NULL; } + inline void SetFired( bool fired ) { bFired = fired; } + inline bool HasBeenFired() { return bFired; } + AI_ResponseFollowup( void ) : followup_concept(NULL), followup_contexts(NULL), followup_delay(0), followup_target(NULL), followup_entityiotarget(NULL), followup_entityioinput(NULL), followup_entityiodelay(0), bFired(false) {}; AI_ResponseFollowup( char *_followup_concept, char *_followup_contexts, float _followup_delay, char *_followup_target, @@ -235,67 +235,67 @@ namespace ResponseRules /// entity, subsequent to the match but BEFORE the dispatch. /// Returns the number of contexts modified. If it returns 0, then /// pSetOnWorld is empty. - static int InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, - CriteriaSet * RESTRICT pSetOnWorld ); + static int InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, + CriteriaSet * RESTRICT pSetOnWorld ); private: - void RemoveCriteria( int idx, bool bTestForPrefix ); + void RemoveCriteria( int idx, bool bTestForPrefix ); struct CritEntry_t { CritEntry_t() : - criterianame( UTL_INVAL_SYMBOL ), - weight( 0.0f ) - { - value[ 0 ] = 0; - } - - CritEntry_t( const CritEntry_t& src ) - { - criterianame = src.criterianame; - value[ 0 ] = 0; - weight = src.weight; - SetValue( src.value ); - } + criterianame( UTL_INVAL_SYMBOL ), + weight( 0.0f ) + { + value[ 0 ] = 0; + } - CritEntry_t& operator=( const CritEntry_t& src ) - { - if ( this == &src ) - return *this; + CritEntry_t( const CritEntry_t& src ) + { + criterianame = src.criterianame; + value[ 0 ] = 0; + weight = src.weight; + SetValue( src.value ); + } - criterianame = src.criterianame; - weight = src.weight; - SetValue( src.value ); + CritEntry_t& operator=( const CritEntry_t& src ) + { + if ( this == &src ) + return *this; - return *this; - } + criterianame = src.criterianame; + weight = src.weight; + SetValue( src.value ); - static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs ) - { - return lhs.criterianame < rhs.criterianame; - } + return *this; + } - void SetValue( char const *str ) - { - if ( !str ) + static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs ) { - value[ 0 ] = 0; + return lhs.criterianame < rhs.criterianame; } - else + + void SetValue( char const *str ) { - Q_strncpy( value, str, sizeof( value ) ); + if ( !str ) + { + value[ 0 ] = 0; + } + else + { + Q_strncpy( value, str, sizeof( value ) ); + } } - } - CritSymbol_t criterianame; - char value[ 64 ]; - float weight; + CritSymbol_t criterianame; + char value[ 64 ]; + float weight; }; static CUtlSymbolTable sm_CriteriaSymbols; - typedef CUtlRBTree< CritEntry_t, short > Dict_t; - Dict_t m_Lookup; - int m_nNumPrefixedContexts; // number of contexts prefixed with kAPPLYTOWORLDPREFIX + typedef CUtlRBTree< CritEntry_t, short > Dict_t; + Dict_t m_Lookup; + int m_nNumPrefixedContexts; // number of contexts prefixed with kAPPLYTOWORLDPREFIX bool m_bOverrideOnAppend; }; @@ -457,20 +457,20 @@ namespace ResponseRules return ( index >= 0 && index < ((int)(m_Lookup.Count())) ); } - inline int CriteriaSet::Head() const - { - return m_Lookup.FirstInorder(); - } - - inline int CriteriaSet::Next( int i ) const - { - return m_Lookup.NextInorder(i); - } - - inline const char *CriteriaSet::SymbolToStr( const CritSymbol_t &symbol ) - { - return sm_CriteriaSymbols.String(symbol); - } + inline int CriteriaSet::Head() const + { + return m_Lookup.FirstInorder(); + } + + inline int CriteriaSet::Next( int i ) const + { + return m_Lookup.NextInorder(i); + } + + inline const char *CriteriaSet::SymbolToStr( const CritSymbol_t &symbol ) + { + return sm_CriteriaSymbols.String(symbol); + } } diff --git a/sp/src/public/tier1/strtools.h b/sp/src/public/tier1/strtools.h index d3f1c65ba4..0872539dc3 100644 --- a/sp/src/public/tier1/strtools.h +++ b/sp/src/public/tier1/strtools.h @@ -470,6 +470,16 @@ inline void V_wcscat( INOUT_Z_CAP(cchDest) wchar_t *dest, const wchar_t *src, in V_wcsncat( dest, src, cchDest, COPY_ALL_CHARACTERS ); } +// Reentrant strtok +inline static char* V_strtok_s( char *str, const char *delimiters, char **context ) +{ +#ifdef _MSC_VER + return strtok_s( str, delimiters, context ); +#elif POSIX + return strtok_r( str, delimiters, context ); +#endif +} + //----------------------------------------------------------------------------- // generic unique name helper functions //----------------------------------------------------------------------------- diff --git a/sp/src/responserules/runtime/response_types_internal.h b/sp/src/responserules/runtime/response_types_internal.h index 25b6f2d12e..08f311855b 100644 --- a/sp/src/responserules/runtime/response_types_internal.h +++ b/sp/src/responserules/runtime/response_types_internal.h @@ -366,6 +366,7 @@ namespace ResponseRules I Insert( const char *pName, const T &element ) { + extern const char *ResponseCopyString( const char *in ); char const *pString = ResponseCopyString( pName ); unsigned int hash = RR_HASH( pString ); m_ReverseMap.Insert( hash, pString ); @@ -374,6 +375,7 @@ namespace ResponseRules I Insert( const char *pName ) { + extern const char *ResponseCopyString( const char *in ); char const *pString = ResponseCopyString( pName ); unsigned int hash = RR_HASH( pString ); m_ReverseMap.Insert( hash, pString ); @@ -388,7 +390,7 @@ namespace ResponseRules const char *GetElementName( I i ) { - int k = Key( i ); + int k = this->Key( i ); int slot = m_ReverseMap.Find( k ); if ( slot == m_ReverseMap.InvalidIndex() ) return ""; @@ -397,7 +399,7 @@ namespace ResponseRules const char *GetElementName( I i ) const { - int k = Key( i ); + int k = this->Key( i ); int slot = m_ReverseMap.Find( k ); if ( slot == m_ReverseMap.InvalidIndex() ) return ""; diff --git a/sp/src/tier1/convar.cpp b/sp/src/tier1/convar.cpp index fc27eb74e0..9d60652073 100644 --- a/sp/src/tier1/convar.cpp +++ b/sp/src/tier1/convar.cpp @@ -594,7 +594,7 @@ void ConCommand::Dispatch( const CCommand &command ) } // Command without callback!!! - AssertMsg( 0, ( "Encountered ConCommand '%s' without a callback!\n", GetName() ) ); + AssertMsg( 0, "Encountered ConCommand '%s' without a callback!\n", GetName() ); }