From ecdf50c48cd31dec4dbdb7fea2d0780e7f0dd8ec Mon Sep 17 00:00:00 2001 From: Peter Covington Date: Sun, 6 Oct 2019 02:16:33 -0400 Subject: [PATCH] Upgraded AI Response System to Alien Swarm + Mapbase combo -Fixed CBaseMultiplayerPlayer leaking expressers --- .../scripts/talker/player/humans.txt | 12 +- src/game/client/client_base.vpc | 3 +- src/game/server/AI_Criteria.cpp | 481 +-- src/game/server/AI_Criteria.h | 226 +- src/game/server/AI_ResponseSystem.cpp | 3076 ++--------------- src/game/server/AI_ResponseSystem.h | 27 +- src/game/server/ai_basenpc.h | 1 - src/game/server/ai_behavior_lead.h | 3 +- src/game/server/ai_expresserfollowup.cpp | 464 +++ src/game/server/ai_playerally.cpp | 25 +- src/game/server/ai_speech.cpp | 830 +++-- src/game/server/ai_speech.h | 336 +- src/game/server/ai_speechconcept.cpp | 28 + src/game/server/ai_speechconcept.h | 45 + src/game/server/ai_speechqueue.cpp | 479 +++ src/game/server/ai_speechqueue.h | 239 ++ src/game/server/baseentity.cpp | 125 +- src/game/server/baseentity.h | 11 +- src/game/server/baseflex.h | 1 - src/game/server/basemultiplayerplayer.cpp | 7 +- src/game/server/basemultiplayerplayer.h | 2 +- src/game/server/bms/npc_basecollegue.cpp | 6 +- src/game/server/hl1/hl1_npc_scientist.cpp | 7 +- src/game/server/hl1/hl1_npc_talker.h | 4 +- src/game/server/hl2/ai_behavior_actbusy.cpp | 2 +- src/game/server/hl2/env_speaker.h | 4 +- src/game/server/peter/laz_player.cpp | 3 +- src/game/server/physconstraint.cpp | 4 +- src/game/server/physics_prop_ragdoll.cpp | 4 +- src/game/server/physics_prop_ragdoll.h | 2 +- src/game/server/sceneentity.cpp | 43 +- src/game/server/sceneentity.h | 2 +- src/game/server/server_base.vpc | 7 +- src/game/shared/multiplay_gamerules.h | 2 +- src/lib/public/responserules.lib | Bin 0 -> 2927900 bytes src/public/datamap.h | 8 + .../responserules/response_host_interface.h | 61 + src/public/responserules/response_types.h | 437 +++ src/public/responserules/rr_speechconcept.h | 57 + src/public/tier0/basetypes.h | 64 + src/public/tier0/platform.h | 23 - src/public/tier1/generichash.h | 6 + src/{game/shared => public/tier1}/interval.h | 0 src/responserules/runtime/criteriaset.cpp | 477 +++ src/responserules/runtime/response_rules.vpc | 41 + src/responserules/runtime/response_system.cpp | 2749 +++++++++++++++ src/responserules/runtime/response_system.h | 297 ++ src/responserules/runtime/response_types.cpp | 267 ++ .../runtime/response_types_internal.cpp | 120 + .../runtime/response_types_internal.h | 542 +++ src/responserules/runtime/rr_convars.cpp | 14 + src/responserules/runtime/rr_response.cpp | 330 ++ .../runtime/rr_speechconcept.cpp | 73 + src/responserules/runtime/rrbase.h | 59 + src/responserules/runtime/rrrlib.cpp | 13 + src/responserules/runtime/stdafx.cpp | 11 + src/{game/shared => tier1}/interval.cpp | 0 src/tier1/tier1.vpc | 1 + src/vpc_scripts/groups.vgc | 4 + src/vpc_scripts/projects.vgc | 5 + 60 files changed, 8343 insertions(+), 3827 deletions(-) create mode 100644 src/game/server/ai_expresserfollowup.cpp create mode 100644 src/game/server/ai_speechconcept.cpp create mode 100644 src/game/server/ai_speechconcept.h create mode 100644 src/game/server/ai_speechqueue.cpp create mode 100644 src/game/server/ai_speechqueue.h create mode 100644 src/lib/public/responserules.lib create mode 100644 src/public/responserules/response_host_interface.h create mode 100644 src/public/responserules/response_types.h create mode 100644 src/public/responserules/rr_speechconcept.h rename src/{game/shared => public/tier1}/interval.h (100%) create mode 100644 src/responserules/runtime/criteriaset.cpp create mode 100644 src/responserules/runtime/response_rules.vpc create mode 100644 src/responserules/runtime/response_system.cpp create mode 100644 src/responserules/runtime/response_system.h create mode 100644 src/responserules/runtime/response_types.cpp create mode 100644 src/responserules/runtime/response_types_internal.cpp create mode 100644 src/responserules/runtime/response_types_internal.h create mode 100644 src/responserules/runtime/rr_convars.cpp create mode 100644 src/responserules/runtime/rr_response.cpp create mode 100644 src/responserules/runtime/rr_speechconcept.cpp create mode 100644 src/responserules/runtime/rrbase.h create mode 100644 src/responserules/runtime/rrrlib.cpp create mode 100644 src/responserules/runtime/stdafx.cpp rename src/{game/shared => tier1}/interval.cpp (100%) diff --git a/game/spp_shared/content/hl2epX_extra/scripts/talker/player/humans.txt b/game/spp_shared/content/hl2epX_extra/scripts/talker/player/humans.txt index 05309315a..670dda644 100644 --- a/game/spp_shared/content/hl2epX_extra/scripts/talker/player/humans.txt +++ b/game/spp_shared/content/hl2epX_extra/scripts/talker/player/humans.txt @@ -480,13 +480,13 @@ rule PlayerCitizenStartCombatTurretCeiling response PlayerResponseFollow { - scene "scenes/npc/$gender01/squad_away03.vcd" weight 4 - scene "scenes/npc/$gender01/squad_follow02.vcd" - scene "scenes/npc/$gender01/squad_follow03.vcd" - scene "scenes/npc/$gender01/squad_away01.vcd" weight 3 - scene "scenes/npc/$gender01/squad_away02.vcd" + scene "scenes/npc/$gender01/squad_away03.vcd" weight 4 then any TLK_PLAYER_LEAD foo:0 0.5 + scene "scenes/npc/$gender01/squad_follow02.vcd" then any TLK_PLAYER_LEAD foo:0 0.5 + scene "scenes/npc/$gender01/squad_follow03.vcd" then any TLK_PLAYER_LEAD foo:0 0.5 + scene "scenes/npc/$gender01/squad_away01.vcd" weight 3 then any TLK_PLAYER_LEAD foo:0 0.5 + scene "scenes/npc/$gender01/squad_away02.vcd" then any TLK_PLAYER_LEAD foo:0 0.5 //Trav|Edt - add more Follow scenes - scene "scenes/npc/$gender01/overhere01.vcd" + scene "scenes/npc/$gender01/overhere01.vcd" then any TLK_PLAYER_LEAD foo:0 0.5 } rule PlayerFollow diff --git a/src/game/client/client_base.vpc b/src/game/client/client_base.vpc index 387247831..a5456862e 100644 --- a/src/game/client/client_base.vpc +++ b/src/game/client/client_base.vpc @@ -672,7 +672,6 @@ $Project "$SRCDIR\public\dt_utlvector_recv.cpp" \ "$SRCDIR\public\filesystem_helpers.cpp" \ "$SRCDIR\public\interpolatortypes.cpp" \ - "$SRCDIR\game\shared\interval.cpp" \ "$SRCDIR\common\language.cpp" \ "$SRCDIR\public\networkvar.cpp" \ "$SRCDIR\common\randoverride.cpp" \ @@ -1245,6 +1244,7 @@ $Project $File "$SRCDIR\public\vgui_controls\WizardSubPanel.h" $File "$SRCDIR\public\worldsize.h" $File "$SRCDIR\public\zip_uncompressed.h" + $File "$SRCDIR\public\tier1\interval.h" //Haptics $File "$SRCDIR\public\haptics\ihaptics.h" [$WIN32] $File "$SRCDIR\public\haptics\haptic_utils.h" [$WIN32] @@ -1301,7 +1301,6 @@ $Project $File "$SRCDIR\game\shared\igamesystem.h" $File "$SRCDIR\game\shared\imovehelper.h" $File "$SRCDIR\game\shared\in_buttons.h" - $File "$SRCDIR\game\shared\interval.h" $File "$SRCDIR\game\shared\iplayeranimstate.h" $File "$SRCDIR\game\shared\ipredictionsystem.h" $File "$SRCDIR\game\shared\itempents.h" diff --git a/src/game/server/AI_Criteria.cpp b/src/game/server/AI_Criteria.cpp index 128e9d324..31a5b1eff 100644 --- a/src/game/server/AI_Criteria.cpp +++ b/src/game/server/AI_Criteria.cpp @@ -1,174 +1,24 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ // -//=============================================================================// +//===========================================================================// #include "cbase.h" -#include "AI_Criteria.h" +#include "ai_criteria.h" + +#ifdef GAME_DLL #include "ai_speech.h" -#include -#include "engine/IEngineSound.h" +#endif + +#include +#include "engine/ienginesound.h" // memdbgon must be the last include file in a .cpp file!!! #include -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -AI_CriteriaSet::AI_CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ) -{ -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : src - -//----------------------------------------------------------------------------- -AI_CriteriaSet::AI_CriteriaSet( const AI_CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ) -{ - // Use fast Copy CUtlRBTree CopyFrom. WARNING: It only handles POD. - m_Lookup.CopyFrom( src.m_Lookup ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -AI_CriteriaSet::~AI_CriteriaSet() -{ -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *criteria - -// "" - -// 1.0f - -//----------------------------------------------------------------------------- -void AI_CriteriaSet::AppendCriteria( const char *criteria, const char *value /*= ""*/, float weight /*= 1.0f*/ ) -{ - // Note: value pointer may come from an entry inside m_Lookup! - // that value string must be copied out before any modification - // to the m_Lookup struct which could make the pointer invalid - int idx = FindCriterionIndex( criteria ); - if ( idx == -1 ) - { - CritEntry_t entry; - entry.criterianame = criteria; - MEM_ALLOC_CREDIT(); - entry.SetValue(value); - entry.weight = weight; - m_Lookup.Insert( entry ); - } - else - { - CritEntry_t *entry = &m_Lookup[ idx ]; - entry->SetValue( value ); - entry->weight = weight; - } -} - - -//----------------------------------------------------------------------------- -// Removes criteria in a set -//----------------------------------------------------------------------------- -void AI_CriteriaSet::RemoveCriteria( const char *criteria ) -{ - int idx = FindCriterionIndex( criteria ); - if ( idx == -1 ) - return; - - m_Lookup.RemoveAt( idx ); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Output : int -//----------------------------------------------------------------------------- -int AI_CriteriaSet::GetCount() const -{ - return m_Lookup.Count(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *name - -// Output : int -//----------------------------------------------------------------------------- -int AI_CriteriaSet::FindCriterionIndex( const char *name ) const -{ - CritEntry_t search; - search.criterianame = name; - int idx = m_Lookup.Find( search ); - if ( idx == m_Lookup.InvalidIndex() ) - return -1; - - return idx; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : index - -// Output : char const -//----------------------------------------------------------------------------- -const char *AI_CriteriaSet::GetName( int index ) const -{ - static char namebuf[ 128 ]; - if ( index < 0 || index >= (int)m_Lookup.Count() ) - return ""; - - const CritEntry_t *entry = &m_Lookup[ index ]; - Q_strncpy( namebuf, entry->criterianame.String(), sizeof( namebuf ) ); - return namebuf; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : index - -// Output : char const -//----------------------------------------------------------------------------- -const char *AI_CriteriaSet::GetValue( int index ) const -{ - if ( index < 0 || index >= (int)m_Lookup.Count() ) - return ""; - - const CritEntry_t *entry = &m_Lookup[ index ]; - return entry->value ? entry->value : ""; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : index - -// Output : float -//----------------------------------------------------------------------------- -float AI_CriteriaSet::GetWeight( int index ) const -{ - if ( index < 0 || index >= (int)m_Lookup.Count() ) - return 1.0f; - - const CritEntry_t *entry = &m_Lookup[ index ]; - return entry->weight; -} -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void AI_CriteriaSet::Describe() -{ - for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) - { - CritEntry_t *entry = &m_Lookup[ i ]; - - if ( entry->weight != 1.0f ) - { - DevMsg( " %20s = '%s' (weight %f)\n", entry->criterianame.String(), entry->value ? entry->value : "", entry->weight ); - } - else - { - DevMsg( " %20s = '%s'\n", entry->criterianame.String(), entry->value ? entry->value : "" ); - } - } -} BEGIN_SIMPLE_DATADESC( AI_ResponseParams ) DEFINE_FIELD( flags, FIELD_SHORT ), @@ -186,316 +36,3 @@ BEGIN_SIMPLE_DATADESC( AI_Response ) DEFINE_EMBEDDED( m_Params ), END_DATADESC() -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -AI_Response::AI_Response() -{ - m_Type = RESPONSE_NONE; - m_szResponseName[0] = 0; - m_szMatchingRule[0] = 0; - - m_pCriteria = NULL; - m_bApplyContextToWorld = false; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -AI_Response::AI_Response( const AI_Response &from ) -{ - m_pCriteria = NULL; - *this = from; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -AI_Response::~AI_Response() -{ - delete m_pCriteria; - m_pCriteria = NULL; -} - -//----------------------------------------------------------------------------- -AI_Response &AI_Response::operator=( const AI_Response &from ) -{ - Assert( (void*)(&m_Type) == (void*)this ); - - if (this == &from) - return *this; - - m_Type = from.m_Type; - - V_strcpy_safe( m_szResponseName, from.m_szResponseName ); - V_strcpy_safe( m_szMatchingRule, from.m_szMatchingRule ); - - delete m_pCriteria; - m_pCriteria = NULL; - - // Copy criteria. - if (from.m_pCriteria) - m_pCriteria = new AI_CriteriaSet(*from.m_pCriteria); - - m_Params = from.m_Params; - - m_szContext = from.m_szContext; - m_bApplyContextToWorld = from.m_bApplyContextToWorld; - - return *this; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *response - -// *criteria - -//----------------------------------------------------------------------------- -void AI_Response::Init( ResponseType_t type, const char *responseName, const AI_CriteriaSet& criteria, - const AI_ResponseParams& responseparams, const char *ruleName, const char *applyContext, - bool bApplyContextToWorld ) -{ - m_Type = type; - - V_strcpy_safe( m_szResponseName, responseName ); - V_strcpy_safe( m_szMatchingRule, ruleName ? ruleName : "NULL" ); - - // Copy underlying criteria - Assert( !m_pCriteria ); - m_pCriteria = new AI_CriteriaSet( criteria ); - - m_Params = responseparams; - - m_szContext = applyContext; - m_bApplyContextToWorld = bApplyContextToWorld; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void AI_Response::Describe() -{ - if ( m_pCriteria ) - { - DevMsg( "Search criteria:\n" ); - m_pCriteria->Describe(); - } - if ( m_szMatchingRule[ 0 ] ) - DevMsg( "Matched rule '%s', ", m_szMatchingRule ); - if ( m_szContext.Length() ) - DevMsg( "Contexts to set '%s' on %s, ", m_szContext.Get(), m_bApplyContextToWorld ? "world" : "speaker" ); - - DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -const char * AI_Response::GetNamePtr() const -{ - return m_szResponseName; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -const char * AI_Response::GetResponsePtr() const -{ - return m_szResponseName; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : type - -// Output : char const -//----------------------------------------------------------------------------- -const char *AI_Response::DescribeResponse( ResponseType_t type ) -{ - if ( (int)type < 0 || (int)type >= NUM_RESPONSES ) - { - Assert( 0 ); - return "???AI_Response bogus index"; - } - - switch( type ) - { - case RESPONSE_NONE: return "RESPONSE_NONE"; - case RESPONSE_SPEAK: return "RESPONSE_SPEAK"; - case RESPONSE_SENTENCE: return "RESPONSE_SENTENCE"; - case RESPONSE_SCENE: return "RESPONSE_SCENE"; - case RESPONSE_RESPONSE: return "RESPONSE_RESPONSE"; - case RESPONSE_PRINT: return "RESPONSE_PRINT"; - } - - Assert( 0 ); - return "RESPONSE_NONE"; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : const AI_CriteriaSet -//----------------------------------------------------------------------------- -const AI_CriteriaSet *AI_Response::GetCriteria() -{ - return m_pCriteria; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void AI_Response::Release() -{ - delete this; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : soundlevel_t -//----------------------------------------------------------------------------- -soundlevel_t AI_Response::GetSoundLevel() const -{ - if ( m_Params.flags & AI_ResponseParams::RG_SOUNDLEVEL ) - { - return (soundlevel_t)m_Params.soundlevel; - } - - return SNDLVL_TALKING; -} - -float AI_Response::GetRespeakDelay( void ) const -{ - if ( m_Params.flags & AI_ResponseParams::RG_RESPEAKDELAY ) - { - interval_t temp; - m_Params.respeakdelay.ToInterval( temp ); - return RandomInterval( temp ); - } - - return 0.0f; -} - -float AI_Response::GetWeaponDelay( void ) const -{ - if ( m_Params.flags & AI_ResponseParams::RG_WEAPONDELAY ) - { - interval_t temp; - m_Params.weapondelay.ToInterval( temp ); - return RandomInterval( temp ); - } - - return 0.0f; -} - -bool AI_Response::GetSpeakOnce( void ) const -{ - if ( m_Params.flags & AI_ResponseParams::RG_SPEAKONCE ) - { - return true; - } - - return false; -} - -bool AI_Response::ShouldntUseScene( void ) const -{ - return ( m_Params.flags & AI_ResponseParams::RG_DONT_USE_SCENE ) != 0; -} - -bool AI_Response::ShouldBreakOnNonIdle( void ) const -{ - return ( m_Params.flags & AI_ResponseParams::RG_STOP_ON_NONIDLE ) != 0; -} - -int AI_Response::GetOdds( void ) const -{ - if ( m_Params.flags & AI_ResponseParams::RG_ODDS ) - { - return m_Params.odds; - } - return 100; -} - -float AI_Response::GetDelay() const -{ - if ( m_Params.flags & AI_ResponseParams::RG_DELAYAFTERSPEAK ) - { - interval_t temp; - m_Params.delay.ToInterval( temp ); - return RandomInterval( temp ); - } - return 0.0f; -} - -float AI_Response::GetPreDelay() const -{ - if ( m_Params.flags & AI_ResponseParams::RG_DELAYBEFORESPEAK ) - { - interval_t temp; - m_Params.predelay.ToInterval( temp ); - return RandomInterval( temp ); - } - return 0.0f; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets context string -// Output : void -//----------------------------------------------------------------------------- -void AI_Response::SetContext( const char *context ) -{ - m_szContext = context; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *raw - -// *key - -// keylen - -// *value - -// valuelen - -// *duration - -// Output : static bool -//----------------------------------------------------------------------------- -const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration ) -{ - char *colon1 = Q_strstr( raw, ":" ); - if ( !colon1 ) - { - DevMsg( "SplitContext: warning, ignoring context '%s', missing colon separator!\n", raw ); - *key = *value = 0; - return NULL; - } - - int len = colon1 - raw; - Q_strncpy( key, raw, MIN( len + 1, keylen ) ); - key[ MIN( len, keylen - 1 ) ] = 0; - - bool last = false; - char *end = Q_strstr( colon1 + 1, "," ); - if ( !end ) - { - int remaining = Q_strlen( colon1 + 1 ); - end = colon1 + 1 + remaining; - last = true; - } - - char *colon2 = Q_strstr( colon1 + 1, ":" ); - if ( colon2 && ( colon2 < end ) ) - { - if ( duration ) - *duration = atof( colon2 + 1 ); - - len = MIN( colon2 - ( colon1 + 1 ), valuelen - 1 ); - Q_strncpy( value, colon1 + 1, len + 1 ); - value[ len ] = 0; - } - else - { - if ( duration ) - *duration = 0.0; - - len = MIN( end - ( colon1 + 1 ), valuelen - 1 ); - Q_strncpy( value, colon1 + 1, len + 1 ); - value[ len ] = 0; - } - - return last ? NULL : end + 1; -} diff --git a/src/game/server/AI_Criteria.h b/src/game/server/AI_Criteria.h index f10c2d05b..b5d2c4fd6 100644 --- a/src/game/server/AI_Criteria.h +++ b/src/game/server/AI_Criteria.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -12,228 +12,30 @@ #include "tier1/utlrbtree.h" #include "tier1/utlsymbol.h" -#include "interval.h" +#include "tier1/interval.h" #include "mathlib/compressed_vector.h" +#include "../../public/responserules/response_types.h" -extern const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration ); +using ResponseRules::ResponseType_t; -class AI_CriteriaSet -{ -public: - AI_CriteriaSet(); - AI_CriteriaSet( const AI_CriteriaSet& src ); - ~AI_CriteriaSet(); - - void AppendCriteria( const char *criteria, const char *value = "", float weight = 1.0f ); - void RemoveCriteria( const char *criteria ); - - void Describe(); - - int GetCount() const; - int FindCriterionIndex( const char *name ) const; - - const char *GetName( int index ) const; - const char *GetValue( int index ) const; - float GetWeight( int index ) const; - -private: - - 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 ); - } - - CritEntry_t& operator=( const CritEntry_t& src ) - { - if ( this == &src ) - return *this; - - criterianame = src.criterianame; - weight = src.weight; - SetValue( src.value ); - - return *this; - } - - static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs ) - { - return Q_stricmp( lhs.criterianame.String(), rhs.criterianame.String() ) < 0 ? true : false; - } - - void SetValue( char const *str ) - { - if ( !str ) - { - value[ 0 ] = 0; - } - else - { - Q_strncpy( value, str, sizeof( value ) ); - } - } - - // We use CUtlRBTree CopyFrom() in ctor, so CritEntry_t must be POD. If you add - // CUtlString or something then you must change AI_CriteriaSet copy ctor. - CUtlSymbol criterianame; - char value[ 64 ]; - float weight; - }; - - CUtlRBTree< CritEntry_t, short > m_Lookup; -}; - -#pragma pack(1) -template -struct response_interval_t -{ - T start; - T range; - - interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; } - void FromInterval( const interval_t &from ) { start = from.start; range = from.range; } - float Random() const { interval_t temp = { start, range }; return RandomInterval( temp ); } -}; - -typedef response_interval_t responseparams_interval_t; - -struct AI_ResponseParams -{ - DECLARE_SIMPLE_DATADESC(); +extern const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration, const char *entireContext ); - enum - { - RG_DELAYAFTERSPEAK = (1<<0), - RG_SPEAKONCE = (1<<1), - RG_ODDS = (1<<2), - RG_RESPEAKDELAY = (1<<3), - RG_SOUNDLEVEL = (1<<4), - RG_DONT_USE_SCENE = (1<<5), - RG_STOP_ON_NONIDLE = (1<<6), - RG_WEAPONDELAY = (1<<7), - RG_DELAYBEFORESPEAK = (1<<8), - }; - - AI_ResponseParams() - { - flags = 0; - odds = 100; - delay.start = 0; - delay.range = 0; - respeakdelay.start = 0; - respeakdelay.range = 0; - weapondelay.start = 0; - weapondelay.range = 0; - soundlevel = 0; - predelay.start = 0; - predelay.range = 0; - } - - responseparams_interval_t delay; //4 - responseparams_interval_t respeakdelay; //8 - responseparams_interval_t weapondelay; //12 +#ifndef AI_CriteriaSet +#define AI_CriteriaSet ResponseRules::CriteriaSet +#endif - short odds; //14 +typedef ResponseRules::ResponseParams AI_ResponseParams ; +typedef ResponseRules::CRR_Response AI_Response; - short flags; //16 - byte soundlevel; //17 - responseparams_interval_t predelay; //21 -}; -#pragma pack() -//----------------------------------------------------------------------------- -// Purpose: Generic container for a response to a match to a criteria set -// This is what searching for a response returns -//----------------------------------------------------------------------------- -enum ResponseType_t +/* +// An AI response that is dynamically new'ed up and returned from SpeakFindResponse. +class AI_ResponseReturnValue : AI_Response { - RESPONSE_NONE = 0, - RESPONSE_SPEAK, - RESPONSE_SENTENCE, - RESPONSE_SCENE, - RESPONSE_RESPONSE, // A reference to another response by name - RESPONSE_PRINT, - - NUM_RESPONSES, -}; - -class AI_Response -{ -public: - DECLARE_SIMPLE_DATADESC(); - - AI_Response(); - AI_Response( const AI_Response &from ); - ~AI_Response(); - AI_Response &operator=( const AI_Response &from ); - - void Release(); - - const char * GetNamePtr() const; - const char * GetResponsePtr() const; - const AI_ResponseParams *GetParams() const { return &m_Params; } - ResponseType_t GetType() const { return (ResponseType_t)m_Type; } - soundlevel_t GetSoundLevel() const; - float GetRespeakDelay() const; - float GetWeaponDelay() const; - bool GetSpeakOnce() const; - bool ShouldntUseScene( ) const; - bool ShouldBreakOnNonIdle( void ) const; - int GetOdds() const; - float GetDelay() const; - float GetPreDelay() const; - - void SetContext( const char *context ); - const char * GetContext( void ) const { return m_szContext.Length() ? m_szContext.Get() : NULL; } - - bool IsApplyContextToWorld( void ) { return m_bApplyContextToWorld; } - - void Describe(); - - const AI_CriteriaSet* GetCriteria(); - - void Init( ResponseType_t type, - const char *responseName, - const AI_CriteriaSet& criteria, - const AI_ResponseParams& responseparams, - const char *matchingRule, - const char *applyContext, - bool bApplyContextToWorld ); - - static const char *DescribeResponse( ResponseType_t type ); - - enum - { - MAX_RESPONSE_NAME = 64, - MAX_RULE_NAME = 64 - }; - - -private: - byte m_Type; - char m_szResponseName[ MAX_RESPONSE_NAME ]; - char m_szMatchingRule[ MAX_RULE_NAME ]; - - // The initial criteria to which we are responsive - AI_CriteriaSet *m_pCriteria; - - AI_ResponseParams m_Params; - CUtlString m_szContext; - bool m_bApplyContextToWorld; }; +*/ #endif // AI_CRITERIA_H diff --git a/src/game/server/AI_ResponseSystem.cpp b/src/game/server/AI_ResponseSystem.cpp index 8a6b0db5b..0d791c39b 100644 --- a/src/game/server/AI_ResponseSystem.cpp +++ b/src/game/server/AI_ResponseSystem.cpp @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -6,732 +6,192 @@ #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 #include "ai_speech.h" +#endif #include "tier0/icommandline.h" #include -#include "sceneentity.h" #include "isaverestore.h" #include "utlbuffer.h" #include "stringpool.h" #include "fmtstr.h" #include "multiplay_gamerules.h" +#include "characterset.h" +#include "responserules/response_host_interface.h" +#include "../../responserules/runtime/response_types_internal.h" + +#include "scenefilecache/ISceneFileCache.h" +#include "tier1/generichash.h" + +#ifdef GAME_DLL +#include "sceneentity.h" +#endif + +#include "networkstringtabledefs.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -ConVar rr_debugresponses( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose matching output (1 for simple, 2 for rule scoring). If set to 3, it will only show response success/failure for npc_selected NPCs." ); -ConVar rr_debugrule( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); -ConVar rr_dumpresponses( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +using namespace ResponseRules; -static CUtlSymbolTable g_RS; +extern ConVar rr_debugresponses; // ( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose matching output (1 for simple, 2 for rule scoring, 3 for noisy). If set to 4, it will only show response success/failure for npc_selected NPCs." ); +extern ConVar rr_debugrule; // ( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); +extern ConVar rr_dumpresponses; // ( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +extern ConVar rr_debugresponseconcept; // ( "rr_debugresponseconcept", "", FCVAR_NONE, "If set, rr_debugresponses will print only responses testing for the specified concept" ); -inline static char *CopyString( const char *in ) -{ - if ( !in ) - return NULL; +extern ISceneFileCache *scenefilecache; +extern INetworkStringTable *g_pStringTableClientSideChoreoScenes; - int len = Q_strlen( in ); - char *out = new char[ len + 1 ]; - Q_memcpy( out, in, len ); - out[ len ] = 0; - return out; -} +static characterset_t g_BreakSetIncludingColons; -#pragma pack(1) -class Matcher +// Simple class to initialize breakset +class CBreakInit { public: - Matcher() - { - valid = false; - isnumeric = false; - notequal = false; - usemin = false; - minequals = false; - usemax = false; - maxequals = false; - maxval = 0.0f; - minval = 0.0f; - - token = UTL_INVAL_SYMBOL; - rawtoken = UTL_INVAL_SYMBOL; - } - - void Describe( void ) - { - if ( !valid ) - { - DevMsg( " invalid!\n" ); - return; - } - char sz[ 128 ]; - - sz[ 0] = 0; - int minmaxcount = 0; - if ( usemin ) - { - Q_snprintf( sz, sizeof( sz ), ">%s%.3f", minequals ? "=" : "", minval ); - minmaxcount++; - } - if ( usemax ) - { - char sz2[ 128 ]; - Q_snprintf( sz2, sizeof( sz2 ), "<%s%.3f", maxequals ? "=" : "", maxval ); - - if ( minmaxcount > 0 ) - { - Q_strncat( sz, " and ", sizeof( sz ), COPY_ALL_CHARACTERS ); - } - Q_strncat( sz, sz2, sizeof( sz ), COPY_ALL_CHARACTERS ); - minmaxcount++; - } - - if ( minmaxcount >= 1 ) - { - DevMsg( " matcher: %s\n", sz ); - return; - } - - if ( notequal ) - { - DevMsg( " matcher: !=%s\n", GetToken() ); - return; - } - - DevMsg( " matcher: ==%s\n", GetToken() ); - } - - float maxval; - float minval; - - bool valid : 1; //1 - bool isnumeric : 1; //2 - bool notequal : 1; //3 - bool usemin : 1; //4 - bool minequals : 1; //5 - bool usemax : 1; //6 - bool maxequals : 1; //7 - - void SetToken( char const *s ) - { - token = g_RS.AddString( s ); - } - - char const *GetToken() - { - if ( token.IsValid() ) - { - return g_RS.String( token ); - } - return ""; - } - void SetRaw( char const *raw ) - { - rawtoken = g_RS.AddString( raw ); - } - char const *GetRaw() + CBreakInit() { - if ( rawtoken.IsValid() ) - { - return g_RS.String( rawtoken ); - } - return ""; + CharacterSetBuild( &g_BreakSetIncludingColons, "{}()':" ); } +} g_BreakInit; -private: - CUtlSymbol token; - CUtlSymbol rawtoken; -}; - -struct Response +inline char rr_tolower( char c ) { - DECLARE_SIMPLE_DATADESC(); - - Response() - { - type = RESPONSE_NONE; - value = NULL; - weight.SetFloat( 1.0f ); - depletioncount = 0; - first = false; - last = false; - } - - Response( const Response& src ) - { - weight = src.weight; - type = src.type; - value = CopyString( src.value ); - depletioncount = src.depletioncount; - first = src.first; - last = src.last; - } - - Response& operator =( const Response& src ) - { - if ( this == &src ) - return *this; - weight = src.weight; - type = src.type; - value = CopyString( src.value ); - depletioncount = src.depletioncount; - first = src.first; - last = src.last; - return *this; - } - - ~Response() - { - delete[] value; - } - - ResponseType_t GetType() { return (ResponseType_t)type; } - - char *value; // fixed up value spot // 4 - float16 weight; // 6 - - byte depletioncount; // 7 - byte type : 6; // 8 - byte first : 1; // - byte last : 1; // -}; - -struct ResponseGroup + if ( c >= 'A' && c <= 'Z' ) + return c - 'A' + 'a'; + return c; +} +// BUG BUG: Note that this function doesn't check for data overruns!!! +// Also, this function lowercases the token as it parses!!! +inline const char *RR_Parse(const char *data, char *token ) { - DECLARE_SIMPLE_DATADESC(); - - ResponseGroup() - { - // By default visit all nodes before repeating - m_bSequential = false; - m_bNoRepeat = false; - m_bEnabled = true; - m_nCurrentIndex = 0; - m_bDepleteBeforeRepeat = true; - m_nDepletionCount = 1; - m_bHasFirst = false; - m_bHasLast = false; - } - - ResponseGroup( const ResponseGroup& src ) - { - int c = src.group.Count(); - for ( int i = 0; i < c; i++ ) - { - group.AddToTail( src.group[ i ] ); - } - - rp = src.rp; - m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; - m_nDepletionCount = src.m_nDepletionCount; - m_bHasFirst = src.m_bHasFirst; - m_bHasLast = src.m_bHasLast; - m_bSequential = src.m_bSequential; - m_bNoRepeat = src.m_bNoRepeat; - m_bEnabled = src.m_bEnabled; - m_nCurrentIndex = src.m_nCurrentIndex; - } - - ResponseGroup& operator=( const ResponseGroup& src ) - { - if ( this == &src ) - return *this; - int c = src.group.Count(); - for ( int i = 0; i < c; i++ ) - { - group.AddToTail( src.group[ i ] ); - } - - rp = src.rp; - m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; - m_nDepletionCount = src.m_nDepletionCount; - m_bHasFirst = src.m_bHasFirst; - m_bHasLast = src.m_bHasLast; - m_bSequential = src.m_bSequential; - m_bNoRepeat = src.m_bNoRepeat; - m_bEnabled = src.m_bEnabled; - m_nCurrentIndex = src.m_nCurrentIndex; - return *this; - } - - bool HasUndepletedChoices() const - { - if ( !m_bDepleteBeforeRepeat ) - return true; - - int c = group.Count(); - for ( int i = 0; i < c; i++ ) - { - if ( group[ i ].depletioncount != m_nDepletionCount ) - return true; - } - - return false; - } - - void MarkResponseUsed( int idx ) - { - if ( !m_bDepleteBeforeRepeat ) - return; - - if ( idx < 0 || idx >= group.Count() ) - { - Assert( 0 ); - return; - } + unsigned char c; + int len; + characterset_t *breaks = &g_BreakSetIncludingColons; + len = 0; + token[0] = 0; - group[ idx ].depletioncount = m_nDepletionCount; - } + if (!data) + return NULL; - void ResetDepletionCount() + // skip whitespace +skipwhite: + while ( (c = *data) <= ' ') { - if ( !m_bDepleteBeforeRepeat ) - return; - ++m_nDepletionCount; + if (c == 0) + return NULL; // end of file; + data++; } - void Reset() + // skip // comments + if (c=='/' && data[1] == '/') { - ResetDepletionCount(); - SetEnabled( true ); - SetCurrentIndex( 0 ); - m_nDepletionCount = 1; - - for ( int i = 0; i < group.Count(); ++i ) - { - group[ i ].depletioncount = 0; - } + while (*data && *data != '\n') + data++; + goto skipwhite; } - bool HasUndepletedFirst( int& index ) - { - index = -1; - - if ( !m_bDepleteBeforeRepeat ) - return false; - - int c = group.Count(); - for ( int i = 0; i < c; i++ ) - { - Response *r = &group[ i ]; - - if ( ( r->depletioncount != m_nDepletionCount ) && r->first ) - { - index = i; - return true; - } - } - return false; - } - - bool HasUndepletedLast( int& index ) + // handle quoted strings specially + if (c == '\"') { - index = -1; - - if ( !m_bDepleteBeforeRepeat ) - return false; - - int c = group.Count(); - for ( int i = 0; i < c; i++ ) + data++; + while (1) { - Response *r = &group[ i ]; - - if ( ( r->depletioncount != m_nDepletionCount ) && r->last ) + c = rr_tolower( *data++ ); + if (c=='\"' || !c) { - index = i; - return true; + token[len] = 0; + return data; } + token[len] = c; + len++; } - - return false; - } - - bool ShouldCheckRepeats() const { return m_bDepleteBeforeRepeat; } - int GetDepletionCount() const { return m_nDepletionCount; } - - bool IsSequential() const { return m_bSequential; } - void SetSequential( bool seq ) { m_bSequential = seq; } - - bool IsNoRepeat() const { return m_bNoRepeat; } - void SetNoRepeat( bool norepeat ) { m_bNoRepeat = norepeat; } - - bool IsEnabled() const { return m_bEnabled; } - void SetEnabled( bool enabled ) { m_bEnabled = enabled; } - - int GetCurrentIndex() const { return m_nCurrentIndex; } - void SetCurrentIndex( byte idx ) { m_nCurrentIndex = idx; } - - CUtlVector< Response > group; - - AI_ResponseParams rp; - - bool m_bEnabled; - - byte m_nCurrentIndex; - // Invalidation counter - byte m_nDepletionCount; - - // Use all slots before repeating any - bool m_bDepleteBeforeRepeat : 1; - bool m_bHasFirst : 1; - bool m_bHasLast : 1; - bool m_bSequential : 1; - bool m_bNoRepeat : 1; - -}; - -struct Criteria -{ - Criteria() - { - name = NULL; - value = NULL; - weight.SetFloat( 1.0f ); - required = false; - } - Criteria& operator =(const Criteria& src ) - { - if ( this == &src ) - return *this; - - name = CopyString( src.name ); - value = CopyString( src.value ); - weight = src.weight; - required = src.required; - - matcher = src.matcher; - - int c = src.subcriteria.Count(); - for ( int i = 0; i < c; i++ ) - { - subcriteria.AddToTail( src.subcriteria[ i ] ); - } - - return *this; } - Criteria(const Criteria& src ) - { - name = CopyString( src.name ); - value = CopyString( src.value ); - weight = src.weight; - required = src.required; - - matcher = src.matcher; - int c = src.subcriteria.Count(); - for ( int i = 0; i < c; i++ ) - { - subcriteria.AddToTail( src.subcriteria[ i ] ); - } - } - ~Criteria() + // parse single characters + if ( IN_CHARACTERSET( *breaks, c ) ) { - delete[] name; - delete[] value; + token[len] = c; + len++; + token[len] = 0; + return data+1; } - bool IsSubCriteriaType() const + // parse a regular word + do { - return ( subcriteria.Count() > 0 ) ? true : false; - } - - char *name; - char *value; - float16 weight; - bool required; - - Matcher matcher; + token[len] = rr_tolower( c ); + data++; + len++; + c = rr_tolower( *data ); + if ( IN_CHARACTERSET( *breaks, c ) ) + break; + } while (c>32); - // Indices into sub criteria - CUtlVector< unsigned short > subcriteria; -}; + token[len] = 0; + return data; +} -struct Rule +namespace ResponseRules { - Rule() - { - m_bMatchOnce = false; - m_bEnabled = true; - m_szContext = NULL; - m_bApplyContextToWorld = false; - } - - Rule& operator =( const Rule& src ) - { - if ( this == &src ) - return *this; - - int i; - int c; - - c = src.m_Criteria.Count(); - for ( i = 0; i < c; i++ ) - { - m_Criteria.AddToTail( src.m_Criteria[ i ] ); - } - - c = src.m_Responses.Count(); - for ( i = 0; i < c; i++ ) - { - m_Responses.AddToTail( src.m_Responses[ i ] ); - } - - SetContext( src.m_szContext ); - m_bMatchOnce = src.m_bMatchOnce; - m_bEnabled = src.m_bEnabled; - m_bApplyContextToWorld = src.m_bApplyContextToWorld; - return *this; - } - - Rule( const Rule& src ) - { - int i; - int c; - - c = src.m_Criteria.Count(); - for ( i = 0; i < c; i++ ) - { - m_Criteria.AddToTail( src.m_Criteria[ i ] ); - } - - c = src.m_Responses.Count(); - for ( i = 0; i < c; i++ ) - { - m_Responses.AddToTail( src.m_Responses[ i ] ); - } - - SetContext( src.m_szContext ); - m_bMatchOnce = src.m_bMatchOnce; - m_bEnabled = src.m_bEnabled; - m_bApplyContextToWorld = src.m_bApplyContextToWorld; - } + extern const char *ResponseCopyString( const char *in ); +} - ~Rule() +// Host functions required by the ResponseRules::IEngineEmulator interface +class CResponseRulesToEngineInterface : public ResponseRules::IEngineEmulator +{ + /// Given an input text buffer data pointer, parses a single token into the variable token and returns the new + /// reading position + virtual const char *ParseFile( const char *data, char *token, int maxlen ) { - delete[] m_szContext; + NOTE_UNUSED( maxlen ); + return RR_Parse( data, token ); } - void SetContext( const char *context ) + /// Return a pointer to an IFileSystem we can use to read and process scripts. + virtual IFileSystem *GetFilesystem() { - delete[] m_szContext; - m_szContext = CopyString( context ); + return filesystem; } - const char *GetContext( void ) const { return m_szContext; } - - bool IsEnabled() const { return m_bEnabled; } - void Disable() { m_bEnabled = false; } - bool IsMatchOnce() const { return m_bMatchOnce; } - bool IsApplyContextToWorld() const { return m_bApplyContextToWorld; } - - // Indices into underlying criteria and response dictionaries - CUtlVector< unsigned short > m_Criteria; - CUtlVector< unsigned short> m_Responses; - - char *m_szContext; - bool m_bApplyContextToWorld : 1; - - bool m_bMatchOnce : 1; - bool m_bEnabled : 1; -}; -#pragma pack() - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -abstract_class CResponseSystem : public IResponseSystem -{ -public: - CResponseSystem(); - ~CResponseSystem(); - - // IResponseSystem - virtual bool FindBestResponse( const AI_CriteriaSet& set, AI_Response& response, IResponseFilter *pFilter = NULL ); - virtual void GetAllResponses( CUtlVector *pResponses ); - - virtual void Release() = 0; - - virtual void DumpRules(); - - virtual void Precache(); - - virtual void PrecacheResponses( bool bEnable ) + /// Return a pointer to an instance of an IUniformRandomStream + virtual IUniformRandomStream *GetRandomStream() { - m_bPrecache = bEnable; + return random; } - bool ShouldPrecache() { return m_bPrecache; } - bool IsCustomManagable() { return m_bCustomManagable; } - - void Clear(); - - void DumpDictionary( const char *pszName ); - -protected: - - virtual const char *GetScriptFile( void ) = 0; - void LoadRuleSet( const char *setname ); - - void ResetResponseGroups(); - - float LookForCriteria( const AI_CriteriaSet &criteriaSet, int iCriteria ); - float RecursiveLookForCriteria( const AI_CriteriaSet &criteriaSet, Criteria *pParent ); - -public: - - void CopyRuleFrom( Rule *pSrcRule, int iRule, CResponseSystem *pCustomSystem ); - void CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); - void CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); - void CopyEnumerationsFrom( CResponseSystem *pCustomSystem ); - -//private: - - struct Enumeration - { - float value; - }; - - struct ResponseSearchResult - { - ResponseSearchResult() - { - group = NULL; - action = NULL; - } - - ResponseGroup *group; - Response *action; - }; - - inline bool ParseToken( void ) + /// Return a pointer to a tier0 ICommandLine + virtual ICommandLine *GetCommandLine() { - if ( m_bUnget ) - { - m_bUnget = false; - return true; - } - if ( m_ScriptStack.Count() <= 0 ) - { - Assert( 0 ); - return false; - } - - m_ScriptStack[ 0 ].currenttoken = engine->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); - m_ScriptStack[ 0 ].tokencount++; - return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + return CommandLine(); } - inline void Unget() + /// Emulates the server's UTIL_LoadFileForMe + virtual byte *LoadFileForMe( const char *filename, int *pLength ) { - m_bUnget = true; + return UTIL_LoadFileForMe( filename, pLength ); } - inline bool TokenWaiting( void ) + /// Emulates the server's UTIL_FreeFile + virtual void FreeFile( byte *buffer ) { - if ( m_ScriptStack.Count() <= 0 ) - { - Assert( 0 ); - return false; - } - - const char *p = m_ScriptStack[ 0 ].currenttoken; - - if ( !p ) - { - Error( "AI_ResponseSystem: Unxpected TokenWaiting() with NULL buffer in %p", m_ScriptStack[ 0 ].name ); - return false; - } - - - while ( *p && *p!='\n') - { - // Special handler for // comment blocks - if ( *p == '/' && *(p+1) == '/' ) - return false; - - if ( !isspace( *p ) || isalnum( *p ) ) - return true; - - p++; - } - - return false; + return UTIL_FreeFile( buffer ); } - - void ParseOneResponse( const char *responseGroupName, ResponseGroup& group ); - - void ParseInclude( CStringPool &includedFiles ); - void ParseResponse( void ); - void ParseCriterion( void ); - void ParseRule( void ); - void ParseEnumeration( void ); - - int ParseOneCriterion( const char *criterionName ); - - bool Compare( const char *setValue, Criteria *c, bool verbose = false ); - bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false ); - void ComputeMatcher( Criteria *c, Matcher& matcher ); - void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ); - float LookupEnumeration( const char *name, bool& found ); - - int FindBestMatchingRule( const AI_CriteriaSet& set, bool verbose ); - - float ScoreCriteriaAgainstRule( const AI_CriteriaSet& set, int irule, bool verbose = false ); - float RecursiveScoreSubcriteriaAgainstRule( const AI_CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ); - float ScoreCriteriaAgainstRuleCriteria( const AI_CriteriaSet& set, int icriterion, bool& exclude, bool verbose = false ); - bool GetBestResponse( ResponseSearchResult& result, Rule *rule, bool verbose = false, IResponseFilter *pFilter = NULL ); - bool ResolveResponse( ResponseSearchResult& result, int depth, const char *name, bool verbose = false, IResponseFilter *pFilter = NULL ); - int SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ); - void DescribeResponseGroup( ResponseGroup *group, int selected, int depth ); - void DebugPrint( int depth, const char *fmt, ... ); - - void LoadFromBuffer( const char *scriptfile, const char *buffer, CStringPool &includedFiles ); - - void GetCurrentScript( char *buf, size_t buflen ); - int GetCurrentToken() const; - void SetCurrentScript( const char *script ); - bool IsRootCommand(); - - void PushScript( const char *scriptfile, unsigned char *buffer ); - void PopScript(void); - - void ResponseWarning( const char *fmt, ... ); - - CUtlDict< ResponseGroup, short > m_Responses; - CUtlDict< Criteria, short > m_Criteria; - CUtlDict< Rule, short > m_Rules; - CUtlDict< Enumeration, short > m_Enumerations; - - char token[ 1204 ]; - - bool m_bUnget; - bool m_bPrecache; - bool m_bCustomManagable; - - struct ScriptEntry - { - unsigned char *buffer; - FileNameHandle_t name; - const char *currenttoken; - int tokencount; - }; +}; - CUtlVector< ScriptEntry > m_ScriptStack; +CResponseRulesToEngineInterface g_ResponseRulesEngineWrapper; +IEngineEmulator *IEngineEmulator::s_pSingleton = &g_ResponseRulesEngineWrapper; - friend class CDefaultResponseSystemSaveRestoreBlockHandler; - friend class CResponseSystemSaveRestoreOps; -}; -BEGIN_SIMPLE_DATADESC( Response ) +BEGIN_SIMPLE_DATADESC( ParserResponse ) // DEFINE_FIELD( type, FIELD_INTEGER ), // DEFINE_ARRAY( value, FIELD_CHARACTER ), // DEFINE_FIELD( weight, FIELD_FLOAT ), @@ -740,6 +200,7 @@ BEGIN_SIMPLE_DATADESC( Response ) // DEFINE_FIELD( last, FIELD_BOOLEAN ), END_DATADESC() + BEGIN_SIMPLE_DATADESC( ResponseGroup ) // DEFINE_FIELD( group, FIELD_UTLVECTOR ), // DEFINE_FIELD( rp, FIELD_EMBEDDED ), @@ -750,2109 +211,240 @@ BEGIN_SIMPLE_DATADESC( ResponseGroup ) // DEFINE_FIELD( m_bSequential, FIELD_BOOLEAN ), // DEFINE_FIELD( m_bNoRepeat, FIELD_BOOLEAN ), DEFINE_FIELD( m_bEnabled, FIELD_BOOLEAN ), - DEFINE_FIELD( m_nCurrentIndex, FIELD_CHARACTER ), -END_DATADESC() - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CResponseSystem::CResponseSystem() -{ - token[0] = 0; - m_bUnget = false; - m_bPrecache = true; - m_bCustomManagable = false; -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -CResponseSystem::~CResponseSystem() -{ -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : char const -//----------------------------------------------------------------------------- -void CResponseSystem::GetCurrentScript( char *buf, size_t buflen ) -{ - Assert( buf ); - buf[ 0 ] = 0; - if ( m_ScriptStack.Count() <= 0 ) - return; - - if ( filesystem->String( m_ScriptStack[ 0 ].name, buf, buflen ) ) - { - return; - } - buf[ 0 ] = 0; -} - -void CResponseSystem::PushScript( const char *scriptfile, unsigned char *buffer ) -{ - ScriptEntry e; - e.name = filesystem->FindOrAddFileName( scriptfile ); - e.buffer = buffer; - e.currenttoken = (char *)e.buffer; - e.tokencount = 0; - m_ScriptStack.AddToHead( e ); -} - -void CResponseSystem::PopScript(void) -{ - Assert( m_ScriptStack.Count() >= 1 ); - if ( m_ScriptStack.Count() <= 0 ) - return; - - m_ScriptStack.Remove( 0 ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::Clear() -{ - m_Responses.RemoveAll(); - m_Criteria.RemoveAll(); - m_Rules.RemoveAll(); - m_Enumerations.RemoveAll(); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *name - -// found - -// Output : float -//----------------------------------------------------------------------------- -float CResponseSystem::LookupEnumeration( const char *name, bool& found ) -{ - int idx = m_Enumerations.Find( name ); - if ( idx == m_Enumerations.InvalidIndex() ) - { - found = false; - return 0.0f; - } - - - found = true; - return m_Enumerations[ idx ].value; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : matcher - -//----------------------------------------------------------------------------- -void CResponseSystem::ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ) -{ - if ( rawtoken[0] != '[' ) - { - Q_strncpy( token, rawtoken, bufsize ); - return; - } - - // Now lookup enumeration - bool found = false; - float f = LookupEnumeration( rawtoken, found ); - if ( !found ) - { - Q_strncpy( token, rawtoken, bufsize ); - ResponseWarning( "No such enumeration '%s'\n", token ); - return; - } - - Q_snprintf( token, bufsize, "%f", f ); -} - - -static bool AppearsToBeANumber( char const *token ) -{ - if ( atof( token ) != 0.0f ) - return true; - - char const *p = token; - while ( *p ) - { - if ( *p != '0' ) - return false; - - p++; - } - - return true; -} - -void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) -{ - const char *s = c->value; - if ( !s ) - { - matcher.valid = false; - return; - } - - const char *in = s; - - char token[ 128 ]; - char rawtoken[ 128 ]; - - token[ 0 ] = 0; - rawtoken[ 0 ] = 0; - - int n = 0; - - bool gt = false; - bool lt = false; - bool eq = false; - bool nt = false; - - bool done = false; - while ( !done ) - { - switch( *in ) - { - case '>': - { - gt = true; - Assert( !lt ); // Can't be both - } - break; - case '<': - { - lt = true; - Assert( !gt ); // Can't be both - } - break; - case '=': - { - eq = true; - } - break; - case ',': - case '\0': - { - rawtoken[ n ] = 0; - n = 0; - - // Convert raw token to real token in case token is an enumerated type specifier - ResolveToken( matcher, token, sizeof( token ), rawtoken ); - - // Fill in first data set - if ( gt ) - { - matcher.usemin = true; - matcher.minequals = eq; - matcher.minval = (float)atof( token ); - - matcher.isnumeric = true; - } - else if ( lt ) - { - matcher.usemax = true; - matcher.maxequals = eq; - matcher.maxval = (float)atof( token ); - - matcher.isnumeric = true; - } - else - { - if ( *in == ',' ) - { - // If there's a comma, this better have been a less than or a gt key - Assert( 0 ); - } - - matcher.notequal = nt; - - matcher.isnumeric = AppearsToBeANumber( token ); - } - - gt = lt = eq = nt = false; - - if ( !(*in) ) - { - done = true; - } - } - break; - case '!': - nt = true; - break; - default: - rawtoken[ n++ ] = *in; - break; - } - - in++; - } - - matcher.SetToken( token ); - matcher.SetRaw( rawtoken ); - matcher.valid = true; -} - -bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose /*=false*/ ) -{ - if ( !m.valid ) - return false; - - float v = (float)atof( setValue ); - if ( setValue[0] == '[' ) - { - bool found = false; - v = LookupEnumeration( setValue, found ); - } - - int minmaxcount = 0; - - if ( m.usemin ) - { - if ( m.minequals ) - { - if ( v < m.minval ) - return false; - } - else - { - if ( v <= m.minval ) - return false; - } - - ++minmaxcount; - } - - if ( m.usemax ) - { - if ( m.maxequals ) - { - if ( v > m.maxval ) - return false; - } - else - { - if ( v >= m.maxval ) - return false; - } - - ++minmaxcount; - } - - // Had one or both criteria and met them - if ( minmaxcount >= 1 ) - { - return true; - } - - if ( m.notequal ) - { - if ( m.isnumeric ) - { - if ( v == (float)atof( m.GetToken() ) ) - return false; - } - else - { - if ( !Q_stricmp( setValue, m.GetToken() ) ) - return false; - } - - return true; - } - - if ( m.isnumeric ) - { - // If the setValue is "", the NPC doesn't have the key at all, - // in which case we shouldn't match "0". - if ( !setValue || !setValue[0] ) - return false; - - return v == (float)atof( m.GetToken() ); - } - - return !Q_stricmp( setValue, m.GetToken() ) ? true : false; -} - -bool CResponseSystem::Compare( const char *setValue, Criteria *c, bool verbose /*= false*/ ) -{ - Assert( c ); - Assert( setValue ); - - bool bret = CompareUsingMatcher( setValue, c->matcher, verbose ); - - if ( verbose ) - { - DevMsg( "'%20s' vs. '%20s' = ", setValue, c->value ); - - { - //DevMsg( "\n" ); - //m.Describe(); - } - } - return bret; -} - -float CResponseSystem::RecursiveScoreSubcriteriaAgainstRule( const AI_CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ) -{ - float score = 0.0f; - int subcount = parent->subcriteria.Count(); - for ( int i = 0; i < subcount; i++ ) - { - int icriterion = parent->subcriteria[ i ]; - - bool excludesubrule = false; - if (verbose) - { - DevMsg( "\n" ); - } - score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, excludesubrule, verbose ); - } - - exclude = ( parent->required && score == 0.0f ) ? true : false; - - return score * parent->weight.GetFloat(); -} - -float CResponseSystem::RecursiveLookForCriteria( const AI_CriteriaSet &criteriaSet, Criteria *pParent ) -{ - float flScore = 0.0f; - int nSubCount = pParent->subcriteria.Count(); - for ( int iSub = 0; iSub < nSubCount; ++iSub ) - { - int iCriteria = pParent->subcriteria[iSub]; - flScore += LookForCriteria( criteriaSet, iCriteria ); - } - - return flScore; -} - -float CResponseSystem::LookForCriteria( const AI_CriteriaSet &criteriaSet, int iCriteria ) -{ - Criteria *pCriteria = &m_Criteria[iCriteria]; - if ( pCriteria->IsSubCriteriaType() ) - { - return RecursiveLookForCriteria( criteriaSet, pCriteria ); - } - - int iIndex = criteriaSet.FindCriterionIndex( pCriteria->name ); - if ( iIndex == -1 ) - return 0.0f; - - Assert( criteriaSet.GetValue( iIndex ) ); - if ( Q_stricmp( criteriaSet.GetValue( iIndex ), pCriteria->value ) ) - return 0.0f; - - return 1.0f; -} - -float CResponseSystem::ScoreCriteriaAgainstRuleCriteria( const AI_CriteriaSet& set, int icriterion, bool& exclude, bool verbose /*=false*/ ) -{ - Criteria *c = &m_Criteria[ icriterion ]; - - if ( c->IsSubCriteriaType() ) - { - return RecursiveScoreSubcriteriaAgainstRule( set, c, exclude, verbose ); - } - - if ( verbose ) - { - DevMsg( " criterion '%25s':'%15s' ", m_Criteria.GetElementName( icriterion ), c->name ); - } - - exclude = false; - - float score = 0.0f; - - const char *actualValue = ""; - - int found = set.FindCriterionIndex( c->name ); - if ( found != -1 ) - { - actualValue = set.GetValue( found ); - if ( !actualValue ) - { - Assert( 0 ); - return score; - } - } - - Assert( actualValue ); - - if ( Compare( actualValue, c, verbose ) ) - { - float w = set.GetWeight( found ); - score = w * c->weight.GetFloat(); - - if ( verbose ) - { - DevMsg( "matched, weight %4.2f (s %4.2f x c %4.2f)", - score, w, c->weight.GetFloat() ); - } - } - else - { - if ( c->required ) - { - exclude = true; - if ( verbose ) - { - DevMsg( "failed (+exclude rule)" ); - } - } - else - { - if ( verbose ) - { - DevMsg( "failed" ); - } - } - } - - return score; -} - -float CResponseSystem::ScoreCriteriaAgainstRule( const AI_CriteriaSet& set, int irule, bool verbose /*=false*/ ) -{ - Rule *rule = &m_Rules[ irule ]; - float score = 0.0f; - - bool bBeingWatched = false; - - // See if we're trying to debug this rule - const char *pszText = rr_debugrule.GetString(); - if ( pszText && pszText[0] && !Q_stricmp( pszText, m_Rules.GetElementName( irule ) ) ) - { - bBeingWatched = true; - } - - if ( !rule->IsEnabled() ) - { - if ( bBeingWatched ) - { - DevMsg("Rule '%s' is disabled.\n", m_Rules.GetElementName( irule ) ); - } - return 0.0f; - } - - if ( bBeingWatched ) - { - verbose = true; - } - - if ( verbose ) - { - DevMsg( "Scoring rule '%s' (%i)\n{\n", m_Rules.GetElementName( irule ), irule+1 ); - } - - // Iterate set criteria - int count = rule->m_Criteria.Count(); - int i; - for ( i = 0; i < count; i++ ) - { - int icriterion = rule->m_Criteria[ i ]; - - bool exclude = false; - score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, exclude, verbose ); - - if ( verbose ) - { - DevMsg( ", score %4.2f\n", score ); - } - - if ( exclude ) - { - score = 0.0f; - break; - } - } - - if ( verbose ) - { - DevMsg( "}\n" ); - } - - return score; -} - -void CResponseSystem::DebugPrint( int depth, const char *fmt, ... ) -{ - int indentchars = 3 * depth; - char *indent = (char *)_alloca( indentchars + 1); - indent[ indentchars ] = 0; - while ( --indentchars >= 0 ) - { - indent[ indentchars ] = ' '; - } - - // Dump text to debugging console. - va_list argptr; - char szText[1024]; - - va_start (argptr, fmt); - Q_vsnprintf (szText, sizeof( szText ), fmt, argptr); - va_end (argptr); - - DevMsg( "%s%s", indent, szText ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::ResetResponseGroups() -{ - int i; - int c = m_Responses.Count(); - for ( i = 0; i < c; i++ ) - { - m_Responses[ i ].Reset(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *g - -// Output : int -//----------------------------------------------------------------------------- -int CResponseSystem::SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ) -{ - int c = g->group.Count(); - if ( !c ) - { - Assert( !"Expecting response group with >= 1 elements" ); - return -1; - } - - int i; - - // Fake depletion of unavailable choices - CUtlVector fakedDepletes; - if ( pFilter && g->ShouldCheckRepeats() ) - { - for ( i = 0; i < c; i++ ) - { - Response *r = &g->group[ i ]; - if ( r->depletioncount != g->GetDepletionCount() && !pFilter->IsValidResponse( r->GetType(), r->value ) ) - { - fakedDepletes.AddToTail( i ); - g->MarkResponseUsed( i ); - } - } - } - - if ( !g->HasUndepletedChoices() ) - { - g->ResetDepletionCount(); - - if ( pFilter && g->ShouldCheckRepeats() ) - { - fakedDepletes.RemoveAll(); - for ( i = 0; i < c; i++ ) - { - Response *r = &g->group[ i ]; - if ( !pFilter->IsValidResponse( r->GetType(), r->value ) ) - { - fakedDepletes.AddToTail( i ); - g->MarkResponseUsed( i ); - } - } - } - - if ( !g->HasUndepletedChoices() ) - return -1; - - // Disable the group if we looped through all the way - if ( g->IsNoRepeat() ) - { - g->SetEnabled( false ); - return -1; - } - } - - bool checkrepeats = g->ShouldCheckRepeats(); - int depletioncount = g->GetDepletionCount(); - - float totalweight = 0.0f; - int slot = -1; - - if ( checkrepeats ) - { - int check= -1; - // Snag the first slot right away - if ( g->HasUndepletedFirst( check ) && check != -1 ) - { - slot = check; - } - - if ( slot == -1 && g->HasUndepletedLast( check ) && check != -1 ) - { - // If this is the only undepleted one, use it now - for ( i = 0; i < c; i++ ) - { - Response *r = &g->group[ i ]; - if ( checkrepeats && - ( r->depletioncount == depletioncount ) ) - { - continue; - } - - if ( r->last ) - { - Assert( i == check ); - continue; - } - - // There's still another undepleted entry - break; - } - - // No more undepleted so use the r->last slot - if ( i >= c ) - { - slot = check; - } - } - } - - if ( slot == -1 ) - { - for ( i = 0; i < c; i++ ) - { - Response *r = &g->group[ i ]; - if ( checkrepeats && - ( r->depletioncount == depletioncount ) ) - { - continue; - } - - // Always skip last entry here since we will deal with it above - if ( checkrepeats && r->last ) - continue; - - int prevSlot = slot; - - if ( !totalweight ) - { - slot = i; - } - - // Always assume very first slot will match - totalweight += r->weight.GetFloat(); - if ( !totalweight || random->RandomFloat(0,totalweight) < r->weight.GetFloat() ) - { - slot = i; - } - - if ( !checkrepeats && slot != prevSlot && pFilter && !pFilter->IsValidResponse( r->GetType(), r->value ) ) - { - slot = prevSlot; - totalweight -= r->weight.GetFloat(); - } - } - } - - if ( slot != -1 ) - g->MarkResponseUsed( slot ); - - // Revert fake depletion of unavailable choices - if ( pFilter && g->ShouldCheckRepeats() ) - { - for ( i = 0; i < fakedDepletes.Count(); i++ ) - { - g->group[ fakedDepletes[ i ] ].depletioncount = 0;; - } - } - - return slot; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : searchResult - -// depth - -// *name - -// verbose - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CResponseSystem::ResolveResponse( ResponseSearchResult& searchResult, int depth, const char *name, bool verbose /*= false*/, IResponseFilter *pFilter ) -{ - int responseIndex = m_Responses.Find( name ); - if ( responseIndex == m_Responses.InvalidIndex() ) - return false; - - ResponseGroup *g = &m_Responses[ responseIndex ]; - // Group has been disabled - if ( !g->IsEnabled() ) - return false; - - int c = g->group.Count(); - if ( !c ) - return false; - - int idx = 0; - - if ( g->IsSequential() ) - { - // See if next index is valid - int initialIndex = g->GetCurrentIndex(); - bool bFoundValid = false; - - do - { - idx = g->GetCurrentIndex(); - g->SetCurrentIndex( idx + 1 ); - if ( idx >= c ) - { - if ( g->IsNoRepeat() ) - { - g->SetEnabled( false ); - return false; - } - idx = 0; - g->SetCurrentIndex( 0 ); - } - - if ( !pFilter || pFilter->IsValidResponse( g->group[idx].GetType(), g->group[idx].value ) ) - { - bFoundValid = true; - break; - } - - } while ( g->GetCurrentIndex() != initialIndex ); - - if ( !bFoundValid ) - return false; - } - else - { - idx = SelectWeightedResponseFromResponseGroup( g, pFilter ); - if ( idx < 0 ) - return false; - } - - if ( verbose ) - { - DebugPrint( depth, "%s\n", m_Responses.GetElementName( responseIndex ) ); - DebugPrint( depth, "{\n" ); - DescribeResponseGroup( g, idx, depth ); - } - - bool bret = true; - - Response *result = &g->group[ idx ]; - if ( result->type == RESPONSE_RESPONSE ) - { - // Recurse - bret = ResolveResponse( searchResult, depth + 1, result->value, verbose, pFilter ); - } - else - { - searchResult.action = result; - searchResult.group = g; - } - - if( verbose ) - { - DebugPrint( depth, "}\n" ); - } - - return bret; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *group - -// selected - -// depth - -//----------------------------------------------------------------------------- -void CResponseSystem::DescribeResponseGroup( ResponseGroup *group, int selected, int depth ) -{ - int c = group->group.Count(); - - for ( int i = 0; i < c ; i++ ) - { - Response *r = &group->group[ i ]; - DebugPrint( depth + 1, "%s%20s : %40s %5.3f\n", - i == selected ? "-> " : " ", - AI_Response::DescribeResponse( r->GetType() ), - r->value, - r->weight.GetFloat() ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *rule - -// Output : CResponseSystem::Response -//----------------------------------------------------------------------------- -bool CResponseSystem::GetBestResponse( ResponseSearchResult& searchResult, Rule *rule, bool verbose /*=false*/, IResponseFilter *pFilter ) -{ - int c = rule->m_Responses.Count(); - if ( !c ) - return false; - - int index = random->RandomInt( 0, c - 1 ); - int groupIndex = rule->m_Responses[ index ]; - - ResponseGroup *g = &m_Responses[ groupIndex ]; - - // Group has been disabled - if ( !g->IsEnabled() ) - return false; - - int count = g->group.Count(); - if ( !count ) - return false; - - int responseIndex = 0; - - if ( g->IsSequential() ) - { - // See if next index is valid - int initialIndex = g->GetCurrentIndex(); - bool bFoundValid = false; - - do - { - responseIndex = g->GetCurrentIndex(); - g->SetCurrentIndex( responseIndex + 1 ); - if ( responseIndex >= count ) - { - if ( g->IsNoRepeat() ) - { - g->SetEnabled( false ); - return false; - } - responseIndex = 0; - g->SetCurrentIndex( 0 ); - } - - if ( !pFilter || pFilter->IsValidResponse( g->group[responseIndex].GetType(), g->group[responseIndex].value ) ) - { - bFoundValid = true; - break; - } - - } while ( g->GetCurrentIndex() != initialIndex ); - - if ( !bFoundValid ) - return false; - } - else - { - responseIndex = SelectWeightedResponseFromResponseGroup( g, pFilter ); - if ( responseIndex < 0 ) - return false; - } - - - Response *r = &g->group[ responseIndex ]; - - int depth = 0; - - if ( verbose ) - { - DebugPrint( depth, "%s\n", m_Responses.GetElementName( groupIndex ) ); - DebugPrint( depth, "{\n" ); - - DescribeResponseGroup( g, responseIndex, depth ); - } - - bool bret = true; - - if ( r->type == RESPONSE_RESPONSE ) - { - bret = ResolveResponse( searchResult, depth + 1, r->value, verbose, pFilter ); - } - else - { - searchResult.action = r; - searchResult.group = g; - } - - if ( verbose ) - { - DebugPrint( depth, "}\n" ); - } - - return bret; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : set - -// verbose - -// Output : int -//----------------------------------------------------------------------------- -int CResponseSystem::FindBestMatchingRule( const AI_CriteriaSet& set, bool verbose ) -{ - CUtlVector< int > bestrules; - float bestscore = 0.001f; - - int c = m_Rules.Count(); - int i; - for ( i = 0; i < c; i++ ) - { - float score = ScoreCriteriaAgainstRule( set, i, verbose ); - // Check equals so that we keep track of all matching rules - if ( score >= bestscore ) - { - // Reset bucket - if( score != bestscore ) - { - bestscore = score; - bestrules.RemoveAll(); - } - - // Add to bucket - bestrules.AddToTail( i ); - } - } - - int bestCount = bestrules.Count(); - if ( bestCount <= 0 ) - return -1; - - if ( bestCount == 1 ) - return bestrules[ 0 ]; - - // Randomly pick one of the tied matching rules - int idx = random->RandomInt( 0, bestCount - 1 ); - if ( verbose ) - { - DevMsg( "Found %i matching rules, selecting slot %i\n", bestCount, idx ); - } - return bestrules[ idx ]; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : set - -// Output : AI_Response -//----------------------------------------------------------------------------- -bool CResponseSystem::FindBestResponse( const AI_CriteriaSet& set, AI_Response& response, IResponseFilter *pFilter ) -{ - bool valid = false; - - int iDbgResponse = rr_debugresponses.GetInt(); - bool showRules = ( iDbgResponse == 2 ); - bool showResult = ( iDbgResponse == 1 || iDbgResponse == 2 ); - - // Look for match. verbose mode used to be at level 2, but disabled because the writers don't actually care for that info. - int bestRule = FindBestMatchingRule( set, iDbgResponse == 3 ); - - ResponseType_t responseType = RESPONSE_NONE; - AI_ResponseParams rp; - - char ruleName[ 128 ]; - char responseName[ 128 ]; - const char *context; - bool bcontexttoworld; - ruleName[ 0 ] = 0; - responseName[ 0 ] = 0; - context = NULL; - bcontexttoworld = false; - if ( bestRule != -1 ) - { - Rule *r = &m_Rules[ bestRule ]; - - ResponseSearchResult result; - if ( GetBestResponse( result, r, showResult, pFilter ) ) - { - Q_strncpy( responseName, result.action->value, sizeof( responseName ) ); - responseType = result.action->GetType(); - rp = result.group->rp; - } - - Q_strncpy( ruleName, m_Rules.GetElementName( bestRule ), sizeof( ruleName ) ); - - // Disable the rule if it only allows for matching one time - if ( r->IsMatchOnce() ) - { - r->Disable(); - } - context = r->GetContext(); - bcontexttoworld = r->IsApplyContextToWorld(); - - valid = true; - } - - response.Init( responseType, responseName, set, rp, ruleName, context, bcontexttoworld ); - - if ( showResult ) - { - /* - // clipped -- chet doesn't really want this info - if ( valid ) - { - // Rescore the winner and dump to console - ScoreCriteriaAgainstRule( set, bestRule, true ); - } - */ - - - if ( valid || showRules ) - { - // Describe the response, too - response.Describe(); - } - } - - return valid; -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CResponseSystem::GetAllResponses( CUtlVector *pResponses ) -{ - for ( int i = 0; i < (int)m_Responses.Count(); i++ ) - { - ResponseGroup &group = m_Responses[i]; - - for ( int j = 0; j < group.group.Count(); j++) - { - Response &response = group.group[j]; - if ( response.type != RESPONSE_RESPONSE ) - { - AI_Response *pResponse = new AI_Response; - pResponse->Init( response.GetType(), response.value, AI_CriteriaSet(), group.rp, NULL, NULL, false ); - pResponses->AddToTail(pResponse); - } - } - } -} - -static void TouchFile( char const *pchFileName ) -{ - filesystem->Size( pchFileName ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::Precache() -{ - bool bTouchFiles = CommandLine()->FindParm( "-makereslists" ) != 0; - - // enumerate and mark all the scripts so we know they're referenced - for ( int i = 0; i < (int)m_Responses.Count(); i++ ) - { - ResponseGroup &group = m_Responses[i]; - - for ( int j = 0; j < group.group.Count(); j++) - { - Response &response = group.group[j]; - - switch ( response.type ) - { - default: - break; - case RESPONSE_SCENE: - { - // fixup $gender references - char file[_MAX_PATH]; - Q_strncpy( file, response.value, sizeof(file) ); - char *gender = strstr( file, "$gender" ); - if ( gender ) - { - // replace with male & female - const char *postGender = gender + strlen("$gender"); - *gender = 0; - char genderFile[_MAX_PATH]; - // male - Q_snprintf( genderFile, sizeof(genderFile), "%smale%s", file, postGender); - - PrecacheInstancedScene( genderFile ); - if ( bTouchFiles ) - { - TouchFile( genderFile ); - } - - Q_snprintf( genderFile, sizeof(genderFile), "%sfemale%s", file, postGender); - - PrecacheInstancedScene( genderFile ); - if ( bTouchFiles ) - { - TouchFile( genderFile ); - } - } - else - { - PrecacheInstancedScene( file ); - if ( bTouchFiles ) - { - TouchFile( file ); - } - } - } - break; - case RESPONSE_SPEAK: - { - CBaseEntity::PrecacheScriptSound( response.value ); - } - break; - } - } - } -} - -void CResponseSystem::ParseInclude( CStringPool &includedFiles ) -{ - char includefile[ 256 ]; - ParseToken(); - Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); - - // check if the file is already included - if ( includedFiles.Find( includefile ) != NULL ) - { - return; - } - - MEM_ALLOC_CREDIT(); - - // Try and load it - CUtlBuffer buf; - if ( !filesystem->ReadFile( includefile, "GAME", buf ) ) - { - DevMsg( "Unable to load #included script %s\n", includefile ); - return; - } - - LoadFromBuffer( includefile, (const char *)buf.PeekGet(), includedFiles ); -} - -void CResponseSystem::LoadFromBuffer( const char *scriptfile, const char *buffer, CStringPool &includedFiles ) -{ - includedFiles.Allocate( scriptfile ); - PushScript( scriptfile, (unsigned char * )buffer ); - - if( rr_dumpresponses.GetBool() ) - { - DevMsg("Reading: %s\n", scriptfile ); - } - - while ( 1 ) - { - ParseToken(); - if ( !token[0] ) - { - break; - } - - if ( !Q_stricmp( token, "#include" ) ) - { - ParseInclude( includedFiles ); - } - else if ( !Q_stricmp( token, "response" ) ) - { - ParseResponse(); - } - else if ( !Q_stricmp( token, "criterion" ) || - !Q_stricmp( token, "criteria" ) ) - { - ParseCriterion(); - } - else if ( !Q_stricmp( token, "rule" ) ) - { - ParseRule(); - } - else if ( !Q_stricmp( token, "enumeration" ) ) - { - ParseEnumeration(); - } - else - { - int byteoffset = m_ScriptStack[ 0 ].currenttoken - (const char *)m_ScriptStack[ 0 ].buffer; - - Error( "CResponseSystem::LoadFromBuffer: Unknown entry type '%s', expecting 'response', 'criterion', 'enumeration' or 'rules' in file %s(offset:%i)\n", - token, scriptfile, byteoffset ); - break; - } - } - - if ( m_ScriptStack.Count() == 1 ) - { - char cur[ 256 ]; - GetCurrentScript( cur, sizeof( cur ) ); - DevMsg( 1, "CResponseSystem: %s (%i rules, %i criteria, and %i responses)\n", - cur, m_Rules.Count(), m_Criteria.Count(), m_Responses.Count() ); - - if( rr_dumpresponses.GetBool() ) - { - DumpRules(); - } - } - - PopScript(); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::LoadRuleSet( const char *basescript ) -{ - int length = 0; - unsigned char *buffer = (unsigned char *)UTIL_LoadFileForMe( basescript, &length ); - if ( length <= 0 || !buffer ) - { - DevMsg( 1, "CResponseSystem: failed to load %s\n", basescript ); - return; - } - - CStringPool includedFiles; - - LoadFromBuffer( basescript, (const char *)buffer, includedFiles ); - - UTIL_FreeFile( buffer ); - - Assert( m_ScriptStack.Count() == 0 ); -} - -static ResponseType_t ComputeResponseType( const char *s ) -{ - if ( !Q_stricmp( s, "scene" ) ) - { - return RESPONSE_SCENE; - } - else if ( !Q_stricmp( s, "sentence" ) ) - { - return RESPONSE_SENTENCE; - } - else if ( !Q_stricmp( s, "speak" ) ) - { - return RESPONSE_SPEAK; - } - else if ( !Q_stricmp( s, "response" ) ) - { - return RESPONSE_RESPONSE; - } - else if ( !Q_stricmp( s, "print" ) ) - { - return RESPONSE_PRINT; - } - - return RESPONSE_NONE; -} - -void CResponseSystem::ParseOneResponse( const char *responseGroupName, ResponseGroup& group ) -{ - Response newResponse; - newResponse.weight.SetFloat( 1.0f ); - AI_ResponseParams *rp = &group.rp; - - newResponse.type = ComputeResponseType( token ); - if ( RESPONSE_NONE == newResponse.type ) - { - ResponseWarning( "response entry '%s' with unknown response type '%s'\n", responseGroupName, token ); - return; - } - - ParseToken(); - newResponse.value = CopyString( token ); - - while ( TokenWaiting() ) - { - ParseToken(); - if ( !Q_stricmp( token, "weight" ) ) - { - ParseToken(); - newResponse.weight.SetFloat( (float)atof( token ) ); - continue; - } - - if ( !Q_stricmp( token, "predelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; - rp->predelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "nodelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.start = 0; - rp->delay.range = 0; - continue; - } - - if ( !Q_stricmp( token, "defaultdelay" ) ) - { - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.start = AIS_DEF_MIN_DELAY; - rp->delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); - continue; - } - - if ( !Q_stricmp( token, "delay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "speakonce" ) ) - { - rp->flags |= AI_ResponseParams::RG_SPEAKONCE; - continue; - } - - if ( !Q_stricmp( token, "noscene" ) ) - { - rp->flags |= AI_ResponseParams::RG_DONT_USE_SCENE; - continue; - } - - if ( !Q_stricmp( token, "stop_on_nonidle" ) ) - { - rp->flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; - continue; - } - - if ( !Q_stricmp( token, "odds" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_ODDS; - rp->odds = clamp( atoi( token ), 0, 100 ); - continue; - } - - if ( !Q_stricmp( token, "respeakdelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_RESPEAKDELAY; - rp->respeakdelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "weapondelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_WEAPONDELAY; - rp->weapondelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "soundlevel" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_SOUNDLEVEL; - rp->soundlevel = (soundlevel_t)TextToSoundLevel( token ); - continue; - } - - if ( !Q_stricmp( token, "displayfirst" ) ) - { - newResponse.first = true; - group.m_bHasFirst = true; - continue; - } - - if ( !Q_stricmp( token, "displaylast" ) ) - { - newResponse.last = true; - group.m_bHasLast= true; - continue; - } - - ResponseWarning( "response entry '%s' with unknown command '%s'\n", responseGroupName, token ); - } - - group.group.AddToTail( newResponse ); -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CResponseSystem::IsRootCommand() -{ - if ( !Q_stricmp( token, "#include" ) ) - return true; - if ( !Q_stricmp( token, "response" ) ) - return true; - if ( !Q_stricmp( token, "enumeration" ) ) - return true; - if ( !Q_stricmp( token, "criteria" ) ) - return true; - if ( !Q_stricmp( token, "criterion" ) ) - return true; - if ( !Q_stricmp( token, "rule" ) ) - return true; - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *kv - -//----------------------------------------------------------------------------- -void CResponseSystem::ParseResponse( void ) -{ - // Should have groupname at start - char responseGroupName[ 128 ]; - - ResponseGroup newGroup; - AI_ResponseParams *rp = &newGroup.rp; - - // Response Group Name - ParseToken(); - Q_strncpy( responseGroupName, token, sizeof( responseGroupName ) ); - - while ( 1 ) - { - ParseToken(); - - // Oops, part of next definition - if( IsRootCommand() ) - { - Unget(); - break; - } - - if ( !Q_stricmp( token, "{" ) ) - { - while ( 1 ) - { - ParseToken(); - if ( !Q_stricmp( token, "}" ) ) - break; - - if ( !Q_stricmp( token, "permitrepeats" ) ) - { - newGroup.m_bDepleteBeforeRepeat = false; - continue; - } - else if ( !Q_stricmp( token, "sequential" ) ) - { - newGroup.SetSequential( true ); - continue; - } - else if ( !Q_stricmp( token, "norepeat" ) ) - { - newGroup.SetNoRepeat( true ); - continue; - } - - ParseOneResponse( responseGroupName, newGroup ); - } - break; - } - - if ( !Q_stricmp( token, "predelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; - rp->predelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "nodelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.start = 0; - rp->delay.range = 0; - continue; - } - - if ( !Q_stricmp( token, "defaultdelay" ) ) - { - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.start = AIS_DEF_MIN_DELAY; - rp->delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); - continue; - } - - if ( !Q_stricmp( token, "delay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; - rp->delay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "speakonce" ) ) - { - rp->flags |= AI_ResponseParams::RG_SPEAKONCE; - continue; - } - - if ( !Q_stricmp( token, "noscene" ) ) - { - rp->flags |= AI_ResponseParams::RG_DONT_USE_SCENE; - continue; - } - - if ( !Q_stricmp( token, "stop_on_nonidle" ) ) - { - rp->flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; - continue; - } - - if ( !Q_stricmp( token, "odds" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_ODDS; - rp->odds = clamp( atoi( token ), 0, 100 ); - continue; - } - - if ( !Q_stricmp( token, "respeakdelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_RESPEAKDELAY; - rp->respeakdelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "weapondelay" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_WEAPONDELAY; - rp->weapondelay.FromInterval( ReadInterval( token ) ); - continue; - } - - if ( !Q_stricmp( token, "soundlevel" ) ) - { - ParseToken(); - rp->flags |= AI_ResponseParams::RG_SOUNDLEVEL; - rp->soundlevel = (soundlevel_t)TextToSoundLevel( token ); - continue; - } - - ParseOneResponse( responseGroupName, newGroup ); - } - - m_Responses.Insert( responseGroupName, newGroup ); -} - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *criterion - -//----------------------------------------------------------------------------- -int CResponseSystem::ParseOneCriterion( const char *criterionName ) -{ - char key[ 128 ]; - char value[ 128 ]; - - Criteria newCriterion; - - bool gotbody = false; - - while ( TokenWaiting() || !gotbody ) - { - ParseToken(); - - // Oops, part of next definition - if( IsRootCommand() ) - { - Unget(); - break; - } - - if ( !Q_stricmp( token, "{" ) ) - { - gotbody = true; - - while ( 1 ) - { - ParseToken(); - if ( !Q_stricmp( token, "}" ) ) - break; - - // Look up subcriteria index - int idx = m_Criteria.Find( token ); - if ( idx != m_Criteria.InvalidIndex() ) - { - newCriterion.subcriteria.AddToTail( idx ); - } - else - { - ResponseWarning( "Skipping unrecongized subcriterion '%s' in '%s'\n", token, criterionName ); - } - } - continue; - } - else if ( !Q_stricmp( token, "required" ) ) - { - newCriterion.required = true; - } - else if ( !Q_stricmp( token, "weight" ) ) - { - ParseToken(); - newCriterion.weight.SetFloat( (float)atof( token ) ); - } - else - { - Assert( newCriterion.subcriteria.Count() == 0 ); + DEFINE_FIELD( m_nCurrentIndex, FIELD_CHARACTER ), +END_DATADESC() - // Assume it's the math info for a non-subcriteria resposne - Q_strncpy( key, token, sizeof( key ) ); - ParseToken(); - Q_strncpy( value, token, sizeof( value ) ); - newCriterion.name = CopyString( key ); - newCriterion.value = CopyString( value ); +/// Add some game-specific code to the basic response system +/// (eg, the scene precacher, which requires the client and server +/// to work) - gotbody = true; - } - } +class CGameResponseSystem : public CResponseSystem +{ +public: + CGameResponseSystem(); - if ( !newCriterion.IsSubCriteriaType() ) + virtual void Precache(); + virtual void PrecacheResponses( bool bEnable ) { - ComputeMatcher( &newCriterion, newCriterion.matcher ); + m_bPrecache = bEnable; } + bool ShouldPrecache() { return m_bPrecache; } - if ( m_Criteria.Find( criterionName ) != m_Criteria.InvalidIndex() ) - { - ResponseWarning( "Multiple definitions for criteria '%s'\n", criterionName ); - return m_Criteria.InvalidIndex(); - } +protected: + bool m_bPrecache; +}; - int idx = m_Criteria.Insert( criterionName, newCriterion ); - return idx; -} //----------------------------------------------------------------------------- // Purpose: -// Input : *kv - //----------------------------------------------------------------------------- -void CResponseSystem::ParseCriterion( void ) -{ - // Should have groupname at start - char criterionName[ 128 ]; - ParseToken(); - Q_strncpy( criterionName, token, sizeof( criterionName ) ); - - ParseOneCriterion( criterionName ); -} +CGameResponseSystem::CGameResponseSystem() : m_bPrecache(true) +{}; //----------------------------------------------------------------------------- // Purpose: -// Input : *kv - //----------------------------------------------------------------------------- -void CResponseSystem::ParseEnumeration( void ) + +#if 0 +class CScenePrecacheSystem : public CAutoGameSystem { - char enumerationName[ 128 ]; - ParseToken(); - Q_strncpy( enumerationName, token, sizeof( enumerationName ) ); +public: + CScenePrecacheSystem() : CAutoGameSystem( "CScenePrecacheSystem" ), m_RepeatCounts( 0, 0, DefLessFunc( int ) ) + { + } - ParseToken(); - if ( Q_stricmp( token, "{" ) ) + // Level init, shutdown + virtual void LevelShutdownPreEntity() { - ResponseWarning( "Expecting '{' in enumeration '%s', got '%s'\n", enumerationName, token ); - return; + m_RepeatCounts.Purge(); } - while ( 1 ) + bool ShouldPrecache( char const *pszScene ) { - ParseToken(); - if ( !Q_stricmp( token, "}" ) ) - break; + int hash = HashStringCaselessConventional( pszScene ); - if ( Q_strlen( token ) <= 0 ) + int slot = m_RepeatCounts.Find( hash ); + if ( slot != m_RepeatCounts.InvalidIndex() ) { - ResponseWarning( "Expecting more tokens in enumeration '%s'\n", enumerationName ); - break; + m_RepeatCounts[ slot ]++; + return false; } - char key[ 128 ]; - - Q_strncpy( key, token, sizeof( key ) ); - ParseToken(); - float value = (float)atof( token ); - - char sz[ 128 ]; - Q_snprintf( sz, sizeof( sz ), "[%s::%s]", enumerationName, key ); - Q_strlower( sz ); + m_RepeatCounts.Insert( hash, 0 ); + return true; + } - Enumeration newEnum; - newEnum.value = value; +private: - if ( m_Enumerations.Find( sz ) == m_Enumerations.InvalidIndex() ) - { - m_Enumerations.Insert( sz, newEnum ); - } - /* - else - { - ResponseWarning( "Ignoring duplication enumeration '%s'\n", sz ); - } - */ - } -} + CUtlMap< int, int > m_RepeatCounts; +}; +static CScenePrecacheSystem g_ScenePrecacheSystem; //----------------------------------------------------------------------------- -// Purpose: -// Input : *kv - +// Purpose: Used for precaching instanced scenes +// Input : *pszScene - //----------------------------------------------------------------------------- -void CResponseSystem::ParseRule( void ) +void PrecacheInstancedScene( char const *pszScene ) { - static int instancedCriteria = 0; + static int nMakingReslists = -1; - char ruleName[ 128 ]; - ParseToken(); - Q_strncpy( ruleName, token, sizeof( ruleName ) ); + if ( !g_ScenePrecacheSystem.ShouldPrecache( pszScene ) ) + return; - ParseToken(); - if ( Q_stricmp( token, "{" ) ) + if ( nMakingReslists == -1 ) { - ResponseWarning( "Expecting '{' in rule '%s', got '%s'\n", ruleName, token ); - return; + nMakingReslists = CommandLine()->FindParm( "-makereslists" ) > 0 ? 1 : 0; } - // entries are "criteria", "response" or an in-line criteria to instance - Rule newRule; - - char sz[ 128 ]; - - bool validRule = true; - while ( 1 ) + if ( nMakingReslists == 1 ) { - ParseToken(); - if ( !Q_stricmp( token, "}" ) ) - { - break; - } - - if ( Q_strlen( token ) <= 0 ) - { - ResponseWarning( "Expecting more tokens in rule '%s'\n", ruleName ); - break; - } - - if ( !Q_stricmp( token, "matchonce" ) ) - { - newRule.m_bMatchOnce = true; - continue; - } - - if ( !Q_stricmp( token, "applyContextToWorld" ) ) - { - newRule.m_bApplyContextToWorld = true; - continue; - } - - if ( !Q_stricmp( token, "applyContext" ) ) - { - ParseToken(); - if ( newRule.GetContext() == NULL ) - { - newRule.SetContext( token ); - } - else - { - CFmtStrN<1024> newContext( "%s,%s", newRule.GetContext(), token ); - newRule.SetContext( newContext ); - } - continue; - } - - if ( !Q_stricmp( token, "response" ) ) - { - // Read them until we run out. - while ( TokenWaiting() ) - { - ParseToken(); - int idx = m_Responses.Find( token ); - if ( idx != m_Responses.InvalidIndex() ) - { - MEM_ALLOC_CREDIT(); - newRule.m_Responses.AddToTail( idx ); - } - else - { - validRule = false; - ResponseWarning( "No such response '%s' for rule '%s'\n", token, ruleName ); - } - } - continue; - } - - if ( !Q_stricmp( token, "criteria" ) || - !Q_stricmp( token, "criterion" ) ) - { - // Read them until we run out. - while ( TokenWaiting() ) - { - ParseToken(); - - int idx = m_Criteria.Find( token ); - if ( idx != m_Criteria.InvalidIndex() ) - { - MEM_ALLOC_CREDIT(); - newRule.m_Criteria.AddToTail( idx ); - } - else - { - validRule = false; - ResponseWarning( "No such criterion '%s' for rule '%s'\n", token, ruleName ); - } - } - continue; - } - - // It's an inline criteria, generate a name and parse it in - Q_snprintf( sz, sizeof( sz ), "[%s%03i]", ruleName, ++instancedCriteria ); - Unget(); - int idx = ParseOneCriterion( sz ); - if ( idx != m_Criteria.InvalidIndex() ) - { - newRule.m_Criteria.AddToTail( idx ); - } + // Just stat the file to add to reslist + g_pFullFileSystem->Size( pszScene ); } - if ( validRule ) + // verify existence, cache is pre-populated, should be there + SceneCachedData_t sceneData; + if ( !scenefilecache->GetSceneCachedData( pszScene, &sceneData ) ) { - m_Rules.Insert( ruleName, newRule ); + // Scenes are sloppy and don't always exist. + // A scene that is not in the pre-built cache image, but on disk, is a true error. + if ( IsX360() && ( g_pFullFileSystem->GetDVDMode() != DVDMODE_STRICT ) && g_pFullFileSystem->FileExists( pszScene, "GAME" ) ) + { + Warning( "PrecacheInstancedScene: Missing scene '%s' from scene image cache.\nRebuild scene image cache!\n", pszScene ); + } } else { - DevMsg( "Discarded rule %s\n", ruleName ); + for ( int i = 0; i < sceneData.numSounds; ++i ) + { + short stringId = scenefilecache->GetSceneCachedSound( sceneData.sceneId, i ); + CBaseEntity::PrecacheScriptSound( scenefilecache->GetSceneString( stringId ) ); + } } -} -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CResponseSystem::GetCurrentToken() const -{ - if ( m_ScriptStack.Count() <= 0 ) - return -1; - - return m_ScriptStack[ 0 ].tokencount; + g_pStringTableClientSideChoreoScenes->AddString( CBaseEntity::IsServer(), pszScene ); } - - -void CResponseSystem::ResponseWarning( const char *fmt, ... ) +#endif +static void TouchFile( char const *pchFileName ) { - va_list argptr; -#ifndef _XBOX - static char string[1024]; -#else - char string[1024]; -#endif - - va_start (argptr, fmt); - Q_vsnprintf(string, sizeof(string), fmt,argptr); - va_end (argptr); - - char cur[ 256 ]; - GetCurrentScript( cur, sizeof( cur ) ); - DevMsg( 1, "%s(token %i) : %s", cur, GetCurrentToken(), string ); + IEngineEmulator::Get()->GetFilesystem()->Size( pchFileName ); } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) +void CGameResponseSystem::Precache() { - // Add criteria from this rule to global list in custom response system. - int nCriteriaCount = pSrcRule->m_Criteria.Count(); - for ( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) - { - int iSrcIndex = pSrcRule->m_Criteria[iCriteria]; - Criteria *pSrcCriteria = &m_Criteria[iSrcIndex]; - if ( pSrcCriteria ) - { - int iIndex = pCustomSystem->m_Criteria.Find( m_Criteria.GetElementName( iSrcIndex ) ); - if ( iIndex != pCustomSystem->m_Criteria.InvalidIndex() ) - { - pDstRule->m_Criteria.AddToTail( iIndex ); - continue; - } + bool bTouchFiles = CommandLine()->FindParm( "-makereslists" ) != 0; - // Add the criteria. - Criteria dstCriteria; + // enumerate and mark all the scripts so we know they're referenced + for ( int i = 0; i < (int)m_Responses.Count(); i++ ) + { + ResponseGroup &group = m_Responses[i]; - dstCriteria.name = CopyString( pSrcCriteria->name ); - dstCriteria.value = CopyString( pSrcCriteria->value ); - dstCriteria.weight = pSrcCriteria->weight; - dstCriteria.required = pSrcCriteria->required; - dstCriteria.matcher = pSrcCriteria->matcher; + for ( int j = 0; j < group.group.Count(); j++) + { + ParserResponse &response = group.group[j]; - int nSubCriteriaCount = pSrcCriteria->subcriteria.Count(); - for ( int iSubCriteria = 0; iSubCriteria < nSubCriteriaCount; ++iSubCriteria ) + switch ( response.type ) { - int iSrcSubIndex = pSrcCriteria->subcriteria[iSubCriteria]; - Criteria *pSrcSubCriteria = &m_Criteria[iSrcSubIndex]; - if ( pSrcCriteria ) + default: + break; + case RESPONSE_SCENE: { - int iSubIndex = pCustomSystem->m_Criteria.Find( pSrcSubCriteria->value ); - if ( iSubIndex != pCustomSystem->m_Criteria.InvalidIndex() ) - continue; + // fixup $gender references + char file[_MAX_PATH]; + Q_strncpy( file, response.value, sizeof(file) ); + char *gender = strstr( file, "$gender" ); + if ( gender ) + { + // replace with male & female + const char *postGender = gender + strlen("$gender"); + *gender = 0; + char genderFile[_MAX_PATH]; + // male + Q_snprintf( genderFile, sizeof(genderFile), "%smale%s", file, postGender); - // Add the criteria. - Criteria dstSubCriteria; + PrecacheInstancedScene( genderFile ); + if ( bTouchFiles ) + { + TouchFile( genderFile ); + } - dstSubCriteria.name = CopyString( pSrcSubCriteria->name ); - dstSubCriteria.value = CopyString( pSrcSubCriteria->value ); - dstSubCriteria.weight = pSrcSubCriteria->weight; - dstSubCriteria.required = pSrcSubCriteria->required; - dstSubCriteria.matcher = pSrcSubCriteria->matcher; + Q_snprintf( genderFile, sizeof(genderFile), "%sfemale%s", file, postGender); - int iSubInsertIndex = pCustomSystem->m_Criteria.Insert( pSrcSubCriteria->value, dstSubCriteria ); - dstCriteria.subcriteria.AddToTail( iSubInsertIndex ); + PrecacheInstancedScene( genderFile ); + if ( bTouchFiles ) + { + TouchFile( genderFile ); + } + } + else + { + PrecacheInstancedScene( file ); + if ( bTouchFiles ) + { + TouchFile( file ); + } + } } - } - - int iInsertIndex = pCustomSystem->m_Criteria.Insert( m_Criteria.GetElementName( iSrcIndex ), dstCriteria ); - pDstRule->m_Criteria.AddToTail( iInsertIndex ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) -{ - // Add responses from this rule to global list in custom response system. - int nResponseGroupCount = pSrcRule->m_Responses.Count(); - for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) - { - int iSrcResponseGroup = pSrcRule->m_Responses[iResponseGroup]; - ResponseGroup *pSrcResponseGroup = &m_Responses[iSrcResponseGroup]; - if ( pSrcResponseGroup ) - { - // Add response group. - ResponseGroup dstResponseGroup; - - dstResponseGroup.rp = pSrcResponseGroup->rp; - dstResponseGroup.m_bDepleteBeforeRepeat = pSrcResponseGroup->m_bDepleteBeforeRepeat; - dstResponseGroup.m_nDepletionCount = pSrcResponseGroup->m_nDepletionCount; - dstResponseGroup.m_bHasFirst = pSrcResponseGroup->m_bHasFirst; - dstResponseGroup.m_bHasLast = pSrcResponseGroup->m_bHasLast; - dstResponseGroup.m_bSequential = pSrcResponseGroup->m_bSequential; - dstResponseGroup.m_bNoRepeat = pSrcResponseGroup->m_bNoRepeat; - dstResponseGroup.m_bEnabled = pSrcResponseGroup->m_bEnabled; - dstResponseGroup.m_nCurrentIndex = pSrcResponseGroup->m_nCurrentIndex; - - int nSrcResponseCount = pSrcResponseGroup->group.Count(); - for ( int iResponse = 0; iResponse < nSrcResponseCount; ++iResponse ) - { - Response *pSrcResponse = &pSrcResponseGroup->group[iResponse]; - if ( pSrcResponse ) + break; + case RESPONSE_SPEAK: { - // Add Response - Response dstResponse; - - dstResponse.weight = pSrcResponse->weight; - dstResponse.type = pSrcResponse->type; - dstResponse.value = CopyString( pSrcResponse->value ); - dstResponse.depletioncount = pSrcResponse->depletioncount; - dstResponse.first = pSrcResponse->first; - dstResponse.last = pSrcResponse->last; - - dstResponseGroup.group.AddToTail( dstResponse ); + CBaseEntity::PrecacheScriptSound( response.value ); } + break; } - - int iInsertIndex = pCustomSystem->m_Responses.Insert( m_Responses.GetElementName( iSrcResponseGroup ), dstResponseGroup ); - pDstRule->m_Responses.AddToTail( iInsertIndex ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::CopyEnumerationsFrom( CResponseSystem *pCustomSystem ) -{ - int nEnumerationCount = m_Enumerations.Count(); - for ( int iEnumeration = 0; iEnumeration < nEnumerationCount; ++iEnumeration ) - { - Enumeration *pSrcEnumeration = &m_Enumerations[iEnumeration]; - if ( pSrcEnumeration ) - { - Enumeration dstEnumeration; - dstEnumeration.value = pSrcEnumeration->value; - pCustomSystem->m_Enumerations.Insert( m_Enumerations.GetElementName( iEnumeration ), dstEnumeration ); } } } -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CResponseSystem::CopyRuleFrom( Rule *pSrcRule, int iRule, CResponseSystem *pCustomSystem ) -{ - // Verify data. - Assert( pSrcRule ); - Assert( pCustomSystem ); - if ( !pSrcRule || !pCustomSystem ) - return; - - // New rule - Rule dstRule; - - dstRule.SetContext( pSrcRule->GetContext() ); - dstRule.m_bMatchOnce = pSrcRule->m_bMatchOnce; - dstRule.m_bEnabled = pSrcRule->m_bEnabled; - dstRule.m_bApplyContextToWorld = pSrcRule->m_bApplyContextToWorld; - - // Copy off criteria. - CopyCriteriaFrom( pSrcRule, &dstRule, pCustomSystem ); - - // Copy off responses. - CopyResponsesFrom( pSrcRule, &dstRule, pCustomSystem ); - - // Copy off enumerations - Don't think we use these. -// CopyEnumerationsFrom( pCustomSystem ); - - // Add rule. - pCustomSystem->m_Rules.Insert( m_Rules.GetElementName( iRule ), dstRule ); -} //----------------------------------------------------------------------------- // Purpose: A special purpose response system associated with a custom entity //----------------------------------------------------------------------------- -class CInstancedResponseSystem : public CResponseSystem +class CInstancedResponseSystem : public CGameResponseSystem { - typedef CResponseSystem BaseClass; + typedef CGameResponseSystem BaseClass; public: CInstancedResponseSystem( const char *scriptfile ) : m_pszScriptFile( 0 ) - { - Assert( scriptfile ); - - int len = Q_strlen( scriptfile ) + 1; - m_pszScriptFile = new char[ len ]; - Assert( m_pszScriptFile ); - Q_strncpy( m_pszScriptFile, scriptfile, len ); - } - - ~CInstancedResponseSystem() - { - delete[] m_pszScriptFile; - } - virtual const char *GetScriptFile( void ) - { - Assert( m_pszScriptFile ); - return m_pszScriptFile; - } - - // CAutoGameSystem - virtual bool Init() - { - const char *basescript = GetScriptFile(); - LoadRuleSet( basescript ); - return true; - } - - virtual void LevelInitPostEntity() - { - ResetResponseGroups(); - } - - virtual void Release() - { - Clear(); - delete this; - } + { + Assert( scriptfile ); + + int len = Q_strlen( scriptfile ) + 1; + m_pszScriptFile = new char[ len ]; + Assert( m_pszScriptFile ); + Q_strncpy( m_pszScriptFile, scriptfile, len ); + } + + ~CInstancedResponseSystem() + { + delete[] m_pszScriptFile; + } + virtual const char *GetScriptFile( void ) + { + Assert( m_pszScriptFile ); + return m_pszScriptFile; + } + + // CAutoGameSystem + virtual bool Init() + { + const char *basescript = GetScriptFile(); + LoadRuleSet( basescript ); + return true; + } + + virtual void LevelInitPostEntity() + { + ResetResponseGroups(); + } + + virtual void Release() + { + Clear(); + delete this; + } private: char *m_pszScriptFile; @@ -2861,7 +453,7 @@ class CInstancedResponseSystem : public CResponseSystem //----------------------------------------------------------------------------- // Purpose: The default response system for expressive AIs //----------------------------------------------------------------------------- -class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem +class CDefaultResponseSystem : public CGameResponseSystem, public CAutoGameSystem { typedef CAutoGameSystem BaseClass; @@ -2903,6 +495,7 @@ class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) { + COM_TimestampedLog( "PrecacheCustomResponseSystem %s - Start", scriptfile ); CInstancedResponseSystem *sys = ( CInstancedResponseSystem * )FindResponseSystem( scriptfile ); if ( !sys ) { @@ -2922,6 +515,8 @@ class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem sys->Precache(); + COM_TimestampedLog( "PrecacheCustomResponseSystem %s - Finish", scriptfile ); + return ( IResponseSystem * )sys; } @@ -2963,6 +558,9 @@ class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem } } + // precache sounds in case we added new ones + Precache(); + } private: @@ -2979,9 +577,10 @@ class CDefaultResponseSystem : public CResponseSystem, public CAutoGameSystem } CUtlDict< CInstancedResponseSystem *, int > m_InstancedSystems; + friend void CC_RR_DumpHashInfo( const CCommand &args ); }; -IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) +ResponseRules::IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) { // Create a instanced response system. CInstancedResponseSystem *pCustomSystem = new CInstancedResponseSystem( pszCustomName ); @@ -2993,10 +592,15 @@ IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( pCustomSystem->Clear(); // Copy the relevant rules and data. + /* int nRuleCount = m_Rules.Count(); for ( int iRule = 0; iRule < nRuleCount; ++iRule ) + */ + for ( ResponseRulePartition::tIndex iIdx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(iIdx) ; + iIdx = m_RulePartitions.Next( iIdx ) ) { - Rule *pRule = &m_Rules[iRule]; + Rule *pRule = &m_RulePartitions[iIdx]; if ( pRule ) { float flScore = 0.0f; @@ -3009,7 +613,7 @@ IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( flScore += LookForCriteria( criteriaSet, iRuleCriteria ); if ( flScore >= flCriteriaScore ) { - CopyRuleFrom( pRule, iRule, pCustomSystem ); + CopyRuleFrom( pRule, iIdx, pCustomSystem ); break; } } @@ -3020,7 +624,7 @@ IResponseSystem *CDefaultResponseSystem::BuildCustomResponseSystemGivenCriteria( m_bCustomManagable = true; AddInstancedResponseSystem( pszCustomName, pCustomSystem ); -// pCustomSystem->DumpDictionary( pszCustomName ); + // pCustomSystem->DumpDictionary( pszCustomName ); return pCustomSystem; } @@ -3032,23 +636,16 @@ void CDefaultResponseSystem::DestroyCustomResponseSystems() static CDefaultResponseSystem defaultresponsesytem; -IResponseSystem *g_pResponseSystem = &defaultresponsesytem; +ResponseRules::IResponseSystem *g_pResponseSystem = &defaultresponsesytem; CON_COMMAND( rr_reloadresponsesystems, "Reload all response system scripts." ) { +#ifdef GAME_DLL if ( !UTIL_IsCommandIssuedByServerAdmin() ) return; +#endif defaultresponsesytem.ReloadAllResponseSystems(); - -#if defined( TF_DLL ) || defined ( TF_CLASSIC ) - // This is kind of hacky, but I need to get it in for now! - if( g_pGameRules->IsMultiplayer() ) - { - CMultiplayRules *pMultiplayRules = static_cast( g_pGameRules ); - pMultiplayRules->InitCustomResponseRulesDicts(); - } -#endif } static short RESPONSESYSTEM_SAVE_RESTORE_VERSION = 1; @@ -3067,7 +664,7 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc { pSave->WriteShort( &RESPONSESYSTEM_SAVE_RESTORE_VERSION ); } - + void ReadRestoreHeaders( IRestore *pRestore ) { // No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so. @@ -3094,7 +691,7 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc pSave->WriteShort( &groupCount ); for ( int j = 0; j < groupCount; ++j ) { - const Response *response = &group->group[ j ]; + const ParserResponse *response = &group->group[ j ]; pSave->StartBlock( "Response" ); pSave->WriteString( response->value ); pSave->WriteAll( response ); @@ -3145,7 +742,7 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc int ri; for ( ri = 0; ri < group->group.Count(); ++ri ) { - Response *response = &group->group[ ri ]; + ParserResponse *response = &group->group[ ri ]; if ( !Q_stricmp( response->value, responsename ) ) { break; @@ -3154,7 +751,7 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc if ( ri < group->group.Count() ) { - Response *response = &group->group[ ri ]; + ParserResponse *response = &group->group[ ri ]; pRestore->ReadAll( response ); } } @@ -3172,7 +769,7 @@ class CDefaultResponseSystemSaveRestoreBlockHandler : public CDefSaveRestoreBloc bool m_fDoLoad; } g_DefaultResponseSystemSaveRestoreBlockHandler; - + ISaveRestoreBlockHandler *GetDefaultResponseSystemSaveRestoreBlockHandler() { return &g_DefaultResponseSystemSaveRestoreBlockHandler; @@ -3197,7 +794,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps CResponseSystem *pRS = *(CResponseSystem **)fieldInfo.pField; if ( !pRS || pRS == &defaultresponsesytem ) return; - + int count = pRS->m_Responses.Count(); pSave->WriteInt( &count ); for ( int i = 0; i < count; ++i ) @@ -3212,7 +809,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps pSave->WriteShort( &groupCount ); for ( int j = 0; j < groupCount; ++j ) { - const Response *response = &group->group[ j ]; + const ParserResponse *response = &group->group[ j ]; pSave->StartBlock( "Response" ); pSave->WriteString( response->value ); pSave->WriteAll( response ); @@ -3222,7 +819,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps pSave->EndBlock(); } } - + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) { CResponseSystem *pRS = *(CResponseSystem **)fieldInfo.pField; @@ -3262,7 +859,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps int ri; for ( ri = 0; ri < group->group.Count(); ++ri ) { - Response *response = &group->group[ ri ]; + ParserResponse *response = &group->group[ ri ]; if ( !Q_stricmp( response->value, responsename ) ) { break; @@ -3271,7 +868,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps if ( ri < group->group.Count() ) { - Response *response = &group->group[ ri ]; + ParserResponse *response = &group->group[ ri ]; pRestore->ReadAll( response ); } } @@ -3284,7 +881,7 @@ class CResponseSystemSaveRestoreOps : public CDefSaveRestoreOps pRestore->EndBlock(); } } - + } g_ResponseSystemSaveRestoreOps; ISaveRestoreOps *responseSystemSaveRestoreOps = &g_ResponseSystemSaveRestoreOps; @@ -3295,12 +892,12 @@ ISaveRestoreOps *responseSystemSaveRestoreOps = &g_ResponseSystemSaveRestoreOps; //----------------------------------------------------------------------------- bool CDefaultResponseSystem::Init() { -/* + /* Warning( "sizeof( Response ) == %d\n", sizeof( Response ) ); Warning( "sizeof( ResponseGroup ) == %d\n", sizeof( ResponseGroup ) ); Warning( "sizeof( Criteria ) == %d\n", sizeof( Criteria ) ); Warning( "sizeof( AI_ResponseParams ) == %d\n", sizeof( AI_ResponseParams ) ); -*/ + */ const char *basescript = GetScriptFile(); LoadRuleSet( basescript ); @@ -3322,12 +919,13 @@ void CDefaultResponseSystem::Shutdown() BaseClass::Shutdown(); } + //----------------------------------------------------------------------------- // Purpose: Instance a custom response system // Input : *scriptfile - // Output : IResponseSystem //----------------------------------------------------------------------------- -IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) +ResponseRules::IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) { return defaultresponsesytem.PrecacheCustomResponseSystem( scriptfile ); } @@ -3338,7 +936,7 @@ IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ) // set - // Output : IResponseSystem //----------------------------------------------------------------------------- -IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) +ResponseRules::IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ) { return defaultresponsesytem.BuildCustomResponseSystemGivenCriteria( pszBaseFile, pszCustomName, criteriaSet, flCriteriaScore ); } @@ -3350,55 +948,3 @@ void DestroyCustomResponseSystems() { defaultresponsesytem.DestroyCustomResponseSystems(); } - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CResponseSystem::DumpRules() -{ - int c = m_Rules.Count(); - int i; - - for ( i = 0; i < c; i++ ) - { - Msg("%s\n", m_Rules.GetElementName( i ) ); - } -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CResponseSystem::DumpDictionary( const char *pszName ) -{ - Msg( "\nDictionary: %s\n", pszName ); - - int nRuleCount = m_Rules.Count(); - for ( int iRule = 0; iRule < nRuleCount; ++iRule ) - { - Msg(" Rule %d: %s\n", iRule, m_Rules.GetElementName( iRule ) ); - - Rule *pRule = &m_Rules[iRule]; - - int nCriteriaCount = pRule->m_Criteria.Count(); - for( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) - { - int iRuleCriteria = pRule->m_Criteria[iCriteria]; - Criteria *pCriteria = &m_Criteria[iRuleCriteria]; - Msg( " Criteria %d: %s %s\n", iCriteria, pCriteria->name, pCriteria->value ); - } - - int nResponseGroupCount = pRule->m_Responses.Count(); - for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) - { - int iRuleResponse = pRule->m_Responses[iResponseGroup]; - ResponseGroup *pResponseGroup = &m_Responses[iRuleResponse]; - - Msg( " ResponseGroup %d: %s\n", iResponseGroup, m_Responses.GetElementName( iRuleResponse ) ); - - int nResponseCount = pResponseGroup->group.Count(); - for ( int iResponse = 0; iResponse < nResponseCount; ++iResponse ) - { - Response *pResponse = &pResponseGroup->group[iResponse]; - Msg( " Response %d: %s\n", iResponse, pResponse->value ); - } - } - } -} diff --git a/src/game/server/AI_ResponseSystem.h b/src/game/server/AI_ResponseSystem.h index a7b3a7977..a558f79e7 100644 --- a/src/game/server/AI_ResponseSystem.h +++ b/src/game/server/AI_ResponseSystem.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -13,27 +13,14 @@ #pragma once #endif -#include "AI_Criteria.h" +#include "ai_criteria.h" +#include "../../public/responserules/response_types.h" -abstract_class IResponseFilter -{ -public: - virtual ~IResponseFilter(){} - virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ) = 0; -}; +// using ResponseRules::IResponseFilter; +// using ResponseRules::IResponseSystem; -abstract_class IResponseSystem -{ -public: - virtual ~IResponseSystem() {} - - virtual bool FindBestResponse( const AI_CriteriaSet& set, AI_Response& response, IResponseFilter *pFilter = NULL ) = 0; - virtual void GetAllResponses( CUtlVector *pResponses ) = 0; - virtual void PrecacheResponses( bool bEnable ) = 0; -}; - -IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ); -IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ); +ResponseRules::IResponseSystem *PrecacheCustomResponseSystem( const char *scriptfile ); +ResponseRules::IResponseSystem *BuildCustomResponseSystemGivenCriteria( const char *pszBaseFile, const char *pszCustomName, AI_CriteriaSet &criteriaSet, float flCriteriaScore ); void DestroyCustomResponseSystems(); class ISaveRestoreBlockHandler *GetDefaultResponseSystemSaveRestoreBlockHandler(); diff --git a/src/game/server/ai_basenpc.h b/src/game/server/ai_basenpc.h index 31c2a4ed6..7534f3676 100644 --- a/src/game/server/ai_basenpc.h +++ b/src/game/server/ai_basenpc.h @@ -64,7 +64,6 @@ class CBaseGrenade; class CBaseDoor; class CBasePropDoor; struct AI_Waypoint_t; -class AI_Response; class CBaseFilter; typedef CBitVec CAI_ScheduleBits; diff --git a/src/game/server/ai_behavior_lead.h b/src/game/server/ai_behavior_lead.h index d59a87d37..0bf4ad0a4 100644 --- a/src/game/server/ai_behavior_lead.h +++ b/src/game/server/ai_behavior_lead.h @@ -9,12 +9,13 @@ #include "simtimer.h" #include "ai_behavior.h" +#include "ai_speechconcept.h" #if defined( _WIN32 ) #pragma once #endif -typedef const char *AIConcept_t; +typedef CAI_Concept AIConcept_t; // Speak concepts #define TLK_LEAD_START "TLK_LEAD_START" diff --git a/src/game/server/ai_expresserfollowup.cpp b/src/game/server/ai_expresserfollowup.cpp new file mode 100644 index 000000000..d9722dec2 --- /dev/null +++ b/src/game/server/ai_expresserfollowup.cpp @@ -0,0 +1,464 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "ai_speech.h" + +#include "game.h" +#include "eventqueue.h" +#include "ai_basenpc.h" +#include "basemultiplayerplayer.h" +#include "ai_baseactor.h" +#include "sceneentity.h" +//#include "flex_expresser.h" +/* +#include "engine/ienginesound.h" +#include "keyvalues.h" +#include "ai_criteria.h" +#include "isaverestore.h" +#include "sceneentity.h" +*/ + + + +// memdbgon must be the last include file in a .cpp file!!! +#include + +static const char *GetResponseName( CBaseEntity *pEnt ) +{ + Assert( pEnt ); + if ( pEnt == NULL ) + return ""; + return STRING( pEnt->GetEntityName() ); +} + +// This is a tiny helper function for below -- what I'd use a lambda for, usually +static void DispatchComeback( CAI_ExpresserWithFollowup *pExpress, CBaseEntity *pSpeaker, CBaseEntity *pRespondent, AI_ResponseFollowup &followup ) +{ + AssertMsg(pSpeaker != NULL, "Response expressor somehow got called with a NULL Outer.\n"); + if ( !pRespondent ) + { + return; + } + + float delay = followup.followup_delay; + if (pSpeaker == pRespondent && delay < 0) + { + Warning("Response rule with a 'self' target specified negative delay, which isn't legal because that would make someone talk over himself."); + delay = 0; + } + + // Msg( "%s: Dispatch comeback about %s to %s\n", pSpeaker->GetBotString(), g_pConceptManager->GetTopicName( handle ), pRespondent->GetBotString() ); + + // build an input event that we will use to force the bot to talk through the IO system + variant_t value; + // Don't send along null contexts + if (followup.followup_contexts && followup.followup_contexts[0] != '\0') + { + value.SetString( MAKE_STRING( followup.followup_contexts ) ); + g_EventQueue.AddEvent( pRespondent, "AddContext", value, delay - 0.01, pSpeaker, pSpeaker ); + } + + /* + value.SetString(MAKE_STRING(followup.followup_concept)); + g_EventQueue.AddEvent( pRespondent, "SpeakResponseConcept", value, delay , pSpeaker, pSpeaker ); + */ + + AI_CriteriaSet criteria; + + // add in the FROM context so dispatchee knows was from me + const char * RESTRICT pszSpeakerName = GetResponseName( pSpeaker ); + criteria.AppendCriteria( "From", pszSpeakerName ); + // if a SUBJECT criteria is missing, put it back in. + if ( criteria.FindCriterionIndex( "Subject" ) == -1 ) + { + criteria.AppendCriteria( "Subject", pszSpeakerName ); + } + + // add in any provided contexts from the parameters onto the ones stored in the followup + criteria.Merge( followup.followup_contexts ); + + // This is kludgy and needs to be fixed in class hierarchy, but for now, try to guess at the most likely + // kinds of targets and dispatch to them. + if (CBaseMultiplayerPlayer *pPlayer = dynamic_cast(pRespondent)) + { + pPlayer->Speak( followup.followup_concept, &criteria ); + } + + else if (CAI_BaseActor *pActor = dynamic_cast(pRespondent)) + { + pActor->Speak( followup.followup_concept, &criteria ); + } +} + +#if 0 +//----------------------------------------------------------------------------- +// Purpose: Placeholder for rules based response system +// Input : concept - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CAI_ExpresserWithFollowup::Speak( AIConcept_t &concept, const char *modifiers /*= NULL*/, char *pszOutResponseChosen /* = NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AI_Response *result = SpeakFindResponse( concept, modifiers ); + if ( !result ) + { + return false; + } + + CNPC_CompanionBot *pBot = dynamic_cast(GetOuter()); + if ( pBot ) + { + pBot->SetConversationTopic( g_pConceptManager->GetTopic( handle ) ); + pBot->SetLastSpeaker( g_pConceptManager->GetSpeaker( handle ) ); + // Msg( "%s: Conversing about %s\n", pBot->GetBotString(), g_pConceptManager->GetTopicName( handle ) ); + } + + SpeechMsg( GetOuter(), "%s (%x) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), g_pConceptManager->GetConcept( handle ), gpGlobals->curtime ); + + bool spoke = SpeakDispatchResponse( handle, result, filter ); + if ( pszOutResponseChosen ) + { + result->GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} +#endif + + +// Work out the character from the "subject" context. +// Right now, this is a simple find by entity name search. +// But you can define arbitrary subject names, like L4D does +// for "biker", "manager", etc. +static CBaseEntity *AscertainSpeechSubjectFromContext( AI_Response *response, AI_CriteriaSet &criteria, const char *pContextName ) +{ + const char *subject = criteria.GetValue( criteria.FindCriterionIndex( pContextName ) ); + if (subject) + { + + return gEntList.FindEntityByName( NULL, subject ); + + } + else + { + return NULL; + } +} + +// TODO: Currently uses awful stricmp. Use symbols! Once I know which ones we want, that is. +static CResponseQueue::CFollowupTargetSpec_t ResolveFollowupTargetToEntity( AIConcept_t &concept, AI_CriteriaSet &criteria, const char * RESTRICT szTarget, AI_Response * RESTRICT response = NULL ) +{ + + + + if ( Q_stricmp(szTarget, "self") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_SPECIFIC, concept.GetSpeaker() ); + } + else if ( Q_stricmp(szTarget, "subject") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( AscertainSpeechSubjectFromContext( response, criteria, "Subject" ) ); + } + else if ( Q_stricmp(szTarget, "from") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( AscertainSpeechSubjectFromContext( response, criteria, "From" ) ); + } + else if ( Q_stricmp(szTarget, "any") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_ANY, concept.GetSpeaker() ); + } + else if ( Q_stricmp(szTarget, "all") == 0 ) + { + return CResponseQueue::CFollowupTargetSpec_t( kDRT_ALL ); + } + + // last resort, try a named lookup + else if ( CBaseEntity *pSpecific = gEntList.FindEntityByName(NULL, szTarget) ) // it could be anything + { + return CResponseQueue::CFollowupTargetSpec_t( pSpecific ); + } + + Warning("Couldn't resolve response target %s\n", szTarget ); + return CResponseQueue::CFollowupTargetSpec_t(); // couldn't resolve. +} + + +// TODO: Currently uses awful stricmp. Use symbols! Once I know which ones we want, that is. +static CResponseQueue::CFollowupTargetSpec_t ResolveFollowupTargetToEntity( AIConcept_t &concept, AI_CriteriaSet &criteria, AI_Response * RESTRICT response, AI_ResponseFollowup * RESTRICT followup ) +{ + const char * RESTRICT szTarget = followup->followup_target; + const CResponseQueue::CFollowupTargetSpec_t INVALID; // default: invalid result + if ( szTarget == NULL ) + return INVALID; + else + return ResolveFollowupTargetToEntity( concept, criteria, szTarget, response ); +} + + +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 */ ) +{ + VPROF("CAI_Expresser::Speak"); + if ( IsSpeechGloballySuppressed() ) + { + return false; + } + + concept.SetSpeaker(GetOuter()); + AI_CriteriaSet criteria; + GatherCriteria(&criteria, concept, modifiers); + GetOuter()->ModifyOrAppendDerivedCriteria(criteria); + AI_Response result; + if ( !FindResponse( result, concept, &criteria ) ) + { + if (chet_debug_idle.GetBool()) + { + + const char *name = GetOuter()->GetDebugName(); + + Msg( "TLK_IDLE: %s did not FindResponse\n", name ); + } + return false; + } + else + { + if (chet_debug_idle.GetBool()) + { + + + const char *name = GetOuter()->GetDebugName(); + + Msg( "TLK_IDLE: %s SUCCESSFUL FindResponse\n", name ); + } + } + + SpeechMsg( GetOuter(), "%s (%x) 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 ); + if ( pszOutResponseChosen ) + { + result.GetResponse( pszOutResponseChosen, bufsize ); + } + + return spoke; +} + +extern ISoundEmitterSystemBase* soundemitterbase; + +static float GetSpeechDurationForResponse( const AI_Response * RESTRICT response, const char *szActorModel) +{ + switch (response->GetType()) + { + case ResponseRules::RESPONSE_SCENE: + { + char szScene[MAX_PATH]; + soundemitterbase->GenderExpandString(szActorModel, response->GetResponsePtr(), szScene, MAX_PATH); + return GetSceneSpeechDuration(szScene); + } + break; + default: + break; + } + + return 0.f; +} + +//----------------------------------------------------------------------------- +// Purpose: Dispatches the result +// Input : *response - +//----------------------------------------------------------------------------- +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() ) + { + concept.SetSpeaker(GetOuter()); + } + + bool bInterrupted = IsSpeaking(); + bool bSuc = CAI_Expresser::SpeakDispatchResponse( concept, response, criteria, filter ); + if (!bSuc) + { + return false; + } + + if ( bInterrupted ) + { + g_ResponseQueueManager.GetQueue()->RemoveSpeechQueuedFor( GetOuter() ); + } + + // Record my followup details so that I may defer its use til end of the speech + AI_ResponseFollowup * RESTRICT followup = response->GetParams()->m_pFollowup; + if ( followup ) + { + if ( followup->followup_entityiotarget && followup->followup_entityioinput ) + if ( criteria ) + { + CBaseEntity * RESTRICT pTarget = gEntList.FindEntityByName( NULL, followup->followup_entityiotarget ); + if ( pTarget ) + { + g_EventQueue.AddEvent( pTarget, followup->followup_entityioinput, variant_t(), followup->followup_entityiodelay, GetOuter(), GetOuter() ); + } + } + if ( followup->IsValid() ) + { + // 11th hour change: rather than trigger followups from the end of a VCD, + // instead fire it from the end of the last speech event in the VCD, because + // there's a multisecond facial relax delay built into the scene. + // The speech length is stored in the cache, so we can post the followup now. + if ( response->GetType() == ResponseRules::RESPONSE_SCENE && + followup->followup_delay >= 0 ) + { + float fTimeToLastSpeech = GetSpeechDurationForResponse( response, GetOuter()->GetModelName().ToCStr()); + // failsafe + if ( fTimeToLastSpeech > 0 ) + { + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( concept, *criteria, response, followup ), + fTimeToLastSpeech + followup->followup_delay, GetOuter() ); + } + else // error + { + // old way, copied from "else" below + m_pPostponedFollowup = followup; + if ( criteria ) + m_followupTarget = ResolveFollowupTargetToEntity( concept, *criteria, response, m_pPostponedFollowup ); + else + { + AI_CriteriaSet tmpCriteria; + m_followupTarget = ResolveFollowupTargetToEntity( concept, tmpCriteria, response, m_pPostponedFollowup ); + } + } + } + else if ( followup->followup_delay < 0 ) + { + // a negative delay has a special meaning. Usually the comeback dispatches after + // the currently said line is finished; the delay is added to that, to provide a + // pause between when character A finishes speaking and B begins. + // A negative delay (-n) actually means "dispatch the comeback n seconds + // after I start talking". + // In this case we do not need to postpone the followup; we just throw it directly + // into the queue. + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( concept, *criteria, response, followup ), + -followup->followup_delay, GetOuter() ); + } + else if ( response->GetType() == ResponseRules::RESPONSE_PRINT ) + { // zero-duration responses dispatch immediately via the queue (must be the queue bec. + // the m_pPostponedFollowup will never trigger) + DispatchFollowupThroughQueue( followup->followup_concept, followup->followup_contexts, + ResolveFollowupTargetToEntity( concept, *criteria, response, followup ), + followup->followup_delay, GetOuter() ); + } + else + { + // this is kind of a quick patch to immediately deal with the issue of null criteria + // (arose while branching to main) without replumbing a bunch of stuff -- to be fixed + // 5.13.08 egr + m_pPostponedFollowup = followup; + if ( criteria ) + m_followupTarget = ResolveFollowupTargetToEntity( concept, *criteria, response, m_pPostponedFollowup ); + else + { + AI_CriteriaSet tmpCriteria; + m_followupTarget = ResolveFollowupTargetToEntity( concept, tmpCriteria, response, m_pPostponedFollowup ); + } + } + } + } + + + return bSuc; +} + +// This is a gimmick used when a negative delay is specified in a followup, which is a shorthand +// for "this many seconds after the beginning of the line" rather than "this may seconds after the end +// of the line", eg to create a THEN rule when two characters talk over each other. +// It's static to avoid accidental use of the postponed followup/target members. +void CAI_ExpresserWithFollowup::DispatchFollowupThroughQueue( const AIConcept_t &concept, + const char * RESTRICT criteriaStr, + const CResponseQueue::CFollowupTargetSpec_t &target, + float delay, + CBaseEntity * RESTRICT pOuter + ) +{ + AI_CriteriaSet criteria; + // Don't add my own criteria! GatherCriteria( &criteria, followup.followup_concept, followup.followup_contexts ); + + criteria.AppendCriteria( "From", STRING( pOuter->GetEntityName() ) ); + + criteria.Merge( criteriaStr ); + g_ResponseQueueManager.GetQueue()->Add( concept, &criteria, gpGlobals->curtime + delay, target, pOuter ); +} + +//----------------------------------------------------------------------------- +// Purpose: Handles the new concept objects +//----------------------------------------------------------------------------- +void CAI_ExpresserWithFollowup::SpeakDispatchFollowup( AI_ResponseFollowup &followup ) +{ + if ( !m_followupTarget.IsValid() ) + return; + + // If a specific entity target is given, use the old pathway for now + if ( m_followupTarget.m_iTargetType == kDRT_SPECIFIC && followup.followup_delay == 0 ) + { + CBaseEntity *pTarget = m_followupTarget.m_hHandle.Get(); + if (!pTarget) + { + return; + } + DispatchComeback( this, GetOuter(), pTarget, followup ); + } + else + { + DispatchFollowupThroughQueue( followup.followup_concept, followup.followup_contexts, m_followupTarget, followup.followup_delay, GetOuter() ); + } + // clear out the followup member just in case. + m_pPostponedFollowup = NULL; + m_followupTarget.m_iTargetType = kDRT_MAX; +} + +void CAI_ExpresserWithFollowup::OnSpeechFinished() +{ + if (m_pPostponedFollowup && m_pPostponedFollowup->IsValid()) + { + return SpeakDispatchFollowup(*m_pPostponedFollowup); + } +} + + + + +void CC_RR_ForceConcept_f( const CCommand &args ) +{ + if ( args.ArgC() < 3 ) + { + Msg("USAGE: rr_forceconcept \"criteria1:value1,criteria2:value2,...\"\n"); + return; + } + + AI_CriteriaSet criteria; + if ( args.ArgC() >= 3 ) + { + const char *criteriastring = args[3]; + criteria.Merge( criteriastring ); + } + + AIConcept_t concept( args[2] ); + QueueSpeak( concept, ResolveFollowupTargetToEntity( concept, criteria, args[1] ), criteria ); +} + + +static ConCommand rr_forceconcept( "rr_forceconcept", CC_RR_ForceConcept_f, + "fire a response concept directly at a given character.\n" + "USAGE: rr_forceconcept \"criteria1:value1,criteria2:value2,...\"\n" + "criteria values are optional.\n" + + , FCVAR_CHEAT ); diff --git a/src/game/server/ai_playerally.cpp b/src/game/server/ai_playerally.cpp index a60969913..a777c0d3c 100644 --- a/src/game/server/ai_playerally.cpp +++ b/src/game/server/ai_playerally.cpp @@ -138,12 +138,17 @@ bool ConceptStringLessFunc( const string_t &lhs, const string_t &rhs ) return CaselessStringLessThan( STRING(lhs), STRING(rhs) ); } +bool ConceptInfoStringLessFunc(const AIConcept_t& lhs, const AIConcept_t& rhs) +{ + return CaselessStringLessThan(lhs.GetStringConcept(), rhs.GetStringConcept()); +} + //----------------------------------------------------------------------------- class CConceptInfoMap : public CUtlMap { public: CConceptInfoMap() : - CUtlMap( CaselessStringLessThan ) + CUtlMap(ConceptInfoStringLessFunc) { for ( int i = 0; i < ARRAYSIZE(g_ConceptInfos); i++ ) { @@ -575,7 +580,7 @@ void CAI_PlayerAlly::PrescheduleThink( void ) if ( SelectNonCombatSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); + SpeakDispatchResponse( selection.concept.c_str(), &selection.Response ); m_flNextIdleSpeechTime = gpGlobals->curtime + RandomFloat( 20,30 ); } else @@ -715,7 +720,7 @@ bool CAI_PlayerAlly::SelectInterjection() if ( SelectIdleSpeech( &selection ) ) { SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); + SpeakDispatchResponse( selection.concept.c_str(), &selection.Response ); return true; } } @@ -764,10 +769,10 @@ void CAI_PlayerAlly::PostSpeakDispatchResponse( AIConcept_t concept, AI_Response { //#ifdef HL2_EPISODIC CAI_AllySpeechManager *pSpeechManager = GetAllySpeechManager(); - ConceptInfo_t *pConceptInfo = pSpeechManager->GetConceptInfo( concept ); + ConceptInfo_t *pConceptInfo = pSpeechManager->GetConceptInfo( concept.GetStringConcept()); if ( pConceptInfo && (pConceptInfo->flags & AICF_QUESTION) && GetSpeechTarget() ) { - bool bSaidHelloToNPC = !Q_strcmp(concept, "TLK_HELLO_NPC"); + bool bSaidHelloToNPC = !Q_strcmp(concept.GetStringConcept(), "TLK_HELLO_NPC"); float duration = GetExpresser()->GetSemaphoreAvailableTime(this) - gpGlobals->curtime; @@ -775,11 +780,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(), concept.GetStringConcept() ); } 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(), concept.GetStringConcept()); } NDebugOverlay::HorzArrow( GetAbsOrigin(), GetSpeechTarget()->GetAbsOrigin(), 8, 0, 255, 0, 64, true, duration ); } @@ -915,7 +920,7 @@ void CAI_PlayerAlly::AnswerQuestion( CAI_PlayerAlly *pQuestioner, int iQARandomN } SetSpeechTarget( selection.hSpeechTarget ); - SpeakDispatchResponse( selection.concept.c_str(), selection.Response ); + SpeakDispatchResponse( selection.concept.c_str(), &selection.Response ); // Prevent idle speech for a while DeferAllIdleSpeech( random->RandomFloat( TALKER_DEFER_IDLE_SPEAK_MIN, TALKER_DEFER_IDLE_SPEAK_MAX ), GetSpeechTarget()->MyNPCPointer() ); @@ -1042,7 +1047,7 @@ void CAI_PlayerAlly::StartTask( const Task_t *pTask ) case TASK_TALKER_SPEAK_PENDING: if ( !m_PendingConcept.empty() ) { - SpeakDispatchResponse( m_PendingConcept.c_str(), m_PendingResponse ); + SpeakDispatchResponse( m_PendingConcept.c_str(), &m_PendingResponse ); m_PendingConcept.erase(); TaskComplete(); } @@ -1764,7 +1769,7 @@ bool CAI_PlayerAlly::RespondedTo( const char *ResponseConcept, bool bForce, bool if ( bCancelScene ) RemoveActorFromScriptedScenes( this, false ); - return SpeakDispatchResponse( ResponseConcept, response ); + return SpeakDispatchResponse( ResponseConcept, &response ); } return false; diff --git a/src/game/server/ai_speech.cpp b/src/game/server/ai_speech.cpp index 7661eb9c2..f486f9cb6 100644 --- a/src/game/server/ai_speech.cpp +++ b/src/game/server/ai_speech.cpp @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -10,12 +10,14 @@ #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" +#include "ai_squad.h" // memdbgon must be the last include file in a .cpp file!!! #include @@ -29,6 +31,8 @@ inline void SpeechMsg( ... ) {} #define DebuggingSpeech() (false) #endif +using namespace ResponseRules; + extern ConVar rr_debugresponses; //----------------------------------------------------------------------------- @@ -38,33 +42,21 @@ CAI_TimedSemaphore g_AIFoesTalkSemaphore; ConceptHistory_t::~ConceptHistory_t() { - delete response; - response = NULL; } ConceptHistory_t::ConceptHistory_t( const ConceptHistory_t& src ) { timeSpoken = src.timeSpoken; - response = NULL; - if ( src.response ) - { - response = new AI_Response( *src.response ); - } + m_response = src.m_response ; } ConceptHistory_t& ConceptHistory_t::operator =( const ConceptHistory_t& src ) { - if ( this != &src ) - { - timeSpoken = src.timeSpoken; + if ( this == &src ) + return *this; - delete response; - response = NULL; - if ( src.response ) - { - response = new AI_Response( *src.response ); - } - } + timeSpoken = src.timeSpoken; + m_response = src.m_response ; return *this; } @@ -88,18 +80,18 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps pSave->StartBlock(); { + // Write element name pSave->WriteString( ch->GetElementName( i ) ); // Write data pSave->WriteAll( pHistory ); - // Write response blob - bool hasresponse = !!pHistory->response; + bool hasresponse = !pHistory->m_response.IsEmpty() ; pSave->WriteBool( &hasresponse ); if ( hasresponse ) { - pSave->WriteAll( pHistory->response ); + pSave->WriteAll( &pHistory->m_response ); } // TODO: Could blat out pHistory->criteria pointer here, if it's needed } @@ -117,7 +109,6 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps { char conceptname[ 512 ]; conceptname[ 0 ] = 0; - ConceptHistory_t history; pRestore->StartBlock(); @@ -127,11 +118,16 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps pRestore->ReadAll( &history ); bool hasresponse = false; + pRestore->ReadBool( &hasresponse ); if ( hasresponse ) { - history.response = new AI_Response(); - pRestore->ReadAll( history.response ); + history.m_response; + pRestore->ReadAll( &history.m_response ); + } + else + { + history.m_response.Invalidate(); } } @@ -150,7 +146,7 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps } } } - + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) { } @@ -164,6 +160,84 @@ class CConceptHistoriesDataOps : public CDefSaveRestoreOps CConceptHistoriesDataOps g_ConceptHistoriesSaveDataOps; +///////////////////////////////////////////////// +// context operators +RR::CApplyContextOperator RR::sm_OpCopy(0); // " +RR::CIncrementOperator RR::sm_OpIncrement(2); // "++" +RR::CDecrementOperator RR::sm_OpDecrement(2); // "--" +RR::CToggleOperator RR::sm_OpToggle(1); // "!" + +RR::CApplyContextOperator *RR::CApplyContextOperator::FindOperator( const char *pContextString ) +{ + if ( !pContextString || pContextString[0] == 0 ) + { + return &sm_OpCopy; + } + + if ( pContextString[0] == '+' && pContextString [1] == '+' && pContextString[2] != '\0' ) + { + return &sm_OpIncrement; + } + else if ( pContextString[0] == '-' && pContextString [1] == '-' && pContextString[2] != '\0' ) + { + return &sm_OpDecrement; + } + else if ( pContextString[0] == '!' ) + { + return &sm_OpToggle; + } + else + { + return &sm_OpCopy; + } +} + +// default is just copy +bool RR::CApplyContextOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator && pNewValue && pNewValBufSize > 0 ); + Assert( m_nSkipChars == 0 ); + if ( pOperator ) + { + V_strncpy( pNewValue, pOperator, pNewValBufSize ); + } + else + { + *pNewValue = 0; + } + return true; +} + +bool RR::CIncrementOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '+' && pOperator[1] == '+' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld+nInc ); + return true; +} + +bool RR::CDecrementOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '-' && pOperator[1] == '-' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + int nInc = V_atoi( pOperator+m_nSkipChars ); + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld-nInc ); + return true; +} + +bool RR::CToggleOperator::Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ) +{ + Assert( pOperator[0] == '!' ); + // parse out the old value as a numeric + int nOld = pOldValue ? V_atoi(pOldValue) : 0; + V_snprintf( pNewValue, pNewValBufSize, "%d", nOld ? 0 : 1 ); + return true; +} + + //----------------------------------------------------------------------------- // // CLASS: CAI_Expresser @@ -210,83 +284,186 @@ int CAI_Expresser::GetVoicePitch() const static int g_nExpressers; #endif +/* +inline bool ShouldBeInExpresserQueue( CBaseFlex *pOuter ) +{ + return true; // return IsTerrorPlayer( pOuter, TEAM_SURVIVOR ); +} +*/ + CAI_Expresser::CAI_Expresser( CBaseFlex *pOuter ) : m_pOuter( pOuter ), m_pSink( NULL ), m_flStopTalkTime( 0 ), - m_flLastTimeAcceptedSpeak( 0 ), m_flBlockedTalkTime( 0 ), m_flStopTalkTimeWithoutDelay( 0 ), - m_voicePitch( 100 ) + m_voicePitch( 100 ), + m_flLastTimeAcceptedSpeak( 0 ) { #ifdef DEBUG g_nExpressers++; #endif + if (m_pOuter) + { + // register me with the global expresser queue. + + // L4D: something a little ass backwards is happening here. We only want + // survivors to be in the queue. However, the team number isn't + // specified yet. So, we actually need to do this in the player's ChangeTeam. + g_ResponseQueueManager.GetQueue()->AddExpresserHost(m_pOuter); + + } } CAI_Expresser::~CAI_Expresser() { m_ConceptHistories.Purge(); - CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( GetOuter() ); - if ( pSemaphore ) + CBaseFlex *RESTRICT outer = GetOuter(); + if ( outer ) { - if ( pSemaphore->GetOwner() == GetOuter() ) - pSemaphore->Release(); + CAI_TimedSemaphore *pSemaphore = GetMySpeechSemaphore( outer ); + if ( pSemaphore ) + { + if ( pSemaphore->GetOwner() == outer ) + pSemaphore->Release(); #ifdef DEBUG - g_nExpressers--; - if ( g_nExpressers == 0 && pSemaphore->GetOwner() ) - DevMsg( 2, "Speech semaphore being held by non-talker entity\n" ); + g_nExpressers--; + if ( g_nExpressers == 0 && pSemaphore->GetOwner() ) + DevMsg( 2, "Speech semaphore being held by non-talker entity\n" ); #endif + } + + g_ResponseQueueManager.GetQueue()->RemoveExpresserHost(outer); } } -//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_Expresser::TestAllResponses() { IResponseSystem *pResponseSystem = GetOuter()->GetResponseSystem(); if ( pResponseSystem ) { - CUtlVector responses; - + CUtlVector responses; pResponseSystem->GetAllResponses( &responses ); for ( int i = 0; i < responses.Count(); i++ ) { - const char *szResponse = responses[i]->GetResponsePtr(); + char response[ 256 ]; + responses[i].GetResponse( response, sizeof( response ) ); - Msg( "Response: %s\n", szResponse ); - SpeakDispatchResponse( "", *responses[i] ); + Msg( "Response: %s\n", response ); + AIConcept_t concept; + SpeakDispatchResponse( concept, &responses[i], NULL ); } } } +//----------------------------------------------------------------------------- +void CAI_Expresser::SetOuter( CBaseFlex *pOuter ) +{ + // if we're changing outers (which is a strange thing to do) + // unregister the old one from the queue. + if ( m_pOuter && ( m_pOuter != pOuter ) ) + { + AssertMsg2( false, "Expresser is switching its Outer from %s to %s. Why?", m_pOuter->GetDebugName(), pOuter->GetDebugName() ); + // unregister me with the global expresser queue + g_ResponseQueueManager.GetQueue()->RemoveExpresserHost(m_pOuter); + } + + m_pOuter = pOuter; +} + //----------------------------------------------------------------------------- static const int LEN_SPECIFIC_SCENE_MODIFIER = strlen( AI_SPECIFIC_SCENE_MODIFIER ); + +// This function appends "Global world" criteria that are always added to +// any character doing any match. This represents global concepts like weather, who's +// alive, etc. +static void ModifyOrAppendGlobalCriteria( AI_CriteriaSet * RESTRICT outputSet ) +{ + return; +} + + +void CAI_Expresser::GatherCriteria( AI_CriteriaSet * RESTRICT outputSet, const AIConcept_t &concept, const char * RESTRICT modifiers ) +{ + // Always include the concept name + outputSet->AppendCriteria( "concept", concept, CONCEPT_WEIGHT ); + +#if 1 + outputSet->Merge( modifiers ); +#else + // Always include any optional modifiers + if ( modifiers != NULL ) + { + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + outputSet->AppendCriteria( key, value, CONCEPT_WEIGHT ); + } + } + } +#endif + + // include any global criteria + ModifyOrAppendGlobalCriteria( outputSet ); + + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( *outputSet ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( *outputSet ); + } +} + //----------------------------------------------------------------------------- // Purpose: Searches for a possible response // Input : concept - // NULL - // Output : AI_Response //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +// 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 ) { + VPROF("CAI_Expresser::FindResponse"); IResponseSystem *rs = GetOuter()->GetResponseSystem(); if ( !rs ) { Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return NULL; + } + + // if I'm dead, I can't possibly match dialog. + if ( !GetOuter()->IsAlive() ) + { return false; } +#if 0 // this is the old technique, where we always gathered criteria in this function AI_CriteriaSet set; // Always include the concept name set.AppendCriteria( "concept", concept, CONCEPT_WEIGHT ); -#ifndef HL2_LAZUL + // Always include any optional modifiers - if ( modifiers ) + if ( modifiers != NULL ) { char copy_modifiers[ 255 ]; const char *pCopy; @@ -298,7 +475,7 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con while( pCopy ) { - pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL ); + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); if( *key && *value ) { @@ -306,7 +483,7 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con } } } -#endif + // Let our outer fill in most match criteria GetOuter()->ModifyOrAppendCriteria( set ); @@ -317,45 +494,154 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con if( pPlayer ) pPlayer->ModifyOrAppendPlayerCriteria( set ); } +#else + AI_CriteriaSet localCriteriaSet; // put it on the stack so we don't deal with new/delete + if (criteria == NULL) + { + GatherCriteria( &localCriteriaSet, concept, NULL ); + criteria = &localCriteriaSet; + } +#endif + + /// intercept any deferred criteria that are being sent to world + AI_CriteriaSet worldWritebackCriteria; + AI_CriteriaSet::InterceptWorldSetContexts( criteria, &worldWritebackCriteria ); + + // Now that we have a criteria set, ask for a suitable response + bool found = rs->FindBestResponse( *criteria, outResponse, this ); + + if ( rr_debugresponses.GetInt() == 4 ) + { + if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) + { + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } + + if ( found ) + { + char response[ 256 ]; + outResponse.GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, (const char*)concept, response ); + } + else + { + Warning( "RESPONSERULES: %s spoke '%s'. Found no matching response.\n", pszName, (const char*)concept ); + } + } + } + + if ( !found ) + { + return false; + } + else if ( worldWritebackCriteria.GetCount() > 0 ) + { + Assert( CBaseEntity::Instance( INDEXENT( 0 ) )->IsWorld( ) ); + worldWritebackCriteria.WriteToEntity( CBaseEntity::Instance( INDEXENT( 0 ) ) ); + } + + if ( outResponse.IsEmpty() ) + { + // AssertMsg2( false, "RR: %s got empty but valid response for %s", GetOuter()->GetDebugName(), concept.GetStringConcept() ); + return false; + } + else + { + return true; + } +} + +#if 0 +//----------------------------------------------------------------------------- +// Purpose: Searches for a possible response; writes it into a response passed as +// parameter rather than new'ing one up. +// Input : concept - +// NULL - +// Output : bool : true on success, false on fail +//----------------------------------------------------------------------------- +AI_Response *CAI_Expresser::SpeakFindResponse( AI_Response *result, AIConcept_t &concept, AI_CriteriaSet *criteria ) +{ + Assert(response); + + IResponseSystem *rs = GetOuter()->GetResponseSystem(); + if ( !rs ) + { + Assert( !"No response system installed for CAI_Expresser::GetOuter()!!!" ); + return NULL; + } + +#if 0 + AI_CriteriaSet set; + // Always include the concept name + set.AppendCriteria( "concept", concept, CONCEPT_WEIGHT ); -#ifdef HL2_LAZUL // Always include any optional modifiers - if (modifiers) + if ( modifiers != NULL ) { - char copy_modifiers[255]; + char copy_modifiers[ 255 ]; const char *pCopy; - char key[128] = { 0 }; - char value[128] = { 0 }; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; - Q_strncpy(copy_modifiers, modifiers, sizeof(copy_modifiers)); + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); pCopy = copy_modifiers; - while (pCopy) + while( pCopy ) { - pCopy = SplitContext(pCopy, key, sizeof(key), value, sizeof(value), NULL); + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); - if (*key && *value) + if( *key && *value ) { - set.AppendCriteria(key, value, CONCEPT_WEIGHT); + set.AppendCriteria( key, value, CONCEPT_WEIGHT ); } } } -#endif + + // Let our outer fill in most match criteria + GetOuter()->ModifyOrAppendCriteria( set ); + + // Append local player criteria to set, but not if this is a player doing the talking + if ( !GetOuter()->IsPlayer() ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); + if( pPlayer ) + pPlayer->ModifyOrAppendPlayerCriteria( set ); + } +#else + AI_CriteriaSet &set = *criteria; +#endif // Now that we have a criteria set, ask for a suitable response - bool found = rs->FindBestResponse( set, outResponse, this ); + bool found = rs->FindBestResponse( set, *result, this ); - if ( rr_debugresponses.GetInt() == 3 ) + if ( rr_debugresponses.GetInt() == 4 ) { if ( ( GetOuter()->MyNPCPointer() && GetOuter()->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT ) || GetOuter()->IsPlayer() ) { - const char *pszName = GetOuter()->IsPlayer() ? - ((CBasePlayer*)GetOuter())->GetPlayerName() : GetOuter()->GetDebugName(); + const char *pszName; + if ( GetOuter()->IsPlayer() ) + { + pszName = ((CBasePlayer*)GetOuter())->GetPlayerName(); + } + else + { + pszName = GetOuter()->GetDebugName(); + } if ( found ) { - const char *szReponse = outResponse.GetResponsePtr(); - Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, concept, szReponse ); + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); + + Warning( "RESPONSERULES: %s spoke '%s'. Found response '%s'.\n", pszName, concept, response ); } else { @@ -365,32 +651,81 @@ bool CAI_Expresser::SpeakFindResponse( AI_Response &outResponse, AIConcept_t con } if ( !found ) + { + //Assert( !"rs->FindBestResponse: Returned a NULL AI_Response!" ); return false; + } - const char *szReponse = outResponse.GetResponsePtr(); - if ( !szReponse[0] ) - return false; + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); - if ( ( outResponse.GetOdds() < 100 ) && ( random->RandomInt( 1, 100 ) <= outResponse.GetOdds() ) ) + if ( !response[0] ) + { return false; + } return true; } +#endif //----------------------------------------------------------------------------- // Purpose: Dispatches the result // Input : *response - //----------------------------------------------------------------------------- -bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response, 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 ) ); + + if (response[0] == '$') + { + const char* context = response + 1; + const char* replace = nullptr; + + int iSymbol = criteria->FindCriterionIndex(context); + if (criteria->IsValidIndex(iSymbol)) + { + replace = criteria->GetValue(iSymbol); + } + + if (replace) + { + DevMsg("Replacing %s with %s...\n", response, replace); + Q_strncpy(response, replace, sizeof(response)); + + // Precache it now because it may not have been precached before + switch (result->GetType()) + { + case RESPONSE_SPEAK: + { + GetOuter()->PrecacheScriptSound(response); + } + break; + + case RESPONSE_SCENE: + { + // TODO: Gender handling? + PrecacheInstancedScene(response); + } + break; + } + } + } + + float delay = result->GetDelay(); + bool spoke = false; - float delay = response.GetDelay(); - const char *szResponse = response.GetResponsePtr(); - soundlevel_t soundlevel = response.GetSoundLevel(); - if ( IsSpeaking() && concept[0] != 0 ) + soundlevel_t soundlevel = result->GetSoundLevel(); + + if ( IsSpeaking() && concept[0] != 0 && result->GetType() != ResponseRules::RESPONSE_PRINT ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); + const char *entityName = STRING( GetOuter()->GetEntityName() ); + if ( GetOuter()->IsPlayer() ) + { + entityName = ToBasePlayer( GetOuter() )->GetPlayerName(); + } + DevMsg( 2, "SpeakDispatchResponse: Entity ( %i/%s ) already speaking, forcing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); // Tracker 15911: Can break the game if we stop an imported map placed lcs here, so only // cancel actor out of instanced scripted scenes. ywb @@ -399,53 +734,68 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res if ( IsRunningScriptedScene( GetOuter() ) ) { - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), concept ); + DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) refusing to speak due to scene entity, tossing '%s'\n", GetOuter()->entindex(), entityName ? entityName : "UNKNOWN", (const char*)concept ); return false; } } - switch ( response.GetType() ) + switch ( result->GetType() ) { default: - case RESPONSE_NONE: + case ResponseRules::RESPONSE_NONE: break; - case RESPONSE_SPEAK: - if ( !response.ShouldntUseScene() ) - { - // This generates a fake CChoreoScene wrapping the sound.txt name - spoke = SpeakAutoGeneratedScene( szResponse, delay ); - } - else + case ResponseRules::RESPONSE_SPEAK: { - float speakTime = GetResponseDuration( response ); - GetOuter()->EmitSound( szResponse ); + if ( !result->ShouldntUseScene() ) + { + // This generates a fake CChoreoScene wrapping the sound.txt name + spoke = SpeakAutoGeneratedScene( response, delay ); + } + else + { + float speakTime = GetResponseDuration( result ); + GetOuter()->EmitSound( response ); - DevMsg( "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), szResponse ); - NoteSpeaking( speakTime, delay ); - spoke = true; + DevMsg( 2, "SpeakDispatchResponse: Entity ( %i/%s ) playing sound '%s'\n", GetOuter()->entindex(), STRING( GetOuter()->GetEntityName() ), response ); + NoteSpeaking( speakTime, delay ); + spoke = true; + } } break; - case RESPONSE_SENTENCE: - spoke = ( -1 != SpeakRawSentence( szResponse, delay, VOL_NORM, soundlevel ) ) ? true : false; + case ResponseRules::RESPONSE_SENTENCE: + { + spoke = ( -1 != SpeakRawSentence( response, delay, VOL_NORM, soundlevel ) ) ? true : false; + } break; - case RESPONSE_SCENE: - spoke = SpeakRawScene( szResponse, delay, &response, filter ); + case ResponseRules::RESPONSE_SCENE: + { + spoke = SpeakRawScene( response, delay, result, filter ); + } break; - case RESPONSE_RESPONSE: - // This should have been recursively resolved already - Assert( 0 ); + case ResponseRules::RESPONSE_RESPONSE: + { + // This should have been recursively resolved already + Assert( 0 ); + } break; - case RESPONSE_PRINT: - if ( g_pDeveloper->GetInt() > 0 ) + case ResponseRules::RESPONSE_PRINT: { - Vector vPrintPos; - GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, szResponse, true, 1.5 ); - spoke = true; + if ( g_pDeveloper->GetInt() > 0 ) + { + Vector vPrintPos; + GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); + NDebugOverlay::Text( vPrintPos, response, true, 1.5 ); + } + spoke = true; + } + break; + case ResponseRules::RESPONSE_ENTITYIO: + { + return FireEntIOFromResponse( response, GetOuter() ); } break; } @@ -453,30 +803,107 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res if ( spoke ) { m_flLastTimeAcceptedSpeak = gpGlobals->curtime; - if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response.GetType() != RESPONSE_PRINT ) + if ( DebuggingSpeech() && g_pDeveloper->GetInt() > 0 && response && result->GetType() != ResponseRules::RESPONSE_PRINT ) { Vector vPrintPos; GetOuter()->CollisionProp()->NormalizedToWorldSpace( Vector(0.5,0.5,1.0f), &vPrintPos ); - NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", concept, szResponse ), true, 1.5 ); + NDebugOverlay::Text( vPrintPos, CFmtStr( "%s: %s", (const char*)concept, response ), true, 1.5 ); } - if ( response.IsApplyContextToWorld() ) + if (result->GetContext()) { - CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( 0 ) ); - if ( pEntity ) + const char* pszContext = result->GetContext(); + + int iContextFlags = result->GetContextFlags(); + if (iContextFlags & APPLYCONTEXT_SQUAD) + { + CAI_BaseNPC* pNPC = GetOuter()->MyNPCPointer(); + if (pNPC && pNPC->GetSquad()) + { + AISquadIter_t iter; + CAI_BaseNPC* pSquadmate = pNPC->GetSquad()->GetFirstMember(&iter); + while (pSquadmate) + { + pSquadmate->AddContext(pszContext); + + pSquadmate = pNPC->GetSquad()->GetNextMember(&iter); + } + } + } + if (iContextFlags & APPLYCONTEXT_ENEMY) + { + CBaseEntity* pEnemy = GetOuter()->GetEnemy(); + if (pEnemy) + { + pEnemy->AddContext(pszContext); + } + } + if (iContextFlags & APPLYCONTEXT_WORLD) { - pEntity->AddContext( response.GetContext() ); + CBaseEntity* pEntity = CBaseEntity::Instance(engine->PEntityOfEntIndex(0)); + if (pEntity) + { + pEntity->AddContext(pszContext); + } + } + if (iContextFlags == 0 || iContextFlags & APPLYCONTEXT_SELF) + { + GetOuter()->AddContext(pszContext); } } - else + SetSpokeConcept( concept, result ); + } + else + { + } + + return spoke; +} + +bool CAI_Expresser::FireEntIOFromResponse( char *response, CBaseEntity *pInitiator ) +{ + // find the space-separator in the response name, then split into entityname, input, and parameter + // may barf in linux; there, should make some StringTokenizer() class that wraps the strtok_s behavior, etc. + char *pszEntname; + char *pszInput; + char *pszParam; + char *strtokContext; + + pszEntname = strtok_s( response, " ", &strtokContext ); + if ( !pszEntname ) + { + Warning( "Response was entityio but had bad value %s\n", response ); + return false; + } + + pszInput = strtok_s( NULL, " ", &strtokContext ); + if ( !pszInput ) + { + Warning( "Response was entityio but had bad value %s\n", response ); + return false; + } + + pszParam = strtok_s( NULL, " ", &strtokContext ); + + // poke entity io + CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, pszEntname, pInitiator ); + if ( !pTarget ) + { + Msg( "Response rule targeted %s with entityio, but that doesn't exist.\n", pszEntname ); + // but this is actually a legit use case, so return true (below). + } + else + { + // pump the action into the target + variant_t variant; + if ( pszParam ) { - GetOuter()->AddContext( response.GetContext() ); + variant.SetString( MAKE_STRING(pszParam) ); } + pTarget->AcceptInput( pszInput, pInitiator, pInitiator, variant, 0 ); - SetSpokeConcept( concept, &response ); } - - return spoke; + return true; } //----------------------------------------------------------------------------- @@ -484,33 +911,45 @@ bool CAI_Expresser::SpeakDispatchResponse( AIConcept_t concept, AI_Response& res // Input : *response - // Output : float //----------------------------------------------------------------------------- -float CAI_Expresser::GetResponseDuration( AI_Response& response ) +float CAI_Expresser::GetResponseDuration( AI_Response *result ) { - const char *szResponse = response.GetResponsePtr(); + Assert( result ); + char response[ 256 ]; + result->GetResponse( response, sizeof( response ) ); - switch ( response.GetType() ) + switch ( result->GetType() ) { - default: - case RESPONSE_NONE: + case ResponseRules::RESPONSE_SPEAK: + { + return GetOuter()->GetSoundDuration( response, STRING( GetOuter()->GetModelName() ) ); + } break; - - case RESPONSE_SPEAK: - return GetOuter()->GetSoundDuration( szResponse, STRING( GetOuter()->GetModelName() ) ); - - case RESPONSE_SENTENCE: - Assert( 0 ); - return 999.0f; - - case RESPONSE_SCENE: - return GetSceneDuration( szResponse ); - - case RESPONSE_RESPONSE: - // This should have been recursively resolved already - Assert( 0 ); + case ResponseRules::RESPONSE_SENTENCE: + { + Assert( 0 ); + return 999.0f; + } break; - - case RESPONSE_PRINT: - return 1.0; + case ResponseRules::RESPONSE_SCENE: + { + return GetSceneDuration( response ); + } + break; + case ResponseRules::RESPONSE_RESPONSE: + { + // This should have been recursively resolved already + Assert( 0 ); + } + break; + case ResponseRules::RESPONSE_PRINT: + { + return 1.0; + } + break; + default: + case ResponseRules::RESPONSE_NONE: + case ResponseRules::RESPONSE_ENTITYIO: + return 0.0f; } return 0.0f; @@ -521,22 +960,44 @@ float CAI_Expresser::GetResponseDuration( 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; + GatherCriteria(&criteria, concept, modifiers); + + return Speak( concept, &criteria, pszOutResponseChosen, bufsize, filter ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CAI_Expresser::Speak( AIConcept_t &concept, AI_CriteriaSet * RESTRICT criteria, char *pszOutResponseChosen , size_t bufsize , IRecipientFilter *filter ) { - AI_Response response; - bool result = SpeakFindResponse( response, concept, modifiers ); - if ( !result ) + VPROF("CAI_Expresser::Speak"); + if ( IsSpeechGloballySuppressed() ) + { return false; + } - SpeechMsg( GetOuter(), "%s (%p) spoke %s (%f)\n", STRING(GetOuter()->GetEntityName()), GetOuter(), concept, gpGlobals->curtime ); + GetOuter()->ModifyOrAppendDerivedCriteria(*criteria); + AI_Response result; + if ( !FindResponse( result, concept, criteria ) ) + { + return false; + } - bool spoke = SpeakDispatchResponse( concept, response, filter ); + SpeechMsg( GetOuter(), "%s (%x) 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 ); if ( pszOutResponseChosen ) { - const char *szResponse = response.GetResponsePtr(); - Q_strncpy( pszOutResponseChosen, szResponse, bufsize ); + result.GetResponse( pszOutResponseChosen, bufsize ); } - + return spoke; } @@ -550,7 +1011,7 @@ bool CAI_Expresser::SpeakRawScene( const char *pszScene, float delay, AI_Respons { SpeechMsg( GetOuter(), "SpeakRawScene( %s, %f) %f\n", pszScene, delay, sceneLength ); -#if defined( HL2_EPISODIC ) || defined( TF_DLL ) || defined( TF_CLASSIC ) +#if defined( HL2_EPISODIC ) char szInstanceFilename[256]; GetOuter()->GenderExpandString( pszScene, szInstanceFilename, sizeof( szInstanceFilename ) ); // Only mark ourselves as speaking if the scene has speech @@ -604,9 +1065,6 @@ int CAI_Expresser::SpeakRawSentence( const char *pszSentence, float delay, float } else { - if (pszSentence[0] == '~') - pszSentence++; - sentenceIndex = SENTENCEG_PlayRndSz( GetOuter()->NetworkProp()->edict(), pszSentence, volume, soundlevel, 0, GetVoicePitch() ); } @@ -730,14 +1188,14 @@ bool CAI_Expresser::CanSpeakConcept( AIConcept_t concept ) ConceptHistory_t *history = &m_ConceptHistories[iter]; Assert( history ); - AI_Response *response = history->response; - if ( !response ) + const AI_Response &response = history->m_response; + if ( response.IsEmpty() ) return true; - if ( response->GetSpeakOnce() ) + if ( response.GetSpeakOnce() ) return false; - float respeakDelay = response->GetRespeakDelay(); + float respeakDelay = response.GetRespeakDelay(); if ( respeakDelay != 0.0f ) { @@ -782,12 +1240,10 @@ void CAI_Expresser::SetSpokeConcept( AIConcept_t concept, AI_Response *response, ConceptHistory_t *slot = &m_ConceptHistories[ idx ]; slot->timeSpoken = gpGlobals->curtime; - // Update response info if ( response ) { - delete slot->response; - slot->response = new AI_Response( *response ); + slot->m_response = *response; } if ( bCallback ) @@ -818,7 +1274,7 @@ void CAI_Expresser::DumpHistories() bool CAI_Expresser::IsValidResponse( ResponseType_t type, const char *pszValue ) { - if ( type == RESPONSE_SCENE ) + if ( type == ResponseRules::RESPONSE_SCENE ) { char szInstanceFilename[256]; GetOuter()->GenderExpandString( pszValue, szInstanceFilename, sizeof( szInstanceFilename ) ); @@ -833,7 +1289,7 @@ bool CAI_Expresser::IsValidResponse( ResponseType_t type, const char *pszValue ) CAI_TimedSemaphore *CAI_Expresser::GetMySpeechSemaphore( CBaseEntity *pNpc ) { if ( !pNpc->MyNPCPointer() ) - return NULL; + return false; return (pNpc->MyNPCPointer()->IsPlayerAlly() ? &g_AIFriendliesTalkSemaphore : &g_AIFoesTalkSemaphore ); } @@ -846,23 +1302,26 @@ void CAI_Expresser::SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ) if ( !DebuggingSpeech() ) return; - char string[ 2048 ]; - va_list argptr; - va_start( argptr, pszFormat ); - Q_vsnprintf( string, sizeof(string), pszFormat, argptr ); - va_end( argptr ); - if ( pFlex->MyNPCPointer() ) { - DevMsg( pFlex->MyNPCPointer(), "%s", string ); + + DevMsg( pFlex->MyNPCPointer(), CFmtStr( &pszFormat ) ); } else { - DevMsg( "%s", string ); + DevMsg( CFmtStr( &pszFormat ) ); } - UTIL_LogPrintf( "%s", string ); + UTIL_LogPrintf( (char *) ( (const char *) CFmtStr( &pszFormat ) ) ); } +//----------------------------------------------------------------------------- +// Purpose: returns true when l4d is in credits screen or some other +// speech-forbidden state +//----------------------------------------------------------------------------- +bool CAI_Expresser::IsSpeechGloballySuppressed() +{ + return false; +} //----------------------------------------------------------------------------- @@ -883,16 +1342,7 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C if ( pSpeaker->GetEnemy() ) { - CBaseEntity* pEnemy = pSpeaker->GetEnemy(); - set.AppendCriteria( "enemy", pEnemy->GetClassname() ); - set.AppendCriteria("enemyclass", g_pGameRules->AIClassText(pEnemy->Classify())); - float healthfrac = 0.0f; - if (pEnemy->GetMaxHealth() > 0) - { - healthfrac = (float)pEnemy->GetHealth() / (float)pEnemy->GetMaxHealth(); - } - - set.AppendCriteria("enemyhealthfrac", UTIL_VarArgs("%.3f", healthfrac)); + set.AppendCriteria( "enemy", pSpeaker->GetEnemy()->GetClassname() ); set.AppendCriteria( "timesincecombat", "-1" ); } else @@ -915,7 +1365,7 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C set.AppendCriteria( "weapon", "none" ); } - CBasePlayer *pPlayer = pSpeaker->GetBestPlayer(); + CBasePlayer *pPlayer = AI_GetSinglePlayer(); if ( pPlayer ) { Vector distance = pPlayer->GetAbsOrigin() - pSpeaker->GetAbsOrigin(); @@ -948,18 +1398,9 @@ void CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( CAI_BaseNPC *pSpeaker, AI_C } //----------------------------------------------------------------------------- - -//============================================================================= -// HPE_BEGIN: -// [Forrest] Remove npc_speakall from Counter-Strike. -//============================================================================= -#ifndef CSTRIKE_DLL -extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer ); +extern CBaseEntity* FindPickerEntity(CBasePlayer* pPlayer); CON_COMMAND( npc_speakall, "Force the npc to try and speak all their responses" ) { - if ( !UTIL_IsCommandIssuedByServerAdmin() ) - return; - CBaseEntity *pEntity; if ( args[1] && *args[1] ) @@ -972,9 +1413,9 @@ CON_COMMAND( npc_speakall, "Force the npc to try and speak all their responses" } else { - pEntity = FindPickerEntity( UTIL_GetCommandClient() ); + pEntity = UTIL_GetCommandClient() ? FindPickerEntity(UTIL_GetCommandClient()) : NULL; } - + if ( pEntity ) { CAI_BaseNPC *pNPC = pEntity->MyNPCPointer(); @@ -989,14 +1430,9 @@ CON_COMMAND( npc_speakall, "Force the npc to try and speak all their responses" } } } -#endif -//============================================================================= -// HPE_END -//============================================================================= - //----------------------------------------------------------------------------- -CMultiplayer_Expresser::CMultiplayer_Expresser( CBaseFlex *pOuter ) : CAI_Expresser( pOuter ) +CMultiplayer_Expresser::CMultiplayer_Expresser( CBaseFlex *pOuter ) : CAI_ExpresserWithFollowup( pOuter ) { m_bAllowMultipleScenes = false; } @@ -1020,4 +1456,4 @@ void CMultiplayer_Expresser::AllowMultipleScenes() void CMultiplayer_Expresser::DisallowMultipleScenes() { m_bAllowMultipleScenes = false; -} \ No newline at end of file +} diff --git a/src/game/server/ai_speech.h b/src/game/server/ai_speech.h index fa173c1ed..12e51e0f8 100644 --- a/src/game/server/ai_speech.h +++ b/src/game/server/ai_speech.h @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // @@ -11,15 +11,20 @@ #include "utlmap.h" #include "soundflags.h" -#include "AI_ResponseSystem.h" +#include "AI_Criteria.h" +#include "ai_responsesystem.h" #include "utldict.h" +#include "ai_speechconcept.h" #if defined( _WIN32 ) #pragma once #endif class KeyValues; -class AI_CriteriaSet; + +using ResponseRules::ResponseType_t; +using ResponseRules::AI_ResponseFollowup; + //----------------------------------------------------------------------------- // Purpose: Used to share a global resource or prevent a system stepping on @@ -63,8 +68,6 @@ extern CAI_TimedSemaphore g_AIFoesTalkSemaphore; // Constants -const float AIS_DEF_MIN_DELAY = 2.8; // Minimum amount of time an NPCs will wait after someone has spoken before considering speaking again -const float AIS_DEF_MAX_DELAY = 3.2; // Maximum amount of time an NPCs will wait after someone has spoken before considering speaking again const float AIS_NO_DELAY = 0; const soundlevel_t AIS_DEF_SNDLVL = SNDLVL_TALKING; #define AI_NULL_CONCEPT NULL @@ -92,17 +95,20 @@ const soundlevel_t AIS_DEF_SNDLVL = SNDLVL_TALKING; // An id that represents the core meaning of a spoken phrase, // eventually to be mapped to a sentence group or scene +#if AI_CONCEPTS_ARE_STRINGS typedef const char *AIConcept_t; - inline bool CompareConcepts( AIConcept_t c1, AIConcept_t c2 ) { return ( (void *)c1 == (void *)c2 || ( c1 && c2 && Q_stricmp( c1, c2 ) == 0 ) ); } +#else +typedef CAI_Concept AIConcept_t; +inline bool CompareConcepts( AIConcept_t c1, AIConcept_t c2 ) +{ + return c1.m_iConcept == c2.m_iConcept; +} +#endif -//------------------------------------- -// Specifies and stores the base timing and attentuation values for concepts -// -class AI_Response; //----------------------------------------------------------------------------- // CAI_Expresser @@ -127,7 +133,7 @@ struct ConceptHistory_t DECLARE_SIMPLE_DATADESC(); ConceptHistory_t(float timeSpoken = -1 ) - : timeSpoken( timeSpoken ), response( NULL ) + : timeSpoken( timeSpoken ), m_response( ) { } @@ -135,13 +141,13 @@ struct ConceptHistory_t ConceptHistory_t& operator = ( const ConceptHistory_t& src ); ~ConceptHistory_t(); - + float timeSpoken; - AI_Response *response; + AI_Response m_response; }; //------------------------------------- -class CAI_Expresser : public IResponseFilter +class CAI_Expresser : public ResponseRules::IResponseFilter { public: CAI_Expresser( CBaseFlex *pOuter = NULL ); @@ -156,18 +162,32 @@ class CAI_Expresser : public 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, 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 ); + // 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 + // to SpeakFindResponse. + void GatherCriteria( AI_CriteriaSet *outputCritera, const AIConcept_t &concept, const char *modifiers ); // These two methods allow looking up a response and dispatching it to be two different steps - bool SpeakFindResponse( AI_Response &response, AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response &response, IRecipientFilter *filter = NULL ); - float GetResponseDuration( AI_Response &response ); + // AI_Response *SpeakFindResponse( AIConcept_t concept, const char *modifiers = NULL ); + // 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 ); + float GetResponseDuration( AI_Response *response ); virtual int SpeakRawSentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); bool SemaphoreIsAvailable( CBaseEntity *pTalker ); float GetSemaphoreAvailableTime( CBaseEntity *pTalker ); + virtual void OnSpeechFinished() {}; + + // This function can be overriden by games to suppress speech altogether during glue screens, etc + static bool IsSpeechGloballySuppressed(); + // -------------------------------- virtual bool IsSpeaking(); @@ -194,6 +214,12 @@ class CAI_Expresser : public IResponseFilter // Force the NPC to release the semaphore & clear next speech time void ForceNotSpeaking( void ); + // helper used in dealing with RESPONSE_ENTITYIO + // response is the output of AI_Response::GetName + // note: the response string will get stomped on (by strtok) + // returns false on failure (eg, couldn't match parse contents) + static bool FireEntIOFromResponse( char *response, CBaseEntity *pInitiator ); + protected: CAI_TimedSemaphore *GetMySpeechSemaphore( CBaseEntity *pNpc ); @@ -203,7 +229,7 @@ class CAI_Expresser : public IResponseFilter void DumpHistories(); - void SpeechMsg( CBaseEntity *pFlex, PRINTF_FORMAT_STRING const char *pszFormat, ... ); + void SpeechMsg( CBaseEntity *pFlex, const char *pszFormat, ... ); // -------------------------------- @@ -241,7 +267,7 @@ class CAI_Expresser : public IResponseFilter // -------------------------------- // public: - virtual void SetOuter( CBaseFlex *pOuter ) { m_pOuter = pOuter; } + void SetOuter( CBaseFlex *pOuter ); CBaseFlex * GetOuter() { return m_pOuter; } const CBaseFlex * GetOuter() const { return m_pOuter; } @@ -250,22 +276,6 @@ class CAI_Expresser : public IResponseFilter CHandle m_pOuter; }; -class CMultiplayer_Expresser : public CAI_Expresser -{ -public: - CMultiplayer_Expresser( CBaseFlex *pOuter = NULL ); - //~CMultiplayer_Expresser(); - - virtual bool IsSpeaking(); - - void AllowMultipleScenes(); - void DisallowMultipleScenes(); - -private: - bool m_bAllowMultipleScenes; - -}; - //----------------------------------------------------------------------------- // // An NPC base class to assist a branch of the inheritance graph @@ -281,12 +291,21 @@ class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink virtual void NoteSpeaking( float duration, float delay ); virtual bool Speak( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + virtual bool Speak( AIConcept_t concept, AI_CriteriaSet *pCriteria, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); + + void GatherCriteria( AI_CriteriaSet *outputCritera, const AIConcept_t &concept, const char *modifiers ); // These two methods allow looking up a response and dispatching it to be two different steps - bool SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers = NULL ); - bool SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ); - virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) { return; } - float GetResponseDuration( AI_Response& response ); + bool SpeakFindResponse(AI_Response& outResponse, 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 SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria = NULL ); + virtual void PostSpeakDispatchResponse( AIConcept_t concept, AI_Response *response ) { return; } + float GetResponseDuration( AI_Response *response ); float GetTimeSpeechComplete() const { return this->GetExpresser()->GetTimeSpeechComplete(); } @@ -302,7 +321,7 @@ class CAI_ExpresserHost : public BASE_NPC, protected CAI_ExpresserSink int PlaySentence( const char *pszSentence, float delay, float volume = VOL_NORM, soundlevel_t soundlevel = SNDLVL_TALKING, CBaseEntity *pListener = NULL ); virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); - virtual IResponseSystem *GetResponseSystem(); + virtual ResponseRules::IResponseSystem *GetResponseSystem(); // Override of base entity response input handler virtual void DispatchResponse( const char *conceptName ); }; @@ -324,6 +343,21 @@ inline bool CAI_ExpresserHost::Speak( AIConcept_t concept, const char return this->GetExpresser()->Speak( concept, modifiers, pszOutResponseChosen, bufsize, filter ); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::Speak( AIConcept_t concept, AI_CriteriaSet *pCriteria, char *pszOutResponseChosen /*=NULL*/, size_t bufsize /* = 0 */, IRecipientFilter *filter /* = NULL */ ) +{ + AssertOnce( this->GetExpresser()->GetOuter() == this ); + CAI_Expresser * const RESTRICT pExpresser = this->GetExpresser(); + concept.SetSpeaker(this); + // add in any local criteria to the one passed on the command line. + pExpresser->GatherCriteria( pCriteria, concept, NULL ); + // call the "I have aleady gathered criteria" version of Expresser::Speak + return pExpresser->Speak( concept, pCriteria, pszOutResponseChosen, bufsize, filter ); +} + + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template @@ -341,36 +375,86 @@ inline void CAI_ExpresserHost::ModifyOrAppendCriteria( AI_CriteriaSet& { BaseClass::ModifyOrAppendCriteria( criteriaSet ); + if ( this->MyNPCPointer() ) { CAI_ExpresserHost_NPC_DoModifyOrAppendCriteria( this->MyNPCPointer(), criteriaSet ); } + } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline IResponseSystem *CAI_ExpresserHost::GetResponseSystem() +inline ResponseRules::IResponseSystem *CAI_ExpresserHost::GetResponseSystem() { - extern IResponseSystem *g_pResponseSystem; + extern ResponseRules::IResponseSystem *g_pResponseSystem; // Expressive NPC's use the general response system return g_pResponseSystem; } + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline void CAI_ExpresserHost::GatherCriteria( AI_CriteriaSet *outputCriteria, const AIConcept_t &concept, const char *modifiers ) +{ + return this->GetExpresser()->GatherCriteria( outputCriteria, concept, modifiers ); +} + + +#if 1 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline bool CAI_ExpresserHost::SpeakFindResponse(AI_Response& outResponse, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +{ + AI_CriteriaSet criteria; + GatherCriteria(&criteria, concept, modifiers); + return FindResponse(outResponse, concept, &criteria); +} +#endif + +#if 0 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +template +inline AI_Response *CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept, AI_CriteriaSet *criteria /*= NULL*/ ) +{ + return this->GetExpresser()->SpeakFindResponse( concept, criteria ); +} + + +//----------------------------------------------------------------------------- +// In this case we clearly don't care to hang on to the criteria, so make a convenience +// class that generates a one off. +//----------------------------------------------------------------------------- +template +inline AI_Response * CAI_ExpresserHost::SpeakFindResponse( AIConcept_t concept ) +{ + AI_CriteriaSet criteria; + GatherCriteria( &criteria, concept, NULL ); + return this->GetExpresser()->SpeakFindResponse( concept, &criteria ); +} +#endif + + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakFindResponse( AI_Response& response, AIConcept_t concept, const char *modifiers /*= NULL*/ ) +inline bool CAI_ExpresserHost::FindResponse( AI_Response &outResponse, AIConcept_t &concept, AI_CriteriaSet *criteria ) { - return this->GetExpresser()->SpeakFindResponse( response, concept, modifiers ); + return this->GetExpresser()->FindResponse( outResponse, concept, criteria ); } + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t concept, AI_Response& response ) +inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t concept, AI_Response *response, AI_CriteriaSet *criteria ) { - if ( this->GetExpresser()->SpeakDispatchResponse( concept, response ) ) + if ( this->GetExpresser()->SpeakDispatchResponse( concept, response, criteria ) ) { PostSpeakDispatchResponse( concept, response ); return true; @@ -382,7 +466,7 @@ inline bool CAI_ExpresserHost::SpeakDispatchResponse( AIConcept_t conc //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- template -inline float CAI_ExpresserHost::GetResponseDuration( AI_Response& response ) +inline float CAI_ExpresserHost::GetResponseDuration( AI_Response *response ) { return this->GetExpresser()->GetResponseDuration( response ); } @@ -398,4 +482,160 @@ inline void CAI_ExpresserHost::DispatchResponse( const char *conceptNa //----------------------------------------------------------------------------- +/// A shim under CAI_ExpresserHost you can use when deriving a new expresser +/// host type under CAI_BaseNPC. This does the extra step of declaring an m_pExpresser +/// member and initializing it from CreateComponents(). If your BASE_NPC class isn't +/// actually an NPC, then CreateComponents() never gets called and you won't have +/// an expresser created. +/// Note: you still need to add m_pExpresser to the Datadesc for your derived type. +/// This is because I couldn't figure out how to make a templatized datadesc declaration +/// that works generically on the template type. +template +class CAI_ExpresserHostWithData : public CAI_ExpresserHost +{ + DECLARE_CLASS_NOFRIEND( CAI_ExpresserHostWithData, CAI_ExpresserHost ); + +public: + CAI_ExpresserHostWithData( ) : m_pExpresser(NULL) {}; + + virtual CAI_Expresser *GetExpresser() { return m_pExpresser; } + const CAI_Expresser *GetExpresser() const { return m_pExpresser; } + + virtual bool CreateComponents() + { + return BaseClass::CreateComponents() && ( CreateExpresser() != NULL ); + } + +protected: + EXPRESSER_TYPE *CreateExpresser( void ) + { + AssertMsg1( m_pExpresser == NULL, "Tried to double-initialize expresser in %s\n", GetDebugName() ); + m_pExpresser = new EXPRESSER_TYPE(this); + if ( !m_pExpresser) + { + AssertMsg1( false, "Creating an expresser failed in %s\n", GetDebugName() ); + return NULL; + } + + m_pExpresser->Connect(this); + return m_pExpresser; + } + + virtual ~CAI_ExpresserHostWithData( void ) + { + delete m_pExpresser; + m_pExpresser = NULL; + } + + EXPRESSER_TYPE *m_pExpresser; +}; + +/// response rules +namespace RR +{ + /// some applycontext clauses have operators preceding them, + /// like ++1 which means "take the current value and increment it + /// by one". These classes detect these cases and do the appropriate + /// thing. + class CApplyContextOperator + { + public: + inline CApplyContextOperator( int nSkipChars ) : m_nSkipChars(nSkipChars) {}; + + /// perform whatever this operator does upon the given context value. + /// Default op is simply to copy old to new. + /// pOldValue should be the currently set value of the context. May be NULL meaning no prior value. + /// pOperator the value that applycontext says to set + /// pNewValue a pointer to a buffer where the real new value will be writ. + /// returns true on success; false on failure (eg, tried to increment a + /// non-numeric value). + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + + /// This is the function that should be called from outside, + /// fed the input string, it'll select the right operator + /// to apply. + static CApplyContextOperator *FindOperator( const char *pContextString ); + + protected: + int m_nSkipChars; // how many chars to "skip" in the value string to get past the op specifier to the actual value + // eg, "++3" has a m_nSkipChars of 2, because the op string "++" is two characters. + }; + + class CIncrementOperator : public CApplyContextOperator + { + public: + inline CIncrementOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + class CDecrementOperator : public CApplyContextOperator + { + public: + inline CDecrementOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + class CToggleOperator : public CApplyContextOperator + { + public: + inline CToggleOperator( int nSkipChars ) : CApplyContextOperator(nSkipChars) {}; + virtual bool Apply( const char *pOldValue, const char *pOperator, char *pNewValue, int pNewValBufSize ); + }; + + // the singleton operators + extern CApplyContextOperator sm_OpCopy; + extern CIncrementOperator sm_OpIncrement; + extern CDecrementOperator sm_OpDecrement; + extern CToggleOperator sm_OpToggle; +}; + + +//----------------------------------------------------------------------------- +#include "ai_speechqueue.h" + +//----------------------------------------------------------------------------- +// A kind of AI Expresser that can dispatch a follow-up speech event when it +// finishes speaking. +//----------------------------------------------------------------------------- +class CAI_ExpresserWithFollowup : public CAI_Expresser +{ +public: + 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 void SpeakDispatchFollowup( AI_ResponseFollowup &followup ); + + virtual void OnSpeechFinished(); + + typedef CAI_Expresser BaseClass; +protected: + static void DispatchFollowupThroughQueue( const AIConcept_t &concept, + const char *criteriaStr, + const CResponseQueue::CFollowupTargetSpec_t &target, + float delay, + CBaseEntity * RESTRICT pOuter ); + + AI_ResponseFollowup *m_pPostponedFollowup; // TODO: save/restore + CResponseQueue::CFollowupTargetSpec_t m_followupTarget; +}; + +class CMultiplayer_Expresser : public CAI_ExpresserWithFollowup +{ +public: + CMultiplayer_Expresser( CBaseFlex *pOuter = NULL ); + //~CMultiplayer_Expresser(); + + virtual bool IsSpeaking(); + + void AllowMultipleScenes(); + void DisallowMultipleScenes(); + +private: + bool m_bAllowMultipleScenes; + +}; + + #endif // AI_SPEECH_H diff --git a/src/game/server/ai_speechconcept.cpp b/src/game/server/ai_speechconcept.cpp new file mode 100644 index 000000000..c0ae8e36b --- /dev/null +++ b/src/game/server/ai_speechconcept.cpp @@ -0,0 +1,28 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "ai_speechconcept.h" + +#ifdef GAME_DLL +#include "game.h" +#include "ai_basenpc.h" +#include "sceneentity.h" +#endif + +#include "engine/ienginesound.h" +#include "keyvalues.h" +#include "ai_criteria.h" +#include "isaverestore.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include + + +// empty \ No newline at end of file diff --git a/src/game/server/ai_speechconcept.h b/src/game/server/ai_speechconcept.h new file mode 100644 index 000000000..41a3cc60b --- /dev/null +++ b/src/game/server/ai_speechconcept.h @@ -0,0 +1,45 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Class data for an AI Concept, an atom of response-driven dialog. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SPEECHCONCEPT_H +#define AI_SPEECHCONCEPT_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "../../public/responserules/response_types.h" + +class CAI_Concept : public ResponseRules::CRR_Concept +{ +public: + CAI_Concept() {}; + // construct concept from a string. + CAI_Concept(const char *fromString) : CRR_Concept(fromString) {} ; + + // get/set BS + inline EHANDLE GetSpeaker() const { return m_hSpeaker; } + inline void SetSpeaker(EHANDLE val) { m_hSpeaker = val; } + + /* + inline EHANDLE GetTarget() const { return m_hTarget; } + inline void SetTarget(EHANDLE val) { m_hTarget = val; } + inline EHANDLE GetTopic() const { return m_hTopic; } + inline void SetTopic(EHANDLE val) { m_hTopic = val; } + */ + +protected: + EHANDLE m_hSpeaker; + + /* + EHANDLE m_hTarget; + EHANDLE m_hTopic; + */ +}; + + +#endif diff --git a/src/game/server/ai_speechqueue.cpp b/src/game/server/ai_speechqueue.cpp new file mode 100644 index 000000000..5f9a2e0df --- /dev/null +++ b/src/game/server/ai_speechqueue.cpp @@ -0,0 +1,479 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "basemultiplayerplayer.h" +#include "ai_baseactor.h" +#include "ai_speech.h" +//#include "flex_expresser.h" +// memdbgon must be the last include file in a .cpp file!!! +#include + +extern ConVar ai_debug_speech; +#define DebuggingSpeech() ai_debug_speech.GetBool() +extern ConVar rr_debugresponses; + +ConVar rr_followup_maxdist( "rr_followup_maxdist", "1800", FCVAR_CHEAT, "'then ANY' or 'then ALL' response followups will be dispatched only to characters within this distance." ); + +/////////////////////////////////////////////////////////////////////////////// +// RESPONSE QUEUE DATA STRUCTURE +/////////////////////////////////////////////////////////////////////////////// + +CResponseQueue::CResponseQueue( int queueSize ) : m_Queue(queueSize), m_ExpresserTargets(8,8) +{}; + +/// Add a deferred response. +void CResponseQueue::Add( const AIConcept_t &concept, ///< concept to dispatch + const AI_CriteriaSet * RESTRICT contexts, + float time, ///< when to dispatch it. You can specify a time of zero to mean "immediately." + const CFollowupTargetSpec_t &targetspec, + CBaseEntity *pIssuer + ) +{ + // Add a response. + AssertMsg( m_Queue.Count() < AI_RESPONSE_QUEUE_SIZE, "AI Response queue overfilled." ); + QueueType_t::IndexLocalType_t idx = m_Queue.AddToTail(); + m_Queue[idx].Init( concept, contexts, time, targetspec, pIssuer ); +} + + +/// Remove a deferred response matching the concept and issuer. +void CResponseQueue::Remove( const AIConcept_t &concept, ///< concept to dispatch + CBaseEntity * const RESTRICT pIssuer ///< the entity issuing the response, if one exists. + ) RESTRICT +{ + // walk through the queue until we find a response matching the concept and issuer, then strike it. + QueueType_t::IndexLocalType_t idx = m_Queue.Head(); + while (idx != m_Queue.InvalidIndex()) + { + CDeferredResponse &response = m_Queue[idx]; + QueueType_t::IndexLocalType_t previdx = idx; // advance the index immediately because we may be deleting the "current" element + idx = m_Queue.Next(idx); // is now the next index + if ( CompareConcepts( response.m_concept, concept ) && // if concepts match and + ( !pIssuer || ( response.m_hIssuer.Get() == pIssuer ) ) // issuer is null, or matches the one in the response + ) + { + m_Queue.Remove(previdx); + } + } +} + + +void CResponseQueue::RemoveSpeechQueuedFor( const CBaseEntity *pSpeaker ) +{ + // walk through the queue until we find a response matching the speaker, then strike it. + // because responses are dispatched from inside a loop that is already walking through the + // queue, it's not safe to actually remove the elements. Instead, quash it by replacing it + // with a null event. + + for ( QueueType_t::IndexLocalType_t idx = m_Queue.Head() ; + idx != m_Queue.InvalidIndex() ; + idx = m_Queue.Next(idx) ) // is now the next index + { + CDeferredResponse &response = m_Queue[idx]; + if ( response.m_Target.m_hHandle.Get() == pSpeaker ) + { + response.Quash(); + } + } +} + +// TODO: use a more compact representation. +void CResponseQueue::DeferContextsFromCriteriaSet( DeferredContexts_t &contextsOut, const AI_CriteriaSet * RESTRICT criteriaIn ) +{ + contextsOut.Reset(); + if (criteriaIn) + { + contextsOut.Merge(criteriaIn); + } +} + +void CResponseQueue::PerFrameDispatch() +{ +failsafe: + // Walk through the list, find any messages whose time has come, and dispatch them. Then remove them. + QueueType_t::IndexLocalType_t idx = m_Queue.Head(); + while (idx != m_Queue.InvalidIndex()) + { + // do we need to dispatch this concept? + CDeferredResponse &response = m_Queue[idx]; + QueueType_t::IndexLocalType_t previdx = idx; // advance the index immediately because we may be deleting the "current" element + idx = m_Queue.Next(idx); // is now the next index + + if ( response.IsQuashed() ) + { + // we can delete this entry now + m_Queue.Remove(previdx); + } + else if ( response.m_fDispatchTime <= gpGlobals->curtime ) + { + // dispatch. we've had bugs where dispatches removed things from inside the queue; + // so, as a failsafe, if the queue length changes as a result, start over. + int oldLength = m_Queue.Count(); + DispatchOneResponse(response); + if ( m_Queue.Count() < oldLength ) + { + AssertMsg( false, "Response queue length changed in non-reentrant way! FAILSAFE TRIGGERED" ); + goto failsafe; // ick + } + + // we can delete this entry now + m_Queue.Remove(previdx); + } + } +} + + +/// Add an expressor owner to this queue. +void CResponseQueue::AddExpresserHost(CBaseEntity *host) +{ + EHANDLE ehost(host); + // see if it's in there already + if (m_ExpresserTargets.HasElement(ehost)) + { + AssertMsg1(false, "Tried to add %s to response queue when it was already in there.", host->GetDebugName()); + } + else + { + // zip through the queue front to back, first see if there's any invalid handles to replace + int count = m_ExpresserTargets.Count(); + for (int i = 0 ; i < count ; ++i ) + { + if ( !m_ExpresserTargets[i].Get() ) + { + m_ExpresserTargets[i] = ehost; + return; + } + } + + // if we're down here we didn't find one to replace, so append the host to the end. + m_ExpresserTargets.AddToTail(ehost); + } +} + +/// Remove an expresser host from this queue. +void CResponseQueue::RemoveExpresserHost(CBaseEntity *host) +{ + int idx = m_ExpresserTargets.Find(host); + if (idx == -1) + { + // AssertMsg1(false, "Tried to remove %s from response queue, but it's not in there to begin with!", host->GetDebugName() ); + } + else + { + m_ExpresserTargets.FastRemove(idx); + } +} + +/// Get the expresser for a base entity. +/// TODO: Kind of an ugly hack until I get the class hierarchy straightened out. +static CAI_Expresser *InferExpresserFromBaseEntity(CBaseEntity * RESTRICT pEnt) +{ + if ( CBaseMultiplayerPlayer *pPlayer = dynamic_cast(pEnt) ) + { + return pPlayer->GetExpresser(); + } + else if ( CAI_BaseActor *pActor = dynamic_cast(pEnt) ) + { + return pActor->GetExpresser(); + } + //else if ( CFlexExpresser *pFlex = dynamic_cast(pEnt) ) + //{ + // return pFlex->GetExpresser(); + //} + else + { + return NULL; + } +} + + +void CResponseQueue::CDeferredResponse::Quash() +{ + m_Target = CFollowupTargetSpec_t(); + m_fDispatchTime = 0; +} + +bool CResponseQueue::DispatchOneResponse(CDeferredResponse &response) +{ + // find the target. + CBaseEntity * RESTRICT pTarget = NULL; + AI_CriteriaSet &deferredCriteria = response.m_contexts; + CAI_Expresser * RESTRICT pEx = NULL; + CBaseEntity * RESTRICT pIssuer = response.m_hIssuer.Get(); // MAY BE NULL + float followupMaxDistSq; + { + //CFlexExpresser * RESTRICT pOrator = CFlexExpresser::AsFlexExpresser( pIssuer ); + //if ( pOrator ) + //{ + // // max dist is overridden. "0" means infinite distance (for orators only), + // // anything else is a finite distance. + // if ( pOrator->m_flThenAnyMaxDist > 0 ) + // { + // followupMaxDistSq = pOrator->m_flThenAnyMaxDist * pOrator->m_flThenAnyMaxDist; + // } + // else + // { + // followupMaxDistSq = FLT_MAX; + // } + // + //} + //else + { + followupMaxDistSq = rr_followup_maxdist.GetFloat(); // square of max audibility distance + followupMaxDistSq *= followupMaxDistSq; + } + } + + switch (response.m_Target.m_iTargetType) + { + case kDRT_SPECIFIC: + { + pTarget = response.m_Target.m_hHandle.Get(); + } + break; + case kDRT_ANY: + { + return DispatchOneResponse_ThenANY( response, &deferredCriteria, pIssuer, followupMaxDistSq ); + } + break; + case kDRT_ALL: + { + bool bSaidAnything = false; + Vector issuerLocation; + if ( pIssuer ) + { + issuerLocation = pIssuer->GetAbsOrigin(); + } + + // find all characters + int numExprs = GetNumExpresserTargets(); + for ( int i = 0 ; i < numExprs; ++i ) + { + pTarget = GetExpresserHost(i); + float distIssuerToTargetSq = 0.0f; + if ( pIssuer ) + { + distIssuerToTargetSq = (pTarget->GetAbsOrigin() - issuerLocation).LengthSqr(); + if ( distIssuerToTargetSq > followupMaxDistSq ) + continue; // too far + + int iRelation = g_pGameRules->PlayerRelationship(pIssuer, pTarget); + if (iRelation != GR_TEAMMATE && iRelation != GR_ALLY) + continue; + } + + pEx = InferExpresserFromBaseEntity(pTarget); + if ( !pEx || pTarget == pIssuer ) + continue; + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge(&deferredCriteria); + if ( pIssuer ) + { + characterCriteria.AppendCriteria( "dist_from_issuer", UTIL_VarArgs( "%f", sqrt(distIssuerToTargetSq) ) ); + } + AI_Response prospectiveResponse; + if ( pEx->FindResponse( prospectiveResponse, response.m_concept, &characterCriteria ) ) + { + // dispatch it + bSaidAnything = pEx->SpeakDispatchResponse(response.m_concept, &prospectiveResponse, &deferredCriteria) || bSaidAnything ; + } + } + + return bSaidAnything; + + } + break; + default: + // WTF? + AssertMsg1( false, "Unknown deferred response type %d\n", response.m_Target.m_iTargetType ); + return false; + } + + if (!pTarget) + return false; // we're done right here. + + // Get the expresser for the target. + pEx = InferExpresserFromBaseEntity(pTarget); + if (!pEx) + return false; + + + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge(&deferredCriteria); + pEx->Speak( response.m_concept, &characterCriteria ); + + return true; +} + +// +ConVar rr_thenany_score_slop( "rr_thenany_score_slop", "0.0", FCVAR_CHEAT, "When computing respondents for a 'THEN ANY' rule, all rule-matching scores within this much of the best score will be considered." ); +#define EXARRAYMAX 32 // maximum number of prospective expressers in the array (hardcoded for simplicity) +bool CResponseQueue::DispatchOneResponse_ThenANY( CDeferredResponse &response, AI_CriteriaSet * RESTRICT pDeferredCriteria, CBaseEntity * const RESTRICT pIssuer, float followupMaxDistSq ) +{ + CBaseEntity * RESTRICT pTarget = NULL; + CAI_Expresser * RESTRICT pEx = NULL; + float bestScore = 0; + float slop = rr_thenany_score_slop.GetFloat(); + Vector issuerLocation; + if ( pIssuer ) + { + issuerLocation = pIssuer->GetAbsOrigin(); + } + + // this is an array of prospective respondents. + CAI_Expresser * RESTRICT pBestEx[EXARRAYMAX]; + AI_Response responseToSay[EXARRAYMAX]; + int numExFound = 0; // and this is the high water mark for the array. + + // Here's the algorithm: we're going to walk through all the characters, finding the + // highest scoring ones for this rule. Let the highest score be called k. + // Because there may be (n) many characters all scoring k, we store an array of + // all characters with score k, then choose randomly from that array at return. + // We also define an allowable error for k in the global cvar + // rr_thenany_score_slop , which may be zero. + + // find all characters (except the issuer) + int numExprs = GetNumExpresserTargets(); + AssertMsg1( numExprs <= EXARRAYMAX, "Response queue has %d possible expresser targets, please increase EXARRAYMAX ", numExprs ); + for ( int i = 0 ; i < numExprs; ++i ) + { + pTarget = GetExpresserHost(i); + if ( pTarget == pIssuer ) + continue; // don't dispatch to myself + + if ( !pTarget->IsAlive() ) + continue; // dead men tell no tales + + float distIssuerToTargetSq = 0.0f; + if ( pIssuer ) + { + distIssuerToTargetSq = (pTarget->GetAbsOrigin() - issuerLocation).LengthSqr(); + if ( distIssuerToTargetSq > followupMaxDistSq ) + continue; // too far + + int iRelation = g_pGameRules->PlayerRelationship(pIssuer, pTarget); + if (iRelation != GR_TEAMMATE && iRelation != GR_ALLY) + continue; + } + + pEx = InferExpresserFromBaseEntity(pTarget); + if ( !pEx ) + continue; + + AI_CriteriaSet characterCriteria; + pEx->GatherCriteria(&characterCriteria, response.m_concept, NULL); + characterCriteria.Merge( pDeferredCriteria ); + pTarget->ModifyOrAppendDerivedCriteria( characterCriteria ); + if ( pIssuer ) + { + characterCriteria.AppendCriteria( "dist_from_issuer", UTIL_VarArgs( "%f", sqrt(distIssuerToTargetSq) ) ); + } + AI_Response prospectiveResponse; + + if ( pEx->FindResponse( prospectiveResponse, response.m_concept, &characterCriteria ) ) + { + float score = prospectiveResponse.GetMatchScore(); + if ( score > 0 && !prospectiveResponse.IsEmpty() ) // ignore scores that are zero, regardless of slop + { + // if this score is better than all we've seen (outside the slop), then replace the array with + // an entry just to this expresser + if ( score > bestScore + slop ) + { + responseToSay[0] = prospectiveResponse; + pBestEx[0] = pEx; + bestScore = score; + numExFound = 1; + } + else if ( score >= bestScore - slop ) // if this score is at least as good as the best we've seen, but not better than all + { + if ( numExFound >= EXARRAYMAX ) + continue; // SAFETY: don't overflow the array + + responseToSay[numExFound] = prospectiveResponse; + pBestEx[numExFound] = pEx; + bestScore = fpmax( score, bestScore ); + numExFound += 1; + } + } + } + } + + // if I have a response, dispatch it. + if ( numExFound > 0 ) + { + // get a random number between 0 and the responses found + int iSelect = numExFound > 1 ? RandomInt( 0, numExFound - 1 ) : 0; + + if ( pBestEx[iSelect] != NULL ) + { + return pBestEx[iSelect]->SpeakDispatchResponse( response.m_concept, responseToSay + iSelect, pDeferredCriteria ); + } + else + { + AssertMsg( false, "Response queue somehow found a response, but no expresser for it.\n" ); + return false; + } + } + else + { // I did not find a response. + return false; + } + + return false; // just in case +} + +void CResponseQueue::Evacuate() +{ + m_Queue.RemoveAll(); +} + +#undef EXARRAYMAX + + +/////////////////////////////////////////////////////////////////////////////// +// RESPONSE QUEUE MANAGER +/////////////////////////////////////////////////////////////////////////////// + + +void CResponseQueueManager::LevelInitPreEntity( void ) +{ + if (m_pQueue == NULL) + { + m_pQueue = new CResponseQueue(AI_RESPONSE_QUEUE_SIZE); + } +} + +CResponseQueueManager::~CResponseQueueManager() +{ + if (m_pQueue != NULL) + { + delete m_pQueue; + m_pQueue = NULL; + } +} + +void CResponseQueueManager::Shutdown() +{ + if (m_pQueue != NULL) + { + delete m_pQueue; + m_pQueue = NULL; + } +} + +void CResponseQueueManager::FrameUpdatePostEntityThink() +{ + Assert(m_pQueue); + m_pQueue->PerFrameDispatch(); +} + +CResponseQueueManager g_ResponseQueueManager( "CResponseQueueManager" ); + diff --git a/src/game/server/ai_speechqueue.h b/src/game/server/ai_speechqueue.h new file mode 100644 index 000000000..15101b70b --- /dev/null +++ b/src/game/server/ai_speechqueue.h @@ -0,0 +1,239 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: An event queue of AI concepts that dispatches them to appropriate characters. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef AI_SPEECHQUEUE_H +#define AI_SPEECHQUEUE_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "ai_speech.h" + +#define AI_RESPONSE_QUEUE_SIZE 64 + +enum DeferredResponseTarget_t // possible targets for a deferred response +{ + kDRT_ANY, // best matching respondent within range -- except for the one in the m_hTarget handle + kDRT_ALL, // send to everyone in range -- except for the one in the m_hTarget handle + kDRT_SPECIFIC, // a specific entity is targeted + + kDRT_MAX, // high water mark +}; + +// Allows you to postpone AI speech concepts to a later time, or to direct them to +// a specific character, or all of them. +class CResponseQueue +{ + //////////////////// Local types //////////////////// +public: + + // We pack up contexts to send along with the concept. + // For now I'll just copy criteria sets, but it will be better to do something + // more efficient in the future. + typedef AI_CriteriaSet DeferredContexts_t; + + struct CFollowupTargetSpec_t ///< to whom a followup is directed. Can be a specific entity or something more exotic. + { + DeferredResponseTarget_t m_iTargetType; ///< ANY, ALL, or SPECIFIC. If specific, pass through a handle to: + EHANDLE m_hHandle; ///< a specific target for the message, or a specific character to OMIT. + inline bool IsValid( void ) const; + + // constructors/destructors + explicit CFollowupTargetSpec_t(const DeferredResponseTarget_t &targetType, const EHANDLE &handle) + : m_iTargetType(targetType), m_hHandle(handle) + {}; + explicit CFollowupTargetSpec_t(const EHANDLE &handle) + : m_iTargetType(kDRT_SPECIFIC), m_hHandle(handle) + {}; + CFollowupTargetSpec_t(DeferredResponseTarget_t target) // eg, ANY, ALL, etc. + : m_iTargetType(target) + { + AssertMsg(m_iTargetType != kDRT_SPECIFIC, "Response rule followup tried to specify an entity target, but didn't provide the target.\n" ); + } + CFollowupTargetSpec_t(void) // default: invalid + : m_iTargetType(kDRT_MAX) + {}; + }; + + /// A single deferred response. + struct CDeferredResponse + { + AIConcept_t m_concept; + DeferredContexts_t m_contexts; ///< contexts to send along with the concept + float m_fDispatchTime; + EHANDLE m_hIssuer; ///< an entity, if issued by an entity + /* + DeferredResponseTarget_t m_iTargetType; + EHANDLE m_hTarget; // May be invalid. + */ + CFollowupTargetSpec_t m_Target; + + inline void Init( const AIConcept_t &concept, const AI_CriteriaSet * RESTRICT contexts, float dtime, const CFollowupTargetSpec_t &target, CBaseEntity *pIssuer ); + inline bool IsQuashed() { return !m_Target.IsValid(); } + void Quash(); ///< make this response invalid. + }; + /// write + static void DeferContextsFromCriteriaSet( DeferredContexts_t &contextsOut, const AI_CriteriaSet *criteriaIn ); + + //////////////////// Methods //////////////////// +public: + CResponseQueue( int queueSize ); + + /// Add a deferred response. + void Add( const AIConcept_t &concept, ///< concept to dispatch + const AI_CriteriaSet * RESTRICT contexts, ///< the contexts that come with it (may be NULL) + float time, ///< when to dispatch it. You can specify a time of zero to mean "immediately." + const CFollowupTargetSpec_t &targetspec, /// All information necessary to target this response + CBaseEntity *pIssuer = NULL ///< the entity who should not respond if this is a ANY or ALL rule. (eg, don't let people talk to themselves.) + ); + + /// Remove all deferred responses matching the concept and issuer. + void Remove( const AIConcept_t &concept, ///< concept to dispatch + CBaseEntity * const pIssuer = NULL ///< the entity issuing the response, if one exists. + ); + + /// Remove all deferred responses queued to be spoken by given character + void RemoveSpeechQueuedFor( const CBaseEntity *pSpeaker ); + + /// Empty out all pending events + void Evacuate(); + + /// Go through and dispatch any deferred responses. + void PerFrameDispatch(); + + /// Add an expressor owner to this queue. + void AddExpresserHost(CBaseEntity *host); + + /// Remove an expresser host from this queue. + void RemoveExpresserHost(CBaseEntity *host); + + /// Iterate over potential expressers for this queue + inline int GetNumExpresserTargets() const; + inline CBaseEntity *GetExpresserHost(int which) const; + +protected: + /// Actually send off one response to a consumer + /// Return true if dispatch succeeded + bool DispatchOneResponse( CDeferredResponse &response ); + +private: + /// Helper function for one case in DispatchOneResponse + /// (for better organization) + bool DispatchOneResponse_ThenANY( CDeferredResponse &response, AI_CriteriaSet * RESTRICT pDeferredCriteria, CBaseEntity * const RESTRICT pIssuer, float followupMaxDistSq ); + + //////////////////// Data //////////////////// +protected: + typedef CUtlFixedLinkedList< CDeferredResponse > QueueType_t; + QueueType_t m_Queue; // the queue of deferred responses, will eventually be sorted + /// Note about the queue type: if you move to replace it with a sorted priority queue, + /// make sure it is a type such that an iterator is not invalidated by inserts and deletes. + /// CResponseQueue::PerFrameDispatch() iterates over the queue calling DispatchOneResponse + /// on each in turn, and those responses may very easily add new events to the queue. + /// A crash will result if the iterator used in CResponseQueue::PerFrameDispatch()'s loop + /// becomes invalid. + + CUtlVector m_ExpresserTargets; // a list of legitimate expresser targets +}; + +inline void CResponseQueue::CDeferredResponse::Init(const AIConcept_t &concept, const AI_CriteriaSet * RESTRICT contexts, float dtime, const CFollowupTargetSpec_t &target, CBaseEntity *pIssuer ) +{ + m_concept = concept; + m_fDispatchTime = dtime; + /* + m_iTargetType = targetType; + m_hTarget = handle ; + */ + m_Target = target; + m_hIssuer = pIssuer; + DeferContextsFromCriteriaSet(m_contexts, contexts); +} + +int CResponseQueue::GetNumExpresserTargets() const +{ + return m_ExpresserTargets.Count(); +} + +CBaseEntity *CResponseQueue::GetExpresserHost(int which) const +{ + return m_ExpresserTargets[which]; +} + + +// The wrapper game system that contains a response queue, and ticks it each frame. + +class CResponseQueueManager : public CAutoGameSystemPerFrame +{ +public: + CResponseQueueManager(char const *name) : CAutoGameSystemPerFrame( name ) + { + m_pQueue = NULL; + } + virtual ~CResponseQueueManager(void); + virtual void Shutdown(); + virtual void FrameUpdatePostEntityThink( void ); + virtual void LevelInitPreEntity( void ); + + inline CResponseQueue *GetQueue(void) { Assert(m_pQueue); return m_pQueue; } + +protected: + CResponseQueue *m_pQueue; +}; + + +// Valid if the target type enum is within bounds. Furthermore if it +// specifies a specific entity, that handle must be valid. +bool CResponseQueue::CFollowupTargetSpec_t::IsValid( void ) const +{ + if (m_iTargetType >= kDRT_MAX) + return false; + if (m_iTargetType < 0) + return false; + if (m_iTargetType == kDRT_SPECIFIC && !m_hHandle.IsValid()) + return false; + + return true; +} + +extern CResponseQueueManager g_ResponseQueueManager; + + +// Handy global helper funcs + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &concept, ///< concept name to say + const CResponseQueue::CFollowupTargetSpec_t& targetspec, ///< kDRT_ANY, kDRT_ALL, etc + CBaseEntity *pIssuer = NULL ///< if specifying ANY or ALL, use this to specify the one you *don't* want to speak + ) +{ + return g_ResponseQueueManager.GetQueue()->Add( concept, NULL, 0.0f, targetspec, pIssuer ); +} + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &concept, ///< concept name to say + const CResponseQueue::CFollowupTargetSpec_t& targetspec, ///< kDRT_ANY, kDRT_ALL, etc + const AI_CriteriaSet &criteria, ///< criteria to pass in + CBaseEntity *pIssuer = NULL ///< if specifying ANY or ALL, use this to specify the one you *don't* want to speak + ) +{ + return g_ResponseQueueManager.GetQueue()->Add( concept, &criteria, 0.0f, targetspec, pIssuer ); +} + +/// Automatically queue up speech to happen immediately -- calls straight through to response rules add +inline void QueueSpeak( const AIConcept_t &concept, ///< concept name to say + const EHANDLE &target, ///< which entity shall speak + float delay, ///< how far in the future to speak + const AI_CriteriaSet &criteria, ///< criteria to pass in + CBaseEntity *pIssuer = NULL ) +{ + return g_ResponseQueueManager.GetQueue()->Add( concept, &criteria, gpGlobals->curtime + delay, + CResponseQueue::CFollowupTargetSpec_t(target), pIssuer ); +} + + + +#endif // AI_SPEECHQUEUE_H diff --git a/src/game/server/baseentity.cpp b/src/game/server/baseentity.cpp index 747f54ca2..b387228b0 100644 --- a/src/game/server/baseentity.cpp +++ b/src/game/server/baseentity.cpp @@ -6607,35 +6607,72 @@ void CBaseEntity::InputFireUser4( inputdata_t& inputdata ) //----------------------------------------------------------------------------- void CBaseEntity::AddContext( const char *contextName ) { - char key[ 128 ]; - char value[ 128 ]; + char key[128]; + char value[128]; float duration; - const char *p = contextName; - while ( p ) + + const char* p = contextName; + while (p) { duration = 0.0f; - p = SplitContext( p, key, sizeof( key ), value, sizeof( value ), &duration ); - if ( duration ) + p = SplitContext(p, key, sizeof(key), value, sizeof(value), &duration, contextName); + if (duration) { duration += gpGlobals->curtime; } - int iIndex = FindContextByName( key ); - if ( iIndex != -1 ) + + AddContext(key, value, duration); + + } +} + +#include "ai_speech.h" +//----------------------------------------------------------------------------- +// Purpose: add exactly one context key,value pair to this object +// Input : inputdata - +//----------------------------------------------------------------------------- +void CBaseEntity::AddContext(const char* pKey, const char* pValue, float duration) +{ + int iIndex = FindContextByName(pKey); + if (iIndex != -1) + { + // Set the existing context to the new value + char buf[64]; + if (RR::CApplyContextOperator::FindOperator(pValue)->Apply( + m_ResponseContexts[iIndex].m_iszValue.ToCStr(), pValue, buf, sizeof(buf))) { - // Set the existing context to the new value - m_ResponseContexts[iIndex].m_iszValue = AllocPooledString( value ); - m_ResponseContexts[iIndex].m_fExpirationTime = duration; - continue; + m_ResponseContexts[iIndex].m_iszValue = AllocPooledString(buf); + } + else + { + Warning("RR: could not apply operator %s to prior value %s\n", + pValue, m_ResponseContexts[iIndex].m_iszValue.ToCStr()); + m_ResponseContexts[iIndex].m_iszValue = AllocPooledString(pValue); } + m_ResponseContexts[iIndex].m_fExpirationTime = duration; + } + else + { ResponseContext_t newContext; - newContext.m_iszName = AllocPooledString( key ); - newContext.m_iszValue = AllocPooledString( value ); + newContext.m_iszName = AllocPooledString(pKey); + + // Create a new context with the appropriate value ( some operators assume 0 on nonexistent prior ) + char buf[64]; + if (RR::CApplyContextOperator::FindOperator(pValue)->Apply( + NULL, pValue, buf, sizeof(buf))) + { + newContext.m_iszValue = AllocPooledString(buf); + } + else + { + newContext.m_iszValue = AllocPooledString(pValue); + } newContext.m_fExpirationTime = duration; - m_ResponseContexts.AddToTail( newContext ); + m_ResponseContexts.AddToTail(newContext); } } @@ -6666,7 +6703,7 @@ void CBaseEntity::InputClearContext( inputdata_t& inputdata ) // Purpose: // Output : IResponseSystem //----------------------------------------------------------------------------- -IResponseSystem *CBaseEntity::GetResponseSystem() +ResponseRules::IResponseSystem *CBaseEntity::GetResponseSystem() { return NULL; } @@ -6728,6 +6765,8 @@ void CBaseEntity::InputAddOutput( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CBaseEntity::DispatchResponse( const char *conceptName ) { + using namespace ResponseRules; + IResponseSystem *rs = GetResponseSystem(); if ( !rs ) return; @@ -6750,35 +6789,45 @@ void CBaseEntity::DispatchResponse( const char *conceptName ) return; // Handle the response here... - const char *szResponse = result.GetResponsePtr(); - switch ( result.GetType() ) + char response[256]; + result.GetResponse(response, sizeof(response)); + switch (result.GetType()) { - case RESPONSE_SPEAK: - EmitSound( szResponse ); - break; - - case RESPONSE_SENTENCE: + case ResponseRules::RESPONSE_SPEAK: + { + EmitSound(response); + } + break; + case ResponseRules::RESPONSE_SENTENCE: + { + int sentenceIndex = SENTENCEG_Lookup(response); + if (sentenceIndex == -1) { - int sentenceIndex = SENTENCEG_Lookup( szResponse ); - if( sentenceIndex == -1 ) - { - // sentence not found - break; - } - - // FIXME: Get pitch from npc? - CPASAttenuationFilter filter( this ); - CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM ); + // sentence not found + break; } - break; - case RESPONSE_SCENE: + // FIXME: Get pitch from npc? + CPASAttenuationFilter filter(this); + CBaseEntity::EmitSentenceByIndex(filter, entindex(), CHAN_VOICE, sentenceIndex, 1, result.GetSoundLevel(), 0, PITCH_NORM); + } + break; + case ResponseRules::RESPONSE_SCENE: + { // Try to fire scene w/o an actor - InstancedScriptedScene( NULL, szResponse ); - break; + InstancedScriptedScene(NULL, response); + } + break; + case ResponseRules::RESPONSE_PRINT: + { - case RESPONSE_PRINT: + } + break; + case ResponseRules::RESPONSE_ENTITYIO: + { + CAI_Expresser::FireEntIOFromResponse(response, this); break; + } default: // Don't know how to handle .vcds!!! break; diff --git a/src/game/server/baseentity.h b/src/game/server/baseentity.h index 7a6af3ab6..f39606577 100644 --- a/src/game/server/baseentity.h +++ b/src/game/server/baseentity.h @@ -20,14 +20,14 @@ #include "ServerNetworkProperty.h" #include "shareddefs.h" #include "engine/ivmodelinfo.h" +#include "AI_Criteria.h" +#include "AI_ResponseSystem.h" class CDamageModifier; class CDmgAccumulator; struct CSoundParameters; -class AI_CriteriaSet; -class IResponseSystem; class IEntitySaveUtils; class CRecipientFilter; class CStudioHdr; @@ -911,6 +911,7 @@ class CBaseEntity : public IServerEntity int FindContextByName( const char *name ) const; public: void AddContext( const char *nameandvalue ); + void AddContext(const char* pKey, const char* pValue, float duration); protected: CUtlVector< ResponseContext_t > m_ResponseContexts; @@ -939,7 +940,7 @@ class CBaseEntity : public IServerEntity virtual CBaseAnimating* GetBaseAnimating() { return 0; } virtual CBaseAnimatingOverlay* GetBaseAnimatingOverlay() { return 0; } - virtual IResponseSystem *GetResponseSystem(); + virtual ResponseRules::IResponseSystem *GetResponseSystem(); virtual void DispatchResponse( const char *conceptName ); // Classify - returns the type of group (i.e, "houndeye", or "human military" so that NPCs with different classnames @@ -1188,6 +1189,10 @@ class CBaseEntity : public IServerEntity #endif // _DEBUG virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); + // this computes criteria that depend on the other criteria having been set. + // needs to be done in a second pass because we may have multiple overrids for + // a context before it all settles out. + virtual void ModifyOrAppendDerivedCriteria(AI_CriteriaSet& set) {}; void AppendContextToCriteria( AI_CriteriaSet& set, const char *prefix = "" ); void DumpResponseCriteria( void ); diff --git a/src/game/server/baseflex.h b/src/game/server/baseflex.h index f7b407c4e..73a2cb24b 100644 --- a/src/game/server/baseflex.h +++ b/src/game/server/baseflex.h @@ -19,7 +19,6 @@ struct flexsettinghdr_t; struct flexsetting_t; -class AI_Response; //----------------------------------------------------------------------------- // Purpose: A .vfe referenced by a scene during .vcd playback diff --git a/src/game/server/basemultiplayerplayer.cpp b/src/game/server/basemultiplayerplayer.cpp index fee7515db..9024dc3f8 100644 --- a/src/game/server/basemultiplayerplayer.cpp +++ b/src/game/server/basemultiplayerplayer.cpp @@ -12,6 +12,8 @@ // Minimum interval between rate-limited commands that players can run. #define COMMAND_MAX_RATE 0.3 +using namespace ResponseRules; + CBaseMultiplayerPlayer::CBaseMultiplayerPlayer() { m_iCurrentConcept = MP_CONCEPT_NONE; @@ -28,6 +30,7 @@ CBaseMultiplayerPlayer::CBaseMultiplayerPlayer() CBaseMultiplayerPlayer::~CBaseMultiplayerPlayer() { m_pAchievementKV->deleteThis(); + delete m_pExpresser; } //----------------------------------------------------------------------------- @@ -91,7 +94,9 @@ bool CBaseMultiplayerPlayer::SpeakConcept( AI_Response &response, int iConcept ) { // Save the current concept. m_iCurrentConcept = iConcept; - return SpeakFindResponse( response, g_pszMPConcepts[iConcept] ); + CAI_Concept concept(g_pszMPConcepts[iConcept]); + concept.SetSpeaker(this); + return FindResponse( response, concept ); } //----------------------------------------------------------------------------- diff --git a/src/game/server/basemultiplayerplayer.h b/src/game/server/basemultiplayerplayer.h index a1ea58f8b..aacded6ff 100644 --- a/src/game/server/basemultiplayerplayer.h +++ b/src/game/server/basemultiplayerplayer.h @@ -27,7 +27,7 @@ class CBaseMultiplayerPlayer : public CAI_ExpresserHost virtual void ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet ); virtual bool SpeakIfAllowed( AIConcept_t concept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); - virtual IResponseSystem *GetResponseSystem(); + virtual ResponseRules::IResponseSystem *GetResponseSystem(); bool SpeakConcept( AI_Response& response, int iConcept ); virtual bool SpeakConceptIfAllowed( int iConcept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL ); diff --git a/src/game/server/bms/npc_basecollegue.cpp b/src/game/server/bms/npc_basecollegue.cpp index 78cb68ade..880e0eaa2 100644 --- a/src/game/server/bms/npc_basecollegue.cpp +++ b/src/game/server/bms/npc_basecollegue.cpp @@ -4,7 +4,7 @@ #include "sceneentity.h" #include "npc_basecollegue.h" - +using namespace ResponseRules; #define ALYX_FEAR_ZOMBIE_DIST_SQR Square(60) @@ -264,9 +264,9 @@ void CNPC_BaseColleague::UseFunc(CBaseEntity *pActivator, CBaseEntity *pCaller, if (IsAllowedToSpeak(TLK_VITALIDLE, true)) { AI_Response pResp; - if (SpeakFindResponse(pResp, TLK_VITALIDLE) && pResp.GetType() != RESPONSE_NONE) + if (SpeakFindResponse(pResp, TLK_VITALIDLE) && pResp.GetType() != ResponseRules::RESPONSE_NONE) { - bSpoke = SpeakDispatchResponse(TLK_VITALIDLE, pResp); + bSpoke = SpeakDispatchResponse(TLK_VITALIDLE, &pResp); } } diff --git a/src/game/server/hl1/hl1_npc_scientist.cpp b/src/game/server/hl1/hl1_npc_scientist.cpp index 2265649eb..aaf2141fd 100644 --- a/src/game/server/hl1/hl1_npc_scientist.cpp +++ b/src/game/server/hl1/hl1_npc_scientist.cpp @@ -1073,8 +1073,8 @@ void CNPC_SittingScientist::SittingThink( void ) ResetSequenceInfo( ); SetCycle( 0 ); SetBoneController( 0, 0 ); - - GetExpresser()->Speak( TLK_HELLO ); + CAI_Concept concept(TLK_HELLO); + GetExpresser()->Speak(concept); } } else if ( IsSequenceFinished() ) @@ -1085,7 +1085,8 @@ void CNPC_SittingScientist::SittingThink( void ) if (m_flResponseDelay && gpGlobals->curtime > m_flResponseDelay) { // respond to question - GetExpresser()->Speak( TLK_QUESTION ); + CAI_Concept concept(TLK_QUESTION); + GetExpresser()->Speak(concept); SetSequence( m_baseSequence + SITTING_ANIM_sitscared ); m_flResponseDelay = 0; } diff --git a/src/game/server/hl1/hl1_npc_talker.h b/src/game/server/hl1/hl1_npc_talker.h index a417e5fb7..60f0334d5 100644 --- a/src/game/server/hl1/hl1_npc_talker.h +++ b/src/game/server/hl1/hl1_npc_talker.h @@ -69,7 +69,7 @@ class CHL1NPCTalker : public CNPCSimpleTalker Disposition_t IRelationType( CBaseEntity *pTarget ); - virtual IResponseSystem *GetResponseSystem() { return m_pInstancedResponseSystem; } + virtual ResponseRules::IResponseSystem *GetResponseSystem() { return m_pInstancedResponseSystem; } void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); @@ -97,7 +97,7 @@ class CHL1NPCTalker : public CNPCSimpleTalker protected: virtual void FollowerUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - IResponseSystem *m_pInstancedResponseSystem; + ResponseRules::IResponseSystem *m_pInstancedResponseSystem; private: virtual void DeclineFollowing( void ) {} diff --git a/src/game/server/hl2/ai_behavior_actbusy.cpp b/src/game/server/hl2/ai_behavior_actbusy.cpp index 5b233aa57..b2e645bea 100644 --- a/src/game/server/hl2/ai_behavior_actbusy.cpp +++ b/src/game/server/hl2/ai_behavior_actbusy.cpp @@ -1646,7 +1646,7 @@ void CAI_ActBusyBehavior::PlaySoundForActBusy( busyanimparts_t AnimPart ) CAI_Expresser *pExpresser = GetOuter()->GetExpresser(); if ( pExpresser ) { - const char *concept = STRING(pBusyAnim->iszSounds[AnimPart]); + CAI_Concept concept = STRING(pBusyAnim->iszSounds[AnimPart]); // Must be able to speak the concept if ( !pExpresser->IsSpeaking() && pExpresser->CanSpeakConcept( concept ) ) diff --git a/src/game/server/hl2/env_speaker.h b/src/game/server/hl2/env_speaker.h index 20fbeb6b5..b6b1820b7 100644 --- a/src/game/server/hl2/env_speaker.h +++ b/src/game/server/hl2/env_speaker.h @@ -27,7 +27,7 @@ class CSpeaker : public CPointEntity virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - virtual IResponseSystem *GetResponseSystem() { return m_pInstancedResponseSystem; } + virtual ResponseRules::IResponseSystem *GetResponseSystem() { return m_pInstancedResponseSystem; } virtual int Save( ISave &save ); virtual int Restore( IRestore &restore ); @@ -43,7 +43,7 @@ class CSpeaker : public CPointEntity string_t m_iszRuleScriptFile; string_t m_iszConcept; - IResponseSystem *m_pInstancedResponseSystem; + ResponseRules::IResponseSystem *m_pInstancedResponseSystem; public: diff --git a/src/game/server/peter/laz_player.cpp b/src/game/server/peter/laz_player.cpp index e39f83251..78c0edd32 100644 --- a/src/game/server/peter/laz_player.cpp +++ b/src/game/server/peter/laz_player.cpp @@ -33,6 +33,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +using namespace ResponseRules; #define HL2MP_COMMAND_MAX_RATE 0.3 @@ -1037,7 +1038,7 @@ void CLaz_Player::AnswerQuestion(CBaseCombatCharacter* pQuestioner, int iQARando } } - SpeakDispatchResponse("TLK_PLAYER_ANSWER", selection); + SpeakDispatchResponse("TLK_PLAYER_ANSWER", &selection); } else if (rr_debug_qa.GetBool()) { diff --git a/src/game/server/physconstraint.cpp b/src/game/server/physconstraint.cpp index 210e569c8..887b7801c 100644 --- a/src/game/server/physconstraint.cpp +++ b/src/game/server/physconstraint.cpp @@ -572,7 +572,7 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) if ( Q_strlen(STRING(m_nameAttach1)) ) { Warning("Bogus constraint %s (attaches ENTITY NOT FOUND:%s to %s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); -#ifdef HL2_EPISODIC +#if defined(HL2_EPISODIC) && !defined(HL2_LAZUL) info.pObjects[0] = info.pObjects[1] = NULL; return; #endif // HL2_EPISODIC @@ -585,7 +585,7 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) if ( Q_strlen(STRING(m_nameAttach2)) ) { Warning("Bogus constraint %s (attaches %s to ENTITY NOT FOUND:%s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); -#ifdef HL2_EPISODIC +#if defined(HL2_EPISODIC) && !defined(HL2_LAZUL) info.pObjects[0] = info.pObjects[1] = NULL; return; #endif // HL2_EPISODIC diff --git a/src/game/server/physics_prop_ragdoll.cpp b/src/game/server/physics_prop_ragdoll.cpp index bcbb4ef22..51f6ce7bf 100644 --- a/src/game/server/physics_prop_ragdoll.cpp +++ b/src/game/server/physics_prop_ragdoll.cpp @@ -480,9 +480,9 @@ void CRagdollProp::InitRagdollAnimation() //----------------------------------------------------------------------------- // Response system stuff //----------------------------------------------------------------------------- -IResponseSystem *CRagdollProp::GetResponseSystem() +ResponseRules::IResponseSystem *CRagdollProp::GetResponseSystem() { - extern IResponseSystem *g_pResponseSystem; + extern ResponseRules::IResponseSystem *g_pResponseSystem; // Just use the general NPC response system; we often come from NPCs after all return g_pResponseSystem; diff --git a/src/game/server/physics_prop_ragdoll.h b/src/game/server/physics_prop_ragdoll.h index b25627dfb..26691b896 100644 --- a/src/game/server/physics_prop_ragdoll.h +++ b/src/game/server/physics_prop_ragdoll.h @@ -53,7 +53,7 @@ class CRagdollProp : public CBaseAnimating, public CDefaultPlayerPickupVPhysics virtual int DrawDebugTextOverlays(void); // Response system stuff - virtual IResponseSystem *GetResponseSystem(); + virtual ResponseRules::IResponseSystem *GetResponseSystem(); virtual void ModifyOrAppendCriteria( AI_CriteriaSet& set ); void SetSourceClassName( const char *pClassname ); diff --git a/src/game/server/sceneentity.cpp b/src/game/server/sceneentity.cpp index 00d78c242..2b8ee5a63 100644 --- a/src/game/server/sceneentity.cpp +++ b/src/game/server/sceneentity.cpp @@ -2285,15 +2285,19 @@ void CSceneEntity::InputInterjectResponse( inputdata_t &inputdata ) // Try to find the response for this slot. AI_Response response; - bool result = npc->SpeakFindResponse( response, inputdata.value.String(), modifiers.Get() ); + CAI_Concept concept(inputdata.value.String()); + concept.SetSpeaker(npc); + AI_CriteriaSet set; + npc->GatherCriteria(&set, concept, modifiers.Get()); + bool result = npc->FindResponse( response, concept, &set); if ( result ) { - float duration = npc->GetResponseDuration( response ); + float duration = npc->GetResponseDuration( &response ); if ( ( duration > 0.0f ) && npc->PermitResponse( duration ) ) { // If we could look it up, dispatch it and bail. - npc->SpeakDispatchResponse( inputdata.value.String(), response ); + npc->SpeakDispatchResponse( concept, &response, &set); return; } } @@ -2821,10 +2825,11 @@ void CSceneEntity::QueueResumePlayback( void ) if ( pBaseActor ) { AI_Response response; - bool result = pBaseActor->SpeakFindResponse( response, STRING(m_iszResumeSceneFile), NULL ); + CAI_Concept concept(STRING(m_iszResumeSceneFile)); + bool result = pBaseActor->FindResponse( response, concept, NULL ); if ( result ) { - const char *szResponse = response.GetResponsePtr(); + const char* szResponse = response.GetResponsePtr(); bStartedScene = InstancedScriptedScene( NULL, szResponse, &m_hWaitingForThisResumeScene, 0, false ) != 0; } } @@ -4713,6 +4718,34 @@ float GetSceneDuration( char const *pszScene ) return flSecs; } +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pszScene - +// Output : float +//----------------------------------------------------------------------------- +float GetSceneSpeechDuration(char const* pszScene) +{ + float flSecs = 0.0f; + + CChoreoScene* pScene = CSceneEntity::LoadScene(pszScene, nullptr); + if (pScene) + { + for (int i = pScene->GetNumEvents()-1; i >= 0 ; i--) + { + CChoreoEvent* pEvent = pScene->GetEvent(i); + + if (pEvent->GetType() == CChoreoEvent::SPEAK) + { + flSecs = pEvent->GetStartTime() + pEvent->GetDuration(); + break; + } + } + delete pScene; + } + + return flSecs; +} + //----------------------------------------------------------------------------- // Purpose: // Input : *pszScene - diff --git a/src/game/server/sceneentity.h b/src/game/server/sceneentity.h index f1580798b..a4bacadb2 100644 --- a/src/game/server/sceneentity.h +++ b/src/game/server/sceneentity.h @@ -13,7 +13,6 @@ // List of the last 5 lines of speech from NPCs for bug reports #define SPEECH_LIST_MAX_SOUNDS 5 -class AI_Response; struct recentNPCSpeech_t { @@ -36,6 +35,7 @@ bool IsRunningScriptedSceneAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstance bool IsRunningScriptedSceneWithSpeech( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); bool IsRunningScriptedSceneWithSpeechAndNotPaused( CBaseFlex *pActor, bool bIgnoreInstancedScenes = false ); float GetSceneDuration( char const *pszScene ); +float GetSceneSpeechDuration(char const* pszScene); int GetSceneSpeechCount( char const *pszScene ); bool IsInInterruptableScenes( CBaseFlex *pActor ); diff --git a/src/game/server/server_base.vpc b/src/game/server/server_base.vpc index c958c8706..eb388f6ad 100644 --- a/src/game/server/server_base.vpc +++ b/src/game/server/server_base.vpc @@ -189,6 +189,7 @@ $Project $File "ai_dynamiclink.cpp" $File "ai_dynamiclink.h" $File "ai_event.cpp" + $File "ai_expresserfollowup.cpp" $File "ai_goalentity.cpp" $File "ai_goalentity.h" $File "ai_hint.cpp" @@ -255,6 +256,8 @@ $Project $File "ai_speech.h" $File "ai_speechfilter.cpp" $File "ai_speechfilter.h" + $File "ai_speechqueue.cpp" + $File "ai_speechqueue.h" $File "ai_squad.cpp" $File "ai_squad.h" $File "ai_squadslot.cpp" @@ -491,7 +494,6 @@ $Project $File "init_factory.h" $File "intermission.cpp" $File "$SRCDIR\public\interpolatortypes.h" - $File "$SRCDIR\game\shared\interval.h" $File "$SRCDIR\public\iregistry.h" $File "$SRCDIR\game\shared\iscenetokenprocessor.h" $File "iservervehicle.h" @@ -761,7 +763,6 @@ $Project "h_export.cpp" \ "init_factory.cpp" \ "$SRCDIR\public\interpolatortypes.cpp" \ - "$SRCDIR\game\shared\interval.cpp" \ "$SRCDIR\public\keyframe\keyframe.cpp" \ "$SRCDIR\common\language.cpp" \ "$SRCDIR\public\map_utils.cpp" \ @@ -1078,6 +1079,7 @@ $Project $File "$SRCDIR\public\zip_uncompressed.h" $File "$SRCDIR\game\shared\mp_shareddefs.h" $File "$SRCDIR\game\shared\econ\ihasowner.h" + $File "$SRCDIR\public\tier1\interval.h" //Haptics $File "$SRCDIR\public\haptics\haptic_utils.h" [$WIN32] } @@ -1098,6 +1100,7 @@ $Project $Lib tier2 $Lib tier3 $Lib fgdlib + $Lib responserules $ImpLibexternal steam_api } } diff --git a/src/game/shared/multiplay_gamerules.h b/src/game/shared/multiplay_gamerules.h index b74dd34fa..4c2580c58 100644 --- a/src/game/shared/multiplay_gamerules.h +++ b/src/game/shared/multiplay_gamerules.h @@ -227,7 +227,7 @@ class CMultiplayRules : public CGameRules struct ResponseRules_t { - CUtlVector m_ResponseSystems; + CUtlVector m_ResponseSystems; }; CUtlVector m_ResponseRules; diff --git a/src/lib/public/responserules.lib b/src/lib/public/responserules.lib new file mode 100644 index 0000000000000000000000000000000000000000..6e193cd0a1625245cf921436d6758cb9d8b58f9b GIT binary patch literal 2927900 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

RF_2na ze?dr zO}iRG#`8zhk_0&*79D_WYAy0J`Mxx<_>}$G8C}B)NI}QnZZxzXap1VbM;e*B<373| z$PBx#v68`9FPPsOSZB)1;|xh(83XIKp&h@{T~ohWMOZP+XJ?Duwq?MW$xiiAJ(ay? zqbfJ!%DZ1OSX?r$3|`J{s1d<-Iy@%TQ2N7;B3SEoRn~5TkMrdmSJs@V|E1Lg^S^u~ zbmacX1M-1o%Y5uXV$bqv$2NkoeIj-xw|O@E7Prs&?t2`fVSD5L>PxuETET$dx-2rw zf>x6&ymeVzYlorw7_;C-&)vD%A-$9&rPW1pB5#ry1aZPc>TFF~rdiBNtt*VQx|C(q zoVB+0x88DoCvV4;BU>;rb?`hHwvc9HZh*J#ZxGpPzFdA6cV^OoQ+~Fkz7d;^X$9q% zLss8NNizKVZ|(!wJ_Mtgi#dN=9A%yCW-jO$F|2UsApEmfkoYZ#qE>!6a?Qi6MH9mZ zpMS7n;r!FlT3swB@&b%G9{p@@usoftmbGuTko>qsDUPAKK&8Qta7$Bp&IbM_H0YAb z>XJB-YB9ehRcrC-bJoMoXF18OUKX&~kw4jO1F>1YUZ3l#U$wM1X)=G8yV~>RJ2?}@lI}ful+YgZS>xCDMMWrSd zKjSjevx#v*XZ(1myxvrvuRLqwlcyMq5dR~qRQ6D@@*J|<=}T{`Zw#L4WoXYDqhRwX zzor3G5KfJJTEVuoV?)jH{19o$nVL=J7Ho{uX;7q4xZBGR2P|>IJ_F zrWn5JVwC}$fs*{Nm%o2SB*#nSO5I{5!;Lh!bBh+jm`_h?^#M9{)OXhLS~vokRQ>^k zzb9`}v)O?Iq71{d80_jo)Flc92%>O;Zze@Fm;1n*DnF~V$U~zU}~wO^N%tB z=eqPopu=mY_y9c|2$Mhup^FNyCiIv2&T&6g;vy@W^$w23${9$0_(M!Aq%GXh6 zIR?q=MJV5=q5H=k5DlZcU9)rX6>Op~dxcTa5&L703^Q5aE;E&KmgA5~=^tYdv=QN1 z4uqE4KgM97s$$RgbP8Nlq^xh%`vU2;3oLu-|8A>y*_*l}b_(Z~Ui_#(!H0*q`96XI z|J)oONh+lC-D-(_!gF@fs^GudZLlKfe&azIbtcef5TZ`Op9KkI$Yx`|tnf z&(A*pufII|kN@)@pZ%9V{nIn=fB)07SO53lKKpO~+XV3nE|NfEv zO+Wnu{*%A`L*l!5%fCGPv*<EFL++|zG=Cw^A@#m7qhCW4kNi|p@{lK2O~DRIZ4Q;UB9HS`Thf@HvH{j+Gx+eI1_ zNm9bdqB`%ph_7sIkl!a|NS_n;TmlgW*`EJP)Dv9ZTa`f6j(8w$qfa9K_-87YTp#{U zw2o`93Pa8w`58%&{t&$prsyZxPW^;*k$TC`s15%kKjZ((-()+9f&VKZOBs=_aoJIO zYQx)+9&qYpe-2MVk)Qr4)ED)8{xji_c%n}vhIISr6XJo7=HH3YBB@K95|*4X91CHJ z#)jH*?ak5^4x#GbT+)0DxLp4}!7t|_3r{2$Y7_k?+r~eUzj2IlImjOAf0M0~mW%h0 zu(`ye-{@ODW8!e)*yHWh-{jBIhDP*B2pq0#7ssE*NwSSwo(N)+ldLi4W090~91mfj z7X0rd{I~|HbVn^E=IC4cPWM}U>?7J}?#Vth10wh;v}oo^iOPRfjBy+!MgE6-KW~6ho{o6a+~~FZO8FTc4sl^bhbl^oM^Qeaj`n|CX~!QbJI;waAJKWzV>L{t-Ah#^`VI zdlUiF>gG@QDgWJizbj78`AAp4Hzlfl`3xaW)ZNj{e8VMj0iUPDAQLz zWs4|19L#GiPA+A$p!Pq+H8C|f_$=O;*JlqhCUlR^9akJZh&C5IyW1gWRQb{80+CbN z-xKQgYX2B)=JY0nV{ra8F>8tO!2HVr<#CJrO_-LNIF?YgIBa-qJa?CPRFW5;plF0u zkhoMn;!`OCLUDv|yUqS?=lJ|Pf9j^b!qD?CX=YOeO0sX!K$k-)+8R;eg*djX5}H=c zqCrxnP*l*Kn(;?L&P2hABI=QZ8oE_wOode|olrC-ev@kj<)e5=SBVcxT($Daf}u*( zGYG|L(#9`(BD7tKV`XuN9s~QjC^Rxeg>U+2fetF?+_dGeg=0Zqo}bo90p#R$v%zlX zIP(aygJeUa$<^giW$LS;BjExh6yd@J!u&?rkl#0NZe|i(a@E1%<~BhA+y$?;Bn$ua zJ#x%YUsB#K{_lFMz&hEY$6KHtwC8&4@~~tJ#ksp)=-*W=ti=a7|L4ztjUoWG1tXVB<8%`9xtt2}759WTJ)~RasPF9f)F5NX!(GEIq?OruH$aHKehlPG^#k z?8uG*u;S5JF|uzk%69mRhdDNI$*`R+;IX7MFNV>L0vOEeWbctij3nv8h+$Id#X#UM% zfdu7t*m2*+^U-3J`t1E|OUHl_Cn6HSBj=*2_?U+xt}7vkkL8W#1y6(nrT}l>@sbA^ z60xfmb_riwG*A$+Ft~(EQ0l|%!Ni56K6H#!*Sp=au2;^5)DDM0Fmkt?KRzj{AwGUs zZ@$hq_t@jx?(T^emgI9~o=<*VCH_BUd&g1TOw;4OnFL0SR{&ukn z`V~LH)c%d82epxQ#VRF6c?JO^%{u2LG*s z;bOaU^6W^L#O7z!T}A-f%iwWl0E4;$T7+^!*lZ^0(=37ADHMny)oW2$0)2!c1 zh@do~su4RHUQ0W7G`g56tOuLcTGj(z&J#eZrqH%_w+`|Rh8dHz@;oIJc9y#?tR~ZL z!jp(?BsiLK2R495_@o5Ny7nK=VtGXNo(EZ+LjKLY)5m;!?)q6cwvZMcfco z^2`sP5!k+e#U6g5149|Wp(5qa^(0WFJ^dNpaRnKNGAZgavqe`jg<3UouU>S2jMGM< zd|zrvRIGjEbxwxLmmjxSm=Lk_!pT|@a^07Slo~@5>Flt9*2I&3!(h9W7oS1QP z7Ut4&EfI}CDGNkYTVfOkdQ7sggIZWTa+RXXJJ+EJMjQo2V1lDE{XV$c;lB26EXqkP zkfi<3=-7*Oq(x3F@cQtgqLHs5Y>nh%}LZM6MFq$rze6(aOR4#a+cC$$|>ff#kU zKr*TgHmtnOilJ8AEZ{5-Q5)M82f@OvqRnli6$P%EipdytLqK2$$j+PE!Il$F=Tddh zP;G#>_11UpZns%{-0$e6z4aYCZOu}}5P(Rv<qm3NuW>C&Hz^#jV44GZthvi{v#GaSB zsCV9j)lwM;Vzv&uL-?h0&_z5cjz{y|-REGF<-@qYDK}HAZc~v=REK;zDk@4Lx$>!n zsU*-UG+Nr!dIqKh(keWLE4Av<4?$_^(OT;QqRZ{8#TYIN4eW*OG>|YVR<_#6P#J)F z+VU)U5mHS3b1>U4Qgep_a?jhENo3~M9I6D9>AR9Z zjg8|lK?B`pDtjrE#@o>sXp6V6=xQ}%^V?v)x%-S}`z0O|m(8OZy6^BvC z=_I;Tn<*qjaxk`YMI5neV_POQ{_$G*n2N6r^_)F>j3#gYv*EJ*gzIY zQbsGRf^bi>w6SKtG?}VlITBV&Gjt@X61k!B>Y+7pbuc1l24HE-K-Njmly=yf&+4R; z&7%#0th_y+lob8KGG8yuGEcwy5-q_pJ0BE6P?c%F?FDkq%)Tn1b zgUqTGrDwn_Z2iT~_Pa~|B5k5NqS6^@jB|QU3JIQS7ouX3)=>_ta?^4E(ZxL5kt7kr zsnjfH>1@h^6%se5kJTp2F&MX{=^%pP{`(m0Dv^Sf+Uf&?%2ew?+sm4V7?nv|$s)H!H zX)ACu+G^`>GuobO^=$^JhH~0Om}iW+)AmY;+9v8wAT3jQo95IMv2!}>tGeYBG))zE zqFK(>-qB(;%yMVv;or%vluJrxd;5n6Y=0|jUELZ|L6Be2#c4IvX+>0|qBMiWjp)ei zX)+N}_k1ml+T}t_H=_vEyoGYf0$B-~e!gLaunL8zrb4Cx0L8cUvl09>?ajR~lnJ&c@O#y@^>F>K~O=zsawijkY@rUn9l{RBW69L*}-Nq)|MZ zVFLn8i_C8YAcd22EIO{j@u|{myeP7Yh*GgaQ7f#Pz#4|C937U1^JH`?iJQ9BOlzbM z!>pW_fL<>rwhrMC?16?nHzGDvYMpL`($4uDiVEqZG9yEdR5~ujFZ^4&1lQntr)i&vdurs{=DC9*MC zc0%Df6RSQcjFM%Y>*Y8MtrV!ydhf{Ptw{CcENA&4Q6cNXHJw#m6%*d{@VC<`^0(nl z^=3AtD*eh}w)9_xDYJuHhH{>|qD*CxL8aCyELzXS+0=cVg2P-A??XRozW3Vfwae7^ z2Aj{|7PDKjwAacCQC1yu%c@U;L*l?-l>`<;D-|v;9A@RlBsu(${#M-1jps75z7^MV z!WDLtd;@D>AS}6KZK5%0i;(2PZ;mrXv-eILc_MlAQ5%AxO|Q z5qL4RO;^mx2A0qwVa6!4f@Zng(=cEKr4W}^5VeD31*I5WrPqFy_I~p9CmkUdO@&q` z>IaaTW}f_krKUt!bXPb2&pl?^^pqDu3deypA%#yr>r2nk6plmk1Un5M6%Q|RwoVT+ zj%8>#Kbh1!!Ou-5Y937If6Hln1o@C-8eyq>#zv4!)2~}Fl`xz6pbkc%h4LSWLK)s# zx|yh3Y1u>|tW+!NRuVHzM47y6;n`aX{&9IJtaeA{g@yd419O>c!*nPF(v9HCOWg?C zLZ=T*sa2+hp6Q|ORvT@%%jIwk6(nDZ9~+H7GC%PkQvOEKEJ{$LO&F^Ykx+D*eFnC| z7!-nUIRy&A%%C~343=Po0Qp%^*bGy%QjnQim4Iwl9M5N?Ri6xQtonYJv5PlJO=oQ^X241ToU&TSox5L+)N39;}V3GrC;gd36Zs#Pz=ikyI6CQ^HP zo6Ys(<9vm;+OZo4vo8FFbg>lkK(n;h#X+A~mh=)Yb`$>|{8Z*k>I^tLuHwZWgHS)u zIX|E_Q}1N=+6}ME!DgS@@!BKy_037o>0p~vI!l0UA^B zKnRcabJEbFfUP$4EQeu6Ko!lJ&g|l%Ii8L^x7TzS0{ZB(*&g;LgW(X52lU3# z$L;p0?{@rw(|8qq*!8;ZcsOlg@)Cipf3GpP9BsOA69-n)QHmR;pxHIhJskkB-GAS3}T(Fi?eM)%p>bD5cY>Rsp7b8g-4o)OJg z)U7(VZ_#zDO7-aOE0ah#{!C(%IL6M02@rz$?AQcbKmhYHUR$q?ztI=j^rCUVH8J+H3FKDAt?RQVm~T0~8Z(>!4aY zsOSW?X+GU5RP$9`Zxrx2Uz%CZtNB)`c+e;_Dr_WgRm&BlFs* z#00dRuh+A!YF5|ooQ|!hpgCWw6+q2%pt8BYYrSd|irFTBY5TkMKkG%alx-Dr@51)}w&+XAnzA>`E$|_qV{@u781;sWzQy93m1>=4 z3gFKsbZxdpRSiR2tCw0@Paf+g$N6Th)~Z)p**p`&LVYwI8EhOZrF64#kgpc1I?ZrN z9!6OqYipD=-Z}c zE~k|Xg;KVLyvqI!vL(aikx;0y&aA!dIngwN`JSKF$0}{>AZCJy)(l#cTW==KWnMD8Ot< z0>J6zMzhh#+K{$^wb;lP?ci##L(OItMue&C{arS)75ytPD3%(v zauM3v376?0i(9y|BCF?e#YR@k&T!W~iPZjXiK%1amu1}n5_IYn2(=R;Q;K$om2x$w z>##VIkCH{;eW8ILCdszJEoukNMy1khzzBN}8=6vcCZ~>u)l#tq%U2>Lg8v-~IpNhh@_V1e2I`jy65#AlhBW(2OKuOb!`E0%g z-6bbsX=?)#Bj?=?`+Q0S@t6GV z>|v)-yj?u(WZRwg(IF<3MG`(}7Fx~bL5__iWdmtV6XZEH;_?(OYn75-&t>6Bcn&Ag zbk8z|IedQrpRQGH`G1d-;7vtV)()U2o7s}jEID4-=4u7nAHGHw-QaEw>wpd#YQ`gG zG=<`TapEbIz>iyiLYw4gI1|PUSWd}E_$b6 z+Gue`7r8P0YN59=yQ}0%+_geW{%b#s zXn*&3d~X2}8I1bIBa7g=)`as3Xe>%4{>5k=KL%n<{l)9fJDS}hAOMfFxC3$Of$hYpkObjB3t8C`8T z9gG(FNZ*hlxDL4w~I_sFF=7^HzgEIjaegLB=!b@|AkOsRqw)`Q$Xca1Dgqa7nv0XB%EFv%m*XnmgtL0j) zmR^LC(!m;@X4>C9?J{9v{e=9oyN2oynIP#HK_>L#=-$AVz=Itq*9yqtHEPf@_yCJ}P$`xia~Qz2zuRPi zh=ub&s}yzkbh@q`Rf^DhBE!KrY!Wf-;x=W>SIe|Q1oH=wj1tm@JcGbee|8^gXMbnw zgw1#z9Y9x0;)#X53O}@fd~g%SR(6@281!|!28}@;5;#V5*_&0XrFyMI8SEP~11hyk z^2@Z+g!GMYc!3r-*<0;unC?h{7Meaz+*#*vJSGR&^a&u*_U5qdC8!IZK4YEJ>R=$vh%U-e1iL)gw$9-vwYB+{)Dv>PLN|<9@1;aV#c^}h- zpHYScX%%~x6>&-a$R)2!@P9-bF6EP4)$D4s_CtTTdc zY)y@m!6VBBMl)oaTREhS?HHXC-y>MCdfU*drDp3OU-orLYvb{KP`yLS(%!CC%eTN` zFP+RJu{0f@iGx&4_otyDf!D0pTfPFtSL54rOdvb5dI?J{^`FG8 z?xdHwva&a8Lbd2feEad#6I&C?w4852|7-a+i9qpeFo)}5PBa7?w?_9z0yHci&l zko?CQPNC*EIlWlY((;W`EsF&dZzApbkF6(J{cCBBa<+?5V=$da;@V?UOlgSQ zf>CTX#?n#YpbFO18`_i94g0&&`GO*~w`}PR@TcYD@SJr@gXwHu zni|k7q#CTIIW4CbbIoeLrnT=6CKEQD7Ne;F1#}Po8M!!%W7jwq&tTZZmE2mL*cI)0?zW*H7tH!hat=V`n?HT*eO@@mZ{fj44i|Ptk zoo(jf@hdZ`qBYA1$VwF$Wc{${;{}WiqYn|aWdM-QJ%AruMMSSk?SYod7jp=By@!U$ z#b7kw-m*yrp9WTs542{siuFzyo&wfzFmZ;kpK{1L-0j(!KcXpx@+PUa3-DdA=3dD8 zsck|IQ^+$)VuTzHDnY1W-s?VY?WAEm%<~MbZCMPh3Rq06Ks%~(tExd5Yq?TgS8rJ_ zWpi-U3aTw@FyYN|KAVlvvQ{aOX7n*szHtgnO+8=9ph z8!7Nn4{k6BB?D=B%d`^FtQSG4my<2BqL|hs^!S%tLq2h=JZdqgwNTE{DjoPJQnaJ0 zzr5W`GzSOitek#;bU+ryO7ATB`ON)bQ63R*h4n~9RSwFnypA3Ob(g|qBHWtb2-*(d zl^viw2NsszLnp8x;uI#_nW2Z5xqkUivN~p(;oc=)fBtAuC0s!AYihJd8|7J8TL~OPvBk5Ez6FU8 z8cE;DN-YmcaAP6Kw`SdY2G3sjW>H$>u689?>)vzC+`dMFtjqfDXt-{2Ky0hI4$7|FuRPt1zB3|#fURMteP;y`b-*p1d zH}cI^32{H_WF{y(9Cl|`TC0vKmC`{Ks#pTQ;cQ)kh-D1Zf=LlDt2PmLJ zK96OWQ8EHOPPUCN1Xx1R(m)6nJewAzcB_aCip14I-l_uGgnMG*YN0^NiWcw%AQbX7 zR15PtSH9JtWQGlfUMr#O6S)fU#Zk6awHH~nv>NmkGj}GIcD`tvx-G4R!tf&1Ix*&= zFP;S@ylW-&)hq%_yyf;~wuz}zc3D$%t%#ONu(=UQGS6jWu;m{dvttS6m2FrWFWy{A0U!JeoS3zW@Sy+ zd4}>58KM}74m|aHN5`G|y}K3jn9vY_j-xWgX`#U+I9jlM@N_toLYwH@(&?-Y6~IfA zaDC@Ku7^%G?Zw7NegNL;*`v52a$RIuhn*#5z3&FfRJvjvu9b{V)eV;^5D%0=N*HH)NYDOU?q+v!R1WmB14$|U$ks68o>A5>I;I`)hU_uUfS(Y?$K8Y@mJ<;J0xDE(d zJ`7cw17C0$J_+!pTpnPj)n};q5_myoCgJVU>$HWw5+nD?TV8fl zvK*#wO{{R>3=`XUQh^Dfa@;`DyXqrxTa~8OaE2TBb&Ry#l~9sgf6pN?+5VtoaGNXL z#576W4Gr$$mrM1%G!Gz7N=HQ`m2qW!${YoTK*uN{r^CQ=ze_<<3812zl|mO3F~;gu zs2`U?KSFW%Q7#TaDmxr4EchbJ^8nku9vCceULHr$&hrqlC8tDu?0JNk-^Z8n05LyW zQ$GaE7mU~E%(5-jk4E)rMBqY~n<48!xRD8LK1n>sRqVb1!#*ilr ztAC0MKpGFZ`-3vIgEsJI2oXYf}95$nyb_)o)FDAc>e7ug^ za|15P^P)APNdRy#hMh3#?ro59;LX?xc0SEK%>*^OcI_n`edNJif$uV!3`uta+5&o< zy5ZrY69RVK1ktjZkE{fm7*%UTooBd)!*NeX&D(T@0u!!yE@lGjn82L|<2TVnMd^Yb zzEb0M)Nq!Y&U!GJ7^A+qFev|maszh)4}E?auJ=ZrAyI8skJ0Ql>GAgY+3|R&(UL0% zF};U<=N_kAW~cX1o@9T+hKSWx@{zHvS)nsHc8VCV{GQgW*n7sH<@d4It{BjGt-UGb zupCQR))jdzaVOx?>&URca-QC_5$=G-KZp!3axRpGAbv;{phTx^Da?4*CsOU*vzg{t^z!ZKg%Py|zAYys(`SPV$EtgU*`SpCWQm%Td#z5xs<~oI zN2c6Y2{};@LNb#oBnN>?M59#0P{u0s$Yu#}L!8u-or*FY1AemJ1SUFz&CZfG2Js=_ z64Dwc12rzx94qf-=gam))16wVL#t|vB@x~e$<4CVI@FP#S zOR)nv&+M4?CFgkQQ#$G0`_oh}Rl&v;R`4fU8w1#xfT| z@)^r9hiKrJ$!KNWLCEFKV60#qLQ)LQ&^_d1mP(E>s|C|la(gbi6y~;#NQGA3LL4~R zog@Z+YS9$<86#qW17>isu}P^3OLPaqkQ#cnJL#}|WPA1BXF=#b(gI&x|j zR#}A92dk&fcj?fR*$kO&Y*?t_Z%3!yk*2+p?KHAEUec4<_x?(!4T?s4*qxn{MsPJ5 z8r^9a6_6@U#dtWLiqwl(M2=afq~kV>?42F*JMsjyGuJk;#s(&_pH3XG=JAV{lrTk( zzgJz+Ek(8(d{U8LNSk!LcbI-rq@*&Vft;@Dy7i5P#h7ub2jPXQl5|s z3plNv1_?jEU6b9cy`}MWM69F{h+A~TEx(H)iVw`dWwWpqQGTxZkxHY=)mj{v$$Kj|G{@?% zfrD1hJrb3y9Kb#{$-;Lp4hV?gUHo7@0Pdv;&4XxMT1Qz=jGNFbuZKwCR<4A7ju3cF z+;HGrS?4gFUM)d(`XhfqA+=&hE;4{tBy|I2z$+P<7n zVTE`rVuQ4&XC-X*a=w#bs<|?0^gbW5);Ct^ST7UQn7Ni{ubLp*mzk#26 z^j1nXDKP(4Pfo7_;7Va7-zlL-QbBcZz}*C0p3m zA#NC?s%{>LTdi%c>{LVTVlJ?Bg88k?xwyX*E1&W^`8trYb{73u%CIga?v?#5U||Ll3Y46NusWtMbI}x2xMHME;8ju{s+k_b-T2oW2;i=g@;vk@-^!fEY(qS}cuZ!b~8^ zDK_S$4VKs!02T@`L6(tdCJ4S%Cj(Ekqa@28{N>4InyQSQbA@#vyF2BYTWs0XIk#l| zNUfqkSasPH+&b)1j!KR1@Gr;1>q(I&Oa!clNSW$nqH{qB@7G6;&L)AQTTB-=}N)~PX#)BhM;{8hK^P3vV^g+q0q)!rin9BI16nT$` zI=JYf1=s;;&b6&u`*u8#I0X^CB>nUj=`i9H`>B*sPGyJ{G0Jsu|4~;3s3!1=&=Z;u z8eK(Ir`-2_;i;;)KFWK@vi7gpYkVh^5hvT5dwT#$}&= z?Y(PGs1aYMc4m$RQt!eOYJ`)@{4ib0>Jy?l0b%~V4XH-4PhJ6iDyks1OufE%{L5*zd6WoQMLj-S|#~_ymLmW9OYCuZ3(LQonMy^%AFXbG{g z#9R;zmcj7ltU2+N9sv{lNl+QWAftA}#l1^s zt=K3>^%#6Q6MG4cl{#A2pQ=s$wXB&X)lamNOt(MqX&8UaH4&%M9yYtmT-PW#aHhmm zJIqvhq-Y4%!b4S>(%`Wo&Q!uA}(|+zIV?t!n;?)8P&}$t-89I(;tzl!lBrGGBWD_EExc8wDGfna#JQHS zxuB>bkqk4MlXJ(v$Skqy^#>g)N4`yycX$=ymH$98Y)Og6lzA*_(EQk-N`DIcx&&cr z05^iDOX`<_*{UT&31@l?j3RgoVv$<-ng-Woz;+obmx4GGMyG=pQ}bX>M`?kz;z)Hj z*x1RUO`l!UaJY1qcEPcvI#yr1b8#X+ogGmc_@Ln7pKvtg-F$See_R-lGwuK)gpCg+ zYJ9{KPRUTk_OcT#45Y!N*p%D->Wd=;qGI!`!<}vBkX*!AbI)@%=zX226^)CWo&cXR zD>0mE4$vwXN@gxJJDq;VRgF0_tt%iS%<4qYml6c&2xvH;3vrNKHSLOyt7-Zu_pu)~ zGc<5zGdNi!a5hBAK)s%J`D?EogqEu|^cCjrm%ksvN1$%``frrVY5Zjo-g8Rgp%I zLUGuZ@Yop9dHp#$s~>j|WV2Pdo;EcMn(NM0rO0mls#jg8W|bX%!>)ZBAv}7}9fH=W zIAo(U5YH&c5|q$j%i=35u*YhR9KD%)>|dg_|r^6;CU8 zph;zA6pWx%Rr9=(HtwS9odU~Zi2LC9<>Gv40H+fA)d&;L@pz~qw!Mw3?8r6kGz5ck z{Jy^Nv^_CUraaA#`d%ThudkAYuL5ncu^~E##&hElP8}nvBsT=VfES+%#QdmzslVuK z%H^-wX{De(znD&q(VQ>r%FjGaJW#kA@y!uoE6^lxt!#lEIc6a|8s9fYp-nB61!LGf z$M*q8a^{M4!2n(njE1}Y$o_Xg!W-W z6y!T#P$8~N=|WsxB$)uz3~Dr(k~f~y4>s8!ifl<-^%oGv8BzI;uCcpmtea~vzvcYl z+CYRwVsF>}HS|4RVvovM9GN{a+`edhl6xpJO8|$-8CBMzqsbse_6}sUj4G-GgkMy3 zgiLcJWR^!H6>XCT)5CNeE6*sUGIH^Vf#}#Ah3E;t3*nqI>6bnUA+c)m+2t`t&g5U( zeZug@O8~BbkRZ!sCc)CyCt!eLzG$VSNNeV22O}WIS)!IlF5Onz(U zgh}Ux8C13r7Uq<`Zq4Z`zd#=qycS+6HE4%k*N6G!y01?nZ1(#Ucm-mUU2lz9z$d(0 z;aHAGxpUS>rfJ=sBhSo|Mjzjmd_(vJq8l=jY)!E#Q^8+9>^{`|&%n1hMkFGXQiClb z~>+d zxW(VekdtVVf0zAp$g!k>UGfe=DH|hPTiMh5j2NG$?6v_f5#aG%ltE?pLc(c9nXjbF z5%AE330ZbwyL?S8z_l&Ow%gs|0xXL`$TDLUwCusz(9X#T8A#uaxia<1q%ffRj^SsogEG5Qofu!3 z2b~y!oHZ0OB?N{ciQ^k5$7;DAQtJw9#l1iLH-)an^LkV0oa|GGiyMH+rA;J2!K4tC zuXL4%TLD*gB6CSFpV;(yNr=LF^4|-TalOyh_Vc<;i5W>-v7h485mzna)6hgNMEn)q1ZQ;RIX;$` z8(fk~>cTZCW4p;vJ2_r-R3Sow!xR>;v%EMh_|lxF1qesq{PX*?UdXOalj9Jq6L5zc zahqY&M~B_fJ-G^gF>GpMCng(UeKbHQ6cj^4%XnOINA6?JT+aoc`27=`o1&kC`Ads| zF+Z9vMm^XazLm6eHislOv}+q!%fo-kPSgRP!ePGml!C2j9F<=Q5rnxZGn!r!9v{D3 z%z|pJCP|@i3^e8h_j2TUP_Y_HcSId)r}w7xs)I5==Rrdm4vNSRAsHb20h zSPK_bX-b33ia1jq1)gAEho-Ql@}+r+DVGeA3Lm^(F)~MqJMIrUR5pB@s&tK8)x_P9 z#u+>b8XWdnbn+nDYKs^N`=N|4WQDxR{>t zgOE_@QN8|koB&rU1@R%K8AUb+X%&0-zsMJ!rZPjIuwe-uM0WjWIVmt)oUaU^#~W< za1YW!Z^YUoAgENbIkvOWABtxIl4vTH!D+$QivYJ5CP#y8Jl3LJIeV8kH?!tLrDG-m56yS{2_!ivYrIRdd*_V6)_#$xwT`rMvnj47>Q zgyOJ5GT9FtQq?mi^E>0|u#dxsu+f8#Ey7l1{|%b$Y^9~M!=>0^M>-v9HR=w<;VZ)3 zyqKzFOd(jon5Unx8sbaTms}CCMv}hZ^szx-?>}-BDkIkNK5es|WruC*Bi@W%9>hZj zUTG{P!T}ATCSvfPo?TSdfrSmRSdva~zi#}B8Z3dx#N!VSc2nhwuXaqg zb8>zGYC7_ys(I7w4sZwQXr|B#qCn;R13i1_MMOoPWF^&CSe$kPZ&38hhC z5(HjkGGo{|B3#i$N+?G$Fed9>s1KGxheC09cLDiTc3lC_EILA1D?3N2J z5=2VLow@{EwB;UF$h#2lVTG9GB*#==85Rt?n)|TYaVI+#YLi#V3{|_mT7^jLh-L+Y zdD5MS93d@IR14 zg%uu9Am64RV~$i9i#*^&7Ew7}6Ct}`zvW_R_w-jTfE0*KEI;J}NOk%rX%i6cm!yqR zPFC)ZqzfIx8qW_&os3BSNBUS5^98F>WJ>-faNsSNuk9s*`C+j zD0JYW7Nlgzlza%{_rS+|CmzLkzEFH4enAAgP5COwh+@!Jf!A%;)5np(xUYnmh$cRL zeM9y&wxM4QIno$=2GG2c0{>-}&z}HXp)+s=$_eeBX;OVb``bCiwl2G-*gB3KQ$-O^ z$s$a0IbJan<*-|8qu9?*t%raFc4<8XF4>_J&_=R5Dd1VMGl^j)u`6jHk7`F!!4=P6Qxay5@y)o%|qznLerwaBBq5w^~cJYrdL6UOE7BPAJGbx2{C4BG@}R8IHU2 z&FjYlY+>4DHyrA-nsGAEpALr728wEpxMv&_PlU?#flM|_q}yYha~uvovQ=Ak&YwFT zT%de-5kDwOW*!q(I7F?fOGYG%J%#@kEK>2==&;#q;)(<3$~&p*7p#K`sx+;fN!&MC zN7rp$P;Alm_j(fdz#nw7G2jkVV)AT$SWNCI`&|iXR>qfv&p;OF*Cp>uAb6J8mjSn; z-6PT!-NY1nqlhtS2SXjv6uK0O!=n@IZew;?GqX(+1pRQ<7&N+#2rgw~d}!cu>#$4I ztWtqP+$Po>4bPp+53c$H?~hzX2i_kgOX#pF$5{|$-+Yc@Q%r)Tnu5r9Bm2GX^|$C4 zENDGaeU(Pas1pLBKC0qMXhCAFG zr^C4z);UEjL)fKFijeCMR1&U`RDugd(y(eo5mGO~ z1h?boX96Kdwot3i%-E|jm--*yXt-ocamgZ~@3+>ROz<$rb`u<#ku~wdfl~xutLPr4 zm6B0kNB31}S|NKbCgYOf3N63FUSi6WjY@mRMx{L3_C!k*Hm{YZrkEi2h@d& zW#6rqf?LYz@BoULkkBpl1%0{PQhzdEcT4?mK(`ym6>#uUxut3M4^!(^<(8(+pNn)$ zmHOiEJ0`SuI!!!}bHsSrDgGfhK0iAi4?QNcgi1;PNiOfp&X^;a%?YQK`*8ef z@2$czOx<=F+Qn~uWz^b9O2L;Ei{XBtlY6uw2ridjD^?r)xUn3hMor(nHj}RD^YK#o zxM89lFBW>WdAh6N(nb2aF?!_hnkF=-QN7+6G_TC}Ri@>!@_^&??y~s7%JwgYZ<v$<4c*6EN#>F1 zMq1VhHss^zNELQ2xhPO*8JV2GjZaSefu9B;lzDGl-tC$Cc8qVp6(&|(qjLL7r{R5W zDHo>zbUbDeu93KjRRm>T=b);=gL1I#GERfS$ngnNGO2asq9P5JqP_&ZaQOL`f+&cV zQUdx?5Y4^h)sy1y-mV_Eobqzxb1JibDRjf|t0iGq-Es1RqzQ2Af9CEh;B6>CylNsVzkng zF?tu~bfwXsP#nuWn9WLyQI8J6D;Ouu$xPGfT5U=q=^Nxj*9`Fm4SR7kpPu6yU?~C~ z87|)T*5=l>#@i1@_jAU{cxqhiLDjgiQD?OUlvO(#W7!wgt%9UvtMxiSm&=_7+P{V>S?+9-7dnF{&D06G+4MUdRFunBLd4_IG+D9M zDn!t+Blv$uIAb zQ;Hcea+jeme&eFt7sZw5guW1QPZ6V)4ohkD6!BkNk5e0CXMiAoQM`oRHY71A^ie_$ zuBv6r6)BBlD8_a6Ds-&I-F|60KFcjmPK;^jsaeR6V5;!C1+=80q7sLYtO})!(TuJC zkH_~**Z1XL4X7+B7S>&lcMCz ze#3Z3iNaJ;;Gm*RhiiDk1bOju-GPuVO_~-|mVEpFdfqU+>>_xWV<)sPOR8)Y-DA4v z)sYih1$!jYWy% z`J+Nwy=#FU+?vA)i~L8jh}PPzuCbl-INYFTOqO=Qm#=MPHQl+>KK51FtkRs9^)?KX z5;(Er>A4mgDt2e>XPsN#;iPYE3P05wkI(M;gn-CdWh*twX^QNfve+~Qe6ii6Wb4yu zu`4$D4lnOwsZn*xE|yyEBdw4If9Ga}NaYO1JYL15Qg%RA)>SgUGLvDZ8*JIGmFX2i z9LEZ;XgFL!kTl!soRG})%CqE(IQNI8IAD(KD4;xj&ezNqb#c5V*-Cvhp7xOv6Xy|y z?5WQc`OZY|mZ~xc#)p6l5+tQiHOvIZZz=@!EogqEv8*6fk3+SHRSTxaBZ>Ty z9L3Po3B@Z0#)SO~Qx$0pPbiM1J}h`%zdOfLfc*$Mc6=NrScT<_eZSIi-dXrp?#fb0 zrZ9ccV5pt?7EV;yF>av{+^6(~HYg1qfy=Ed1-X(1g+Xu5^3GUNa!;zV`@yx1O^T8& zmcyv0wObX`bA{st6SF13+DH)O%V++)`v3acNQAYKz+qle`LPO_6Ds{!INb(0Mft$A z!s5GB1>A>xOzVXM)knp=wQy z^>L8I(&*k_AHw!{G3pPE2gYzM%xqKdnppN-54Jf{-D|=$o-{{|@kj?V*Mjkm(VdJ( z>kt%W?Fc={RR2^eS(L2Wbfb)JA}MtskEkir#X6WxfVVW5&LRoWDv;N@7l0c*jwHXS zc38nirHnVSy-F2tRNIv*QWZOvDq>ZemMU^J`<5)AgANS|3n}-YCZHWG9p1Io2uWR0J2&S_}@gV+Rz-2*wTPXj~i_XORLX z@H+yywlO?OkGS?H7u|k(;O>m4!$jcB71IRluXpFY)2RNlAJa{@EFK|8^6c{$hW&&ht zJQ$1@@)WHLu19T62M@5?N<|i8!S!MY%7Wo+?^bI;d$;)7FI$ZaN@AKkU23F|nWDNF znP^&qBgND&o95N>VmRnUi6}8H(vr4E7sYG3nl0cpTU7UN9lw4#3?{EE5leOQrZ1&N zNaTsSWTj@2SAkh3IDmEb^X)`GVlF-<@)bA_sIpUy4e6|s@=DHiVD`@2k_AFWYdo6K zt==*tx?Y~xYlahZ!heA;C05H>lY+!xNYobBQt1M)2AK`M1d?q$r)F!EL3!Xq~!0~&Y}z5n;FZQqpt@aC(4pP+=^ zvB5k&A2*O(_qw&tZfLrZcGPVEN?)9 z+-Yz;%-!0C>x*-@ka=#OpB;~fkV8hPg&f!0FAP=G=(0CHb9EpXFP-|8^!P9oUf8fX zy4CLC8n*W0xQDCUh(XzV-N9%!XPk7i$;Da3^vfreIZ@HkWBl;3L*vXiJ2s|l+}nds z$+R<1iw2DS+4zC{R;YkA%Q@Rq3-Un+h*!;)dpA@wH!^wR4NH!SpH1;=eX*HycVFru zyN!hf@oE<0Ha zD?W8}PWvHi%%u4sRTJT|_R>05F-trLK{2(d0p(vjj<%xu)QXu$h}ekYKA0v8)1h(P z9d>Ce60dl>Y>Z*ojB;{kR0An8G9LV}LR$Jz3WujUbbMMkzNe2)#-jfhlK`MzQkf{I zHs(%(#DK)C3VeLf42}6 zsBsF8hWobY2%k;^GObH;N`oOP0>pk$JS1#UcLHLo?`^hokpaMUVLHHz(3Wiu$&V-J zxKC^_x@U&3A{T?(#VDWb`1($FI-*ZQ3lg#v@qdCvmk*5TywtsK^b2fUkh2YKjeG&z z9I<^xF5@t&X}fR!bb#%kj?_WSNYy+r@6ZP>I+0+#RvumE2mR8-so(=YwcD4{*TYns zM7rv&Wj$!P&1@P`PI%iR7suDZ0#%w;%%Tg5QA0K4vcns+ zz?yjA{G;C_{9i?c8iR8XxyNJuR$bGfYnLECjbZ1A@W&-QjoCe?qa}X{FL2G#snvz? z*tKq!z{g|D97_N(w8@-1Z?KojtMef-wkP6RzI`=sQiPIAn|qhZk4v?0m`XNp?Xh>@ zQsvDBdT!DC;qO8gCSs1!id9~&o4p--2@J5!h7i2$5*evmmZHUhr<`KKbOek zi%9VrT)s$@Jf=Qh)V^Ilr!O+)k4s)J++|wM-jG*&DcwGH{E*z~mh|i)6dgvsUK(VO2fsMOEs%R!(E66D``!Zo})v0|$QlWSeR1)JD4 zm>&ta z=N3t*zQqEzZGR=-4#~^u4m%Q_dpD5n5D(^S@)pcq%O;{@t}hqUsWF=CqrPF?Lgq;< zwPR<}0)BDSJsui;lL+4iB6Kk3rQx_c*G}lao7edPdUYx=05GarNN>*&^MzRLf6h%jImdl^uU>EJwjn_n^GSvf5#T9y?OGRBrWZdiiSerB}nHi*%r4^ytF9<`^`u z%vDyV<+1XQ5e7N>-j2ZYG)~ z;g+Y)eA??cLqD5)DOcFgK4H3+o{-d{97W)gIzP5X1SigTOXR8&DsUv6G4h1JB@c#X zLIB^>I2a`eyzT5zx^kjwoY#z*yrejSTzHE?U~koABMk;9VvNKSHJCBj6ei_qFeVg7 zBvyn$5uInJaIiHlEMx`8*)ni#j1P^8fv`3Z1x-RT3`WF+Xgj^NCTW(v;3iTXjxgE_ z`sEC9Jt(-qo-K_N%&C^hP7@n{k!V#o zI6WF9-viX6HDAfu;t^3Ruy<_(6L^5QlZwDkm*io*81{2hqkF$OYK%vEAGe+dCiip2 zPJ@oqX`fQd{Hf8q&r|%fklE*KIGW#@8SS1iii&PB9AFm;ui4Y&!QMCxyt0YCEOo4B zf+ThbI4yr2opwhWzOq(3@%AAuY34_6^NYeYuKvT*%DIZ zhe&pBjfR8KeIX1Nb9EWn37v%2LCa+m9Oe-*D(6E!X*&7tu-7mi;`;h=uWMaVfXP;& zf9T`eoxyB2>Ed!cHU-)7`?ou@`Lx%a8NIU!J*GPX*rbJZ9rST97u<@6?ZKzyg?eI& z0-#1j(5MA}sYm{jPkU?F$wZUflG=lY=@}Dixl%|gmVxxBgm`Eboi8Ir>xf5t@G2pM z$hjt_*J2ZTq4}2!pxTjR7bkR0m*=htBd3qh_T0I{eg~iv*-|93cWXEUi`FPsB2Lrshzu)PQ zc^|@P_Xp$71efc~Pda1%ou)mf?R2Wy48E%Ajbf*ByNkWy8~gkF8}`0~ExwlvYcGF7 z+d1$A!6VVF0&}mmIx2~LzT6IqQ}VdJC;PH*+iX-qNt0r?6Z9v%HE%+)lZi3vn>Bj! zFIa-~@;`6qv1rj|KDee~Hu&~0pYOmSDHz9#d*+rV;huDgk9xyJpZQm)Uc8;pkI&A! zqdweh9~$w&q&uZpOIQkD2N@SPK__J`rLe70X_j}_3G8BS$TUhgbh;HuGDzEo&u?Ds zM83ZtlF2!Z0iAOYp#$vVB^t7A4flB5-tq@rFlN2!;Mjiem48(mi-+#)Nd6t2PYgJX z{=mx^e!V!lHy9bkv&FEB$>kOYfMoRf%>{tS^Sx(WGeqlr!BUV$2mt2SUADoF2DvckF+w9!m@U#cM?S4%TSJiIEou4)K_}vo zPZ@`YqB}>li;n^pgdl#65Drt&aA!On_A%?xa&A1D0eegnYZNzKtYIyFK8(k=BcJ*=U%bWRG><+^NZ z%S-3}N{JIf$}uT-NHRNe)We{O-Y`QNfjHCLr3808iLO8WMB>osEvB=<0|QF5HD-A$ zOeyM-V8VEmJLhVZ*eeH{KA343HYh&3;e*0*j{rt8cWVbj40~>K5&UGzP7pF93qzG0 z7`v#5}kp9P#uLvko zrtK|eI6O;0o7uowYcWCrZF3LFtd}BA#J@R;VVt;qB*I~7E~~3&Jcto7OKmU<^=G!k zf|iw|4bIM9+sJCJo0nrJd7-Q``y=v?=j7rKMkixLqQY^_>`$kiK80jc5l8hz!dSxq zjYkv+Q+xMUFah50$yO}CTAWQJe0R%Pr;X)g1Ql3*L7Yw;lAFE6;z7(y#&j&ms z1{#xwWuD=qVs!>R3&)>GvQndh8QUled8=M~^X(DKGAZzNIeGZ{9vx>|8wtC#gg8F4 znUlMPWCqQfH5IQqaIy^X#j^rxU@2H}l>Q-V+N9}&|Es%!fz%coxI0^;ModWfWA)dCr}3! z*W6O*vm(azut5&*r6^+co7Jun?`3D$KZ66Gwf${cV?(C9bT&s6*wC(Rpo$9r&0^)} zCHxH|{Ry~~6>`+i%=8>zZ3@gsZ+Jy+ouE~~Os9jY!J)Px{&D|aetwfZlHYCLbp7t$ z+}_-}eqz2idh}1<{C(p5erM-KmjKH5J3FrTH*TC5w)ZzqZk*6R^7~^Kyq@*_gV~6$ zc;Z|0@10?$bJ9JYon$`#@vDx1Hg|7qY;WJVzPsaie04+o+}f5ezWy!G-en7Vcb~m` zcRHO82glEjkG~<~c-omw45N1{0!xqgGBosfg+>ps+iK~JEYqWqcE*eKM%`iXXTEP| zthUbmx+fMpX2zVo`nc@A;DX@N?#4|gmo_&xu3x`?_3G}%#xDNAKVScr+7n-v`Hktf zf8F4(Wisa({?D`hDb7BBV2GcYZ^2)_^G))X`137KWu9f>`L(uu^T)m?llk!HWisFY z7x|O7;twtJR8D+%B)^;EFW3GX`HTO_zN59AYiA?*=J)ZJKZozW^)K-!@5CQhpK5)* z8}D~Mk;#1GFK06U@AvWV-i1H3r+}Bi>ks(TOy(K<<$w5ZGnwDRzw{4v$qU}E;rW++ zey#7=8<|oB>Z@_Oa z`Uu|tgm1q0vtIDd`}}Dp^IrVrSMkm7i0}O1{TRM`;|~BY{-uB3h<`2qS>y2zJpbRt zH}oC-<44~=!*@UXgZvvO|15a>c>OQ&&E^mB?=Xy>@cw5!{~CPrh5sG@&JSJ(uV277 z-zmQH>o1M(58#_``Qc!AAH(aP#y7tuz6+x7ck#`C|06DVQ&d}a`7`=2@%8t_H}a|W z)Q0x#@oXl4)1MXl5ApZUWHx^GStmFqZ~tZ)-p@Yk!uvIV@dwM_Y3}ddkMC~$s1rG( z&jpXBYnL3mYH2`td@sl)Y6u zs_D7C4?^wtCTH`$`#E0b>qiCG*Ueg?k*ycocw8*#N7+Up-)tP|ja$X5)aQSJe}DE1 zGMPr^i7P~WVef8vFn@-!%d@-4hhu5_nbvSIqkr$troFq;d`xL+>h5%bY~qW3fQy#A597Vg`F*`hnV+MX{^p>%g^ zWAnMYR0Xp@3jO@){LUVnD$#>Uq6-Q&UNZe={1zkKuhT|m5> zuRUu#GBUlhe&(6p)o1ij_Vs{dJc{z=WN|zkM1sk`ygMHl(~anm+4q}KzIP6}z~*>( z^_frTSDzW-mXCYmtIyoo!M`tGeWpL?-W!2ggWhbfH>6U2bf@0B`b@Krf6t$}`b^<= zE06ykW(%F8Vy##&9v!~YDd_ENu2wAIMW>Q&cl4v;VfLtrVy0s5R=KP<$}gasg*$p< zdyBp?|H9tmiTo4gWjXqQO|N49)**`hn}E_fEatOEMfs}HY+&-`m)>P-wdS49;VsOT zdXZoqWAe6!xtYxEBC#yaJAf-iub zX7LLyt`~B8quRL*h0(-ESfDfiey4uh{ClBzyOX=6*NCH~LxAbDntB6V?KIJww%%;m zc}~l9ywCW&Q+yfUHL|r%p;n_GFFe~H4)Fp5R|cefw$*;&cD8n#xY;^v9u)J?V}~z< z&I3nBq#7ZF-gsVk&>cQ7@V?!=b(k-1z5u~3m+)&CMceofKBCxjBNwj<^o3PA6%6-9q?M453UkNcRoBj>D^5g zRd(@cFdTHJuoUemknape{qe)u)#_kAySuq@SJW8cug`8gyScHogFo*sdeeD2oN$nL z3l{Cjn9Y^xy!q^=N$BD%h%!g_?9FDFcSb)}(}#mmFgqMb8^xp2%k4t-?#{E<-DJO< zf!mT1u1Rk)$zWE+^em*CBjRD^0@){PCiBIaYgZ8U_d4AC(5KVUqUS_-B~AFsC8!842Xr|d3P{`(|GO56!iz=$&7tGpKijVx_0GI zP{C4-%#YjoM#OEIH(&Y6r!tv0eC7}TkXFMYCp06fn$JNJLz`&sr>$mNKcWdEdj1aa{weXETunqu9QPITVZLg1;fuw?dJ{8< ze8S9shR-8Rd8Q4z6Q|6RXLOZK2Z*Rk5A5x6W#NAA{_UO*lG*PNl)`0euo%?j(L2Q( zz0taLWU~5Q;%VttBTqas$L8JQ#cjmPhx*Hz4+#EziSv2qPV=x&6VH#1>pC|S0t%Av?EiE65{*CTRzHLh0M1l z7$etwC4HanV7-K?{f5j@q0=mt+QlO%bNK&kus-?@dV^fVoespmh?zw5@#A=kYzaN( zAsOaTM7t9tZ((wE6{z0@)K6rPEFpCQql19zs8q|AJMF68%E&L?;PnM%T{0gOFy7?# zh3F#9S;B)Z+R=0li%@xxEwX={4(EGDf_w?CIT|zUUu9x4+eO~z2f=SuiJMGR+JJ|Szoy(q(t_etQ;g+V;KI;zQf*gMXlIWe$;;b{7 zPiL7wim(1-vR@86>Gn0G;&F_jZ^xg$ zoj={Y&YqGGa3?79>z^*4bsvc{4UXaeXZ{1cOowT*(prgMq!~HCKKEVk|0d>lbV`le zo$<*D)?PZt-PvH4AuY#0`ZG^tp0GZ`y4IP&OwstGnaqut8xs=Y#PB$5nVNoPKeZQAFVO01RC z@r`bKd$#3hC3cf@Xh3YPx%(>z50%n;d-qxIkDAPaAw5-sl^aCrjHHuA0egE6sPseB zFbbMY(w%eY$dl1-(DJur3EvgL5P0g4p9Ivne#wLJpnvtlozDDpFvCXD;Z=!T_EY|r z#C-H4AEq`RSvDeZotU>?d78QAB*_nq-d1Nk9bh|N=BqOH7{vC*8GC#wK63#WV09Iz zRb)Q23_-kdg80QXGf?tW@R&IoA4-j*52E*mR~)bsaEP>Jx7Zdx_XxXxyWLSAqX;YI zKx1J+rqElxyz7be3bboHoPpZa4?XRAFMl!{>i?P-PG0?JY6D9)@IzSY$-wEY!5fCD zZ4{Xg{bhLiM5dKJsvxU@6o0dGL{1o)?C(a%_=TBz^LFv*l~%EnM_AdcGY9U|STd&U zMG2XIk$1?pUuon!fX-v1@BLCj)^1Wt!o>A!0EqZeKE;9>z0bU1&0`kX$q5~x^k&|t zGf!T5-&Q6QkPnLDqggvhSOrIPo0$2NAm9TRNB~pdrhf0Wtq%Gch+Dv(2=t z!q_-G*335o<3C*|Mn`||1N&!_W0#&qa91A!*^jIVnWL8tAU+R9?3kLSmoJ9O^*i$k z!25K1@Eo*$F<}41vzg3bgwqdBa19rva_5OBujm3F--+}5O6KI#sX>)@MRADOc{x2_ zN;9X1%xhjovlKg7rfkQ!&GW{7T6G$05G^cA2BX|XwmjUk=(u0SXK-^Q8`5i$1 z(-Ly94oW<7L0phbiROF9ckMF&4juls*HDKYa!H1h)|yTR#<0)!*UmG41kb)U216X9 zY08GoF-A)oWWE{5yBCDq!I?KhgMCa8qToI_#MaZZi{vkOgOQUose|AR-Nz$%Cm8YW z*BRk5^4B4!|LEfmBToh`ECG`FakTravz=dd-<(1zIR^=|Pnpkw^dEUFNq0=_e}is( zT69BUVh2WRk>>OggtVsf5@4U1{CSwk-|$-Oxzj)YAqc>ACmRAx*V9xnLW%QU-{=jI z6t{mX7WzN*wAaIr1gU9z19!gF{TpG~&w%C+JYF{01U)>GeDMFYS>`lY1;( zW^@4fodf`EF7A5(>ZbsT{GC2Ka*&;)iO}umF++YxAaUu2i`B-af>|3GD#~eXL`8EV zF<*WK1NmLA4NsJ;c3_!r0} zpceam`1w89$eS+>9vS`IV2(51Nfkc--1QexOz`BDJ?uu%+Y{U;(;Z?_fgc;s-u&`a zG{Zp?b3;c7>4is$kup5sK!={UTu-g~RCZl)s z#pqD}yoYmesYsO#^=IA*LwHofwoR1E=dty$ja>p%4^COE&w+eF8Aux9G)SVzqQ*Wm zB?%AE?nkNH$X(Ul74UJ?v)eLKMfP$|Kl2&j{Tu7YYdO&oPij z(H$|8*YI=X6PezChjRoUV1VyF_tlw9q-7h|$g(Av$lJo0BlBC>N)+tK++<$J%^)kY zwee!+`$6}I#e_`7X4@TuWR=eR6#c--yX$A0H0uYBW|;61i8 zv#TRni*JToNj@C`qa(L%%bA&*XmRfUes7N&(S-|qn=XqEa4-UBc?KHnqBlvV)H>_s&D`(DkKHko5T z^Jb?zoKr)K;u6~bZ}Hpj?Fl-l=f4^e&SHkE!7LJTX!>_!HQn1|pumQY0>p?ys0&-j)Vvd5e~=78o2l>;FMR$2JpH3+IzMBb z{92X}KsMoi8|PT|=}HS0Vg5dJ`C<1Q<3OpE??A4+)WVezxHk)T4;BV9nupU&5%052L3Y+4#o#~Jek-X!|f;Tbm0)9>aePsi+rr**!!U;WuKX=>Pl*PLxO(xI9xy3fnwMKOEZ} zmx>@Fwl?b{6u%EFornla6yJ$IpcS416Mp73&ID&xm=aCD3vG|9Y#=05_xb*>vQLHQ z-K>_sW#ZnxVb!LVpLOlvM{|o4Hiu^7~>0 zmO?biL|G)`Ne>@i4CW?4eTze{33bLZYutP?-NbihVt$a`_-WE;mNL78M@NWtZDZ>W zdtGD&>ya15Y|Qik_ybrLNE@)D(vSR$?<1p7Lwqnl!bW?(2K-~(WK#Z?WQrwk$&`N9 z{T%x#tz{Et{F`CMfAcwJm4AiM@)+>Eyy#A8i}I6K{uX*19LsOwpnxZ@+(Td{|G326S*fTK*30ddJ3V=;;0emi;U{A@51svLrB1Wb$ppNF2X6Cdb|kmuRS72J3G zA2H7C#c{Xaq2-(mc}4$DKJ8##Xw;d`=L2z02z&iL2ejcB=e+jEIN8+Te*G24Yx#z_ zb5Fh@Y=-po81dgPUzv~TI1-kzcz)>>d;E>^F#$tTVcf%3W9%GpJf2SB5{-<99b^;k z%}<$Z|1a{35suI^?1WH$1fs$@f;BCpdxj%47}yWWMvQ}uWuwJ#2pT)^;ogmg|5!4O z=%H{LrvebbH$EW%n%^@fehcKEfgu&xL81odh%g2DB5U_^SKw9$go9c-z8@XdH(r_IRC_feq{6U?~55KRed>r z$it`MnaGscGH6(tej7kTM`h@27<7iH_-)b~w?>E`C`;HUIiWOPhNAx;3K(H&ckSo< zup-&KBWkk39Tq9stbdT0 zI|9805oc2H0g{5jh_Wdp{ohW0SAQ@=CWd8LX!8FF=QHH#MwFB7Gt2dNFkSdu$(^$( zkA=X09m3V4ZK&H@of#X#Tcl}du27+K*%;BLeWTCPwBsS!O&Y?#NSLUS1JuxzejCkQ zj0AhB+Tm8d{FG99{4J@Z|w+1?^;My&l8h$=wsbns~V(GKYA;Mp%Z=ZK3m=NhqX%D6os z*N3D%fRs4+y~6e8;!HU&Ha@?LxzVW~qi$nv@F(vfMFS1lB|nrY$S(_d1OoDd^wBkPQ2S2N(}>mCwQ|iFTi3WBc_OpFTHA zXh{?JGm>BV@e~tJa&5-M@-7XhrR`YXo}qjgrF2;~Ec3?zaB@4fXW_H0i=`MzIoCHm(@DMUTJ_8JRtn8a_hBHdB0L#jnD*)^l)0z}n z{ho7RU1JuSGGX%aR%Eld5!mXp6IP$R^8Z;Ax&-CGgDnbxK4Q6PBG*qL7-kNu3B1Wv z&vP`)=v#Bbo#CrUeo`)dhduXkxKNu%G3&?OZAAu{=N0}LDLztr*LMb>l;XFKp#d}| zrF1DOr3mF4iAGqn0nH;sG+Z$;ui_*4y3?u`GGBr3$o}4e%T70}8+`e2X4+xW`M(D1 z$Yg+Xht1D#$DpuvHZrkH$9y%B%yEz+<-DSadrH-h=EA8AYoYH*A6#_~oYxWr>)#1k zO9~iSN}4^I(Ibk1>G70R6MhCV)*y2_1Y1Z={WJty>P1#4S;5*d9m9WaTcjX{f3=r! zBsIo;c(4d3(K82wSo>~k`0L#fF6yv+lwHy~?)*C`!iT1hk@*;Yeg&}$Q=jwn)(}yX z-G^l2O(z1e=>7izK5~(``KXQW;h?vB!X%NW^k?87&t%;qAtNt>s#7)V!KCByFuORrLlcWh@k?P=ZR-Ye;NR>RbasM{!(q297(3+6W+axh zvFlUeEs=2kYp_aGMKp~0!}0V!&3@){{72-vWJmXqQ4xMF&F_C82b#}%rpMoi{1FXi zzS}z$H3-5Ee;6uT_tMogoqq@OEifmyd6P;1-y|lR(*HcDw>yUPQ*?*~5ke;dSLPB^ z8t$ja-^owsFbkBvHh3h9hrU9+wZ*+)<|#QNS?(uMi1vMf5H`7P_K3xgs0S}*{t`fZ zH-S(z?r~~-sZH!7@-jaRO8>&+K&iu3p)#CbCX+0jZfxjYZatVWEBGO%scfa!7qJr$<>WWL07|Wpn;^;$j*PR3`HoEd`^h(V7x*D)WLfVs1sh;j z$8xosRQ%t-sEV{8)5bq<{odQNpI%J00e{!$<=!6hH!SFXhFq6tj*+J1O5xX*TG08) zI1HJ<{U1Iry}{8+IrBQ0j`8(5sQ&8)4LGR^cgSJq!cqj0L(5#8mbRraN{782FoM?k zM0QjxI>UFRMz44T3XVlO^M{Z{lKw9Y66{TQydes&|CYf0uQ(dsG2?I>g z&fkWE;PA}Zh|%Huv=l}qKOmA+*lz-ZuLVYi^UtDa;2+U9rVcYt5i|#fjQ^?)B6l|2 z(=J7{6dL|36#g2tV-s?80&v2iXwtGJGn9_N?9-O*%c9D?3oi0epLQv zcEPE?|2n7K{)hXwd*cU*8`*NGad_K5gI|9_sFo!+C(f*Ljk0siz<<|&v~v%a&m7PE zZFJzjc#Jz>bNa{?`+Dk%U*2aE+b1cA|Lw3KerqdZ;Ja3ueDO45Y(esCSB}QUBnp2F zIQ%-!pGD@>V5yVm@bE*RLcv{@!OJsf`s<9J?k(Fa>)_Z#jr0}8I^^l)4{^^boT{hs z`}-p{-(ep5)3ki62c+o8xwG6+?ks;0opa4BUH-n|=##!?$ON^OJI5bz7jRt(|4#~hU}g;*^$mMb5$(oeOicLET4RUr}F z<%`u=-1QDGw&0#*A%!gIMF-P%%#&&9YABQ|n`;ts8JnuV=voZkLny$V4z~X5@n*@Um+Q980_`edA_b0vsvcD zX#JAsYYPdhfnjCJ|B84KuzSR(##t(LN>2P7qVLjlF`MJEv3cf)@Z^s>okd4LYyRMM zL+(=$&DT&DBH{8O%h9qu3@qihL$O-(M2!14!anlNKKXdj>0-jAH%PkLOyJ9k4;RWh+LxL;u#BToDE3y>F^atjsLSEYnx1y%sAgD=W(^D_{OU-*e8rbLTQ3qtx&B{=awN&OP^g_V4+g z@A;nZ+4#)q8OVZSiWVytXm)L*QA~{S)j|2TD{8Rt7C}jFycvGoD;z*{1f+X^3ZR3t za;+PDQY5s>r>4?2uNv1CV%2V$T;@X(`umiALlSx{rV5D5nn)EO^meHh3y2VUN)jDu zp0`|1^U^mhzA?-1cziGQoNZV72iaqJN>*a|CgFS{aBgwd@Y9J%7Kl>H&3Cso&L@s4D%=Nd<@Zx=f^xIoqlxlx<4GRqp&o)|r7-5m84UKtEwd%Gf~;Pnlk9 z>;3h(o<|@0bZ**{>d5x8-rhrg8XJAs;<$+mkrw zxq$wgX9v9hK4YsmyzJP{Tg;aXZX1_7ENX_qE-(Yk3}H4|8}#+P}Jd@XFH9f_`qh{`($TS&W_HaQ|sH{djd=|Ca6M zp^~SKXL9cCZ~Tq1Q5=59FQ*S|9DlOs+3Zi3o*HuJ4~*4v_zTxr zxAYt^^zf!%?yo%@dCz9X)^T{Bgcn`imLA@2>H6ccW3SG-ow3h2Jhh`OtADRWWrugR zS^Q?N85YL6x1e;NHhsUR%YmquN59^F^XCt>oXXgA4o{fXXPq@?)t$!OJBPhB?HLg7 zKREpBTTeZ{J8}NY+gIH07yaHvM;ZHs!(Ui+`u44>-e2?9)OGW>TovDrv2LKDP``+e z+dfdy@ynHSET6d!ha3VYoy6h$W`BF!_}$;EDfe}0G4Q+H`x(2L!_zOS9ed!-``Ryk zV%Hm=eq07T9O3Xb311glcf@49Upa5>p6i|kOX$*);xF%X@!A#dzSeog6NL-+x7zz1 z;^FX;eNWH-^^*H`&zRn21HCG1f7N;^}>B zVQ9zuuADdg`RBL&`;*R(V1U8lvtnL|eYtzpv3dS0S7n4PdXKRs9KPbj>1UprwR3FJ zjL1)vTph0%R$fgad?lNU1u!lGwJvFBbM7=vq!FH>{AX8>ifsD z3mz_N*LSa}CUj5YgQ&+~il_a!{hi`p@A1pCyW91?p_3JKZsYJOv-Og}S&ttde4qWu z#EsLD|NA)nCu7$vw)o~RH@|*uUh)9{os1pg@Gr~*c3&|qFKGTF6Ia%KdD_a@*wz&P z^4JNF)vP-DuU`{-44>OK8K;~4jl*xU%-a1`!s+!_1h0H}#;Gs6GWINomn{zcx$nVS zy9}!R;thYl%h6s=a`@>b3rG8B&x%|7=AxT!Zt0J9H>?fCzhY^@>1|#9zC3!f`N7t+ zM;`#4b9lh?gJ({5&YiNY=HV{~-cdK$JWpdV$?O$E|eJvKkw550s zWd45VGbg5`hXj6f!#CX~f*y)EJmtH^)7F=7`K|YNmv3xywEA7f_H%gY4PR`S)%L*D z8JXiYZg2%%iuMTF4fUHk4dF6Ui3$+)xR8CHi)qq96n%AS=uExL^%Fb8EKe=IJ zb-zP(yAr;IO^5S3IC+>X9yf`iJlge!HdJf-}b#>x*7boTXys>xB9bv(1fQK-OXYn=9 zy|w7<>dh4=4{f=1R%_7mWDYkBUhCLnwOoA3OZM&?|MAl@#_BlSbo=ced~)q0uOy7z z`&eMR=h2zG!r_nSSQ78FA05_ZQ}(r{gsgJh>WI-osNahZRQI{_(1dH+J{$ep*)C_E zW^4k7kGwkdr}w}3bw~i*clGLeMiq@ zM|X5vKBLFV;Ry-foCdw2-?=*+KbEATYDd*fXt|7~SYzch4xE=TVo=dsY=Eem>om^B z%7dbq=puWirM$*!gEcBTDkeHM9`B+WEKw=4RN>4GoN8EMtFTnpnw?Q)%$ig*)9#9N zU}K-NNUY+FtS+x{(o^JgSc=3_mLeAxKt>lKptWRXRV4ymaAx>I0UvTO6Vf}EG@2uE z1ru|zhRdyG6nGfG@)pV=HmR&z>vgN7rluv;8e&Z<(EagN=I6~9Jket@f@*yxx< zw8x5y8f@aLEt+E~azUTvEUIwA8WSHCGa@Q>WOQtt+L~Q_xdh)M+2lrB;;be{;R^+! zna31CpKF=zgodiZI^2iAH2B5_ULQi(=`ayGaFsR#`w&j$M%ZRkWob%4htz30pbd2v zIdCW|s;$W3aFp9iqAbT3F#=oMhRbX zi_KeQKvj`^HzmymP_9gI5W1XV3IeObn-ZZ!oRSqNUodrqfDLe+W@~ylFj&xwd&9O5 z*(F-#^(>l31DW-`6QAp2zr|ZxrF&(!4@JP5Mj+dl08rKm?UWCJboAmuCy1s2#5G$j z&#S=hIhtAUA&N zDMPnNQ+z%|B&ZtY=iQbM0cY}SALiiN2XhIi1R?+IidD74O~#Ta98TZ1(COVi6poAK z{CpjAH8!`nu(`#D&?=`mPl7;lI3ZA}kOt7&bVh^iP@;2fAf{$(d2arSV=8>Wm(r93 zx?-(91hot9qzWE?T@k6n9F%@GqVo~P>?d_cdOwfhiA<>)>q zCqk+NF^hx5uM2Lyd@*lxM5LCdfh;u}5!$PqrE{$pUUH?mt3#%U!f0cJt)$vG8ZUdb zk-p=NLyXfo0B{0`52yG@fa_?ZF(MWL;WjeX7|A^V5+@)d+>m$#!6c-v%xlv!|c))%of7t;;?I^Etp}7h*h$V z9j`5!5K(w0^peM;Lpp!adu1I|?JPa1XdG0XbcUI;sDPh$9hnC;Cp}!%>Ak;7x0Te) zEb?$O%kf}TwY7x(FsbhNlH=nGCQn(GeWuQI=442yDd=QK7?buku%`snWuG~QJg|_> zJC^PUS^6ZbnDW3R%nn0d8Chl-&UWO0U2XU`|4~3e%S@*^z%z{E+-AvDr&-N3@yS!D z35eU_%F+N_eH#lOviY^8ue<#ABG5(NlL(4Ku1B6ddlscKPrtnG^JzPSu!s`7tMP>6 zxNydb@dRS)9%gK~?GpTs<2ER_abiEYPQfpx=3t}R9M5f(G2vPPn}}r&Y$BE`Vavi3 z$m;N$&TaSLmtqgZ)>$R&6R?S}n_&}Sx5G98Pau0+bv>-QehgbCcO|Mhg(m`!VleT+ z^A{umLqW4`@JD`$+9UiJPGcX3IRUq!FhptO{;TTZH<>FcV$+k76dMj}Xdg!nt)Ac}u}Fm48tH`nnYRNBz~Lh^!Luz_de<(};sk z9&}(yr2$xI#}dORRWd^Xr|-+fCySQf^W}G}{9Y!%v0w6(_UjRNbg!i*|xs0xc#VWU)7iVDk8VRqM5Drp7kQAoHJ4wG1hN^3*(nBg?72*XNI*F8)EGi zqaE67%!c6Le}@rbsd2zebAG{q0i3>55SAV?RJ+oEzKJgIMWkVrPwT!?SMm$4%ZZha6JsqFKR9LHH=&gbYr10#aS(OYZH;I z$1$Zz%}an;&VlfwP0*ho5SR|Xk zqJR+=1x%&XdN_mJBwKz6Z25S+Qyy`H6g-O2<7@#OF4y6V!Vu0n;Gqq`!Zg^*aZ<)S zyUU2v>s*c+Qo8%v*3pVN#}arU-X-utHVq}!nSx|f^v2F8pDB3Ajf}pa#efad^~e;4 z3Q8H+=O&H}tmSlJA*8brMnxU5((kTsk8=c=hHXV7KE+TP)nGDM7NtrM=)D$Fy5CEp zI3eFAzyuP=CXhh3VD<=p1#FG9NyMb1r?}A+l*hXWbPRPti#|bY3l{xKzphrhP1~t4 zf722cyx9$=?HYbYQF^DFWVoc`QP7!#a%g*p8E}izp_9T;v8Y4e??z{)GlMz;8^6ni>=(8O}zkHbQ{D zn=k`59*<)5Qe`~DOTdu^opf!6++BCF$GUPH-(30ap zKT?k@5gc@Q+V;aL-C{JyhY{ZCmipmzJcM2{db*ts*bp5GDGbqV1RjeUg{8$M&eC%b zZCj1#ZJsK5fSztC{=&jMJ1lfZ#u=AUL&1iZnGvCCA|zB#Lk{wumG`p80wb-Id=27jVP&r+g{xtaWEx$ zepS9~%6_oVWz71g!vpaUbvBS6{zkm8}U}E=EIV}&w&)(kg@OzV6J?&@eGi2Dz zMIk3wsL>^df<&ueEC$~%`EeyULD^Z9MF0GjI@H4AKNOA z?K=M0fq*}P7u`-Qk>~E-bm?~o zU)hva*X!R6uZ{UZvUwkx8dl3WAu_#1x1Z#bT~qHJi4HisZ+gt`aC1Iyqh zfD!DM(=>S08j+UOPOv~c{sxleDb-6KZ~2u->+$j{Dge+JZCY5;*?3(W(x%m#htj4M%+tE6eA8oa(io9eEow$kguj70 z6-sOF>8)TKWDC8|`2t=VqfM(V;Qj{cnf#@XHax9;-M^Wj2?DD~OVCC;@^4TowBx}$ zGeug*u00;A3#Fl6l1V*r*p8<)r`-|ChQ?^qq6qyB$@rxb4R7ODsjpCO+dgfHuF+}Jg2;wYX8aQ7woRV;mavUD(B%yPG)9{i;lYy*+w-&v z+hpIN2?DD&EoxQ%2I>W-N=q8^$$#PTl^aq8F#gioCp-`Uj5Wn&_ zbQjUE*O%u^X)GR>j7Q;ej6DGeadaxFa6BmeP?Vl&5qo!+{rZa+BA~`I1<;sJq!Wcg zJZbrb5mVD9kq64HzX9x3<(UL!?A|F~q2JP*A7nf{6nE?h0-+jkLy`cYQV2+trEInn zd-}-qz~gT?#_f&&*bs-=Y_F&`oAWT?YtD3LR`Pj>0<0LKjo``Z2sS0<($v({38|^s zDVMQiWh6#Wa}I%IG-f(-iw=$V0AwRNT(76XOc>_pR%T!wXSom?6_=rivl1ogGE+P>pYDjw z=8Q(2(^AaQvFQ`iCS+#jq^BfDq-8i$Sh7dv<0iX{I99r;1<*N~%~_c_CbJo5t)(PK zCwoO*O8h0Mgd<8iJu78gPVTt0)YSA8YjRw2EEf4EC-PPP$+2RYe{!O-&L0p5GABZg z%}z zGO~1JDH#vUL}--C5h*Egc_XNnQ8bP{iJ=BPQD!_Hbv3BQm#r?%9+*GKm@6)@#i9UX znz(1kVVrEk1;7|M#U#r0*l{sYF>F|DtWj%XhL4PniyJvSIzbCH8e^iPM~oO@G>(Xi ziHYG(GlH}H#5KE{_>s>9*OCs zu+Xtm!~hc)#)a1d(vJe;{xqEw!Ih3g@k8&0q0u|Ef)2q*I0%0d3`1{Ak#^d`9&WGXWpPPigaJ;;gmj+&UKLdTx z7U7S?MQ`Oz1iTfb{;?$a!%#hXi?1`{n*~3MpXJ`TsOc>}!rvz8NBHy}-w`+-g1@cX zgf9}#y~S4y_}B0=;W^>2q5RQ2n-hNS-`;q9Bx3ECeuPi&`8y8BFX8W>&o>@l7dW@j z4XeE2k2>z2@E7=^xA?>$kz7XLNr0b9>93*k6206GKeKkg0^^B4cYH(PcFzvRUc*C% zWDsxpqxe49foAj)EHIw&iNPMhJK*_L`k`+!4aIi~{$AfH{4^Bb)yUBA@KgJW@HeV~ z_-=*2{kt(Yzeo6^5uZ1Dq4Iu%A=*WIg};XI*9P>G3_laz6#g2@pBc_q!OsWMA1Nrj zmG?N{o!>(H*(c&7m4vtaB?Ep5{4A6HkPWZ#y$$$E__2@$rlI`B!|gWdhkL}2xBQWp z*YUGzzwp&id{o{y;Aijw;SXr{8s7(ikAa`A{}lcjijVkC7W@=Te+`xQC-|EUKV~9C zn1=8-7;dZKXP@-fP<-9ta2S40z00F(5Py^5Jm5XlF&;7vm6zt{Z-Ji=4+?(`m6wL` zA%_@C!b7H^{84?R!%z5O?#-P)UB62GvfeBVP1&Ixf{{B7H8W&fivN_*=oGy_%1>rJ zf1xSbK_`U|RU*;67c%tcnjs`PQTw{2UVQMU86uLui}B>t_g61}-QjPUH-BEzU0vT_ zy>zn>-(&UsrKET($EkY$>X(D~&ad_T)hown_%ptbAC2)=AB4YY-u!8XnG^-lK{5Q< zrC*}c6o&fMsMW~dP&`+`&tqDDBsXb>lH`vD^v_E_^vw3$jxS z)5a(DF(WVLg2MF7TythYu6asky2)ISXG+V=$TZ~_jE?SO9F}g%NS%~bn3Xv;sSj40 zTdFHuRy`b!Y1xJ8I^Vfj={c#{rUHOX>6wM8Iq7M+Ifa=ylT1d!%@26qfzEX*^9!Rq zUf4Q3{g#!gl36T?jSBPYO&q5KsQwPSpZY$hjL%*U8Xe|m!4lK+%NDbgv$Uk5Jh?AB zL$fd2o%Uq0^|L^;^%G+Zx%G2$T2Ue2`k7q-t9I*WiM_IDe3jERHDN>%c6t}3WkuQM z*_frm$|5bs$jo!*SgbT}ichh$z3D#1esCZC$27&i$3jbG_qhkq7svP{{g z!u(6k>6rzoW3x=@a4?TgEih*mn(|W%bMwvVrm>U8jmyj#HyUer)2C$S#9_H@I$Dmj zaCbnIHwNfq$pdd_rnE`<&{^anmb`pZT56$5amvZfK{HIN=a!n4l{>|pKMCz7+eC5Y zry_Ss1E$czhiCrGS*FRREHB=&3)0M!P5B-!*<;fR5K&rgc3x%{xq;qzp*$e)fz+uz zkJe#59Xf#t=E-0kx$u-aIa9Sy$)2p*(@m4jV<%;15k@oe5sf)7H!}xVHRqx<1(~@y zTAbr}Nm*uiH=CxyUruV4IXx?jK1N4b%gf<_iW`TR(o*vZMo&)7noQWt%g?>Ulm?EL zKl+^Qz@s3_=3h$Cdpe`Bz-o>S?ghD%^3zN)qd~aiGVoM@in0qqPvd|{I?6GrpuhyO zD6LMS&3GV8OAEh2b4Pe58B}c>HjzNayfG{vLr<;oSd7;V&T$?#0;J zTRY!Ig+|-MU078PQbIXgNjS-(q8ex#HQWJbSsl*il0|H zrlPT&c@$3@%!zaAZPxP&iY-VESCd2Lm{^s7S2EC_FmEMI68}T>N?X(P=K;;w{m($it zoX1m6=ZaugWToa(B{&U@9g~!VzNE$mnZ9M%AR3S@)S`#{;DImCq9%Ct?QxX~PW1H_ zG72FBXu#f3{^$tVq0wr-6#ssW`j1ilXL!w-2Tdd;c{vbLU&5}4=VA=B16fA?q=Ldp z+2)){*?C#1Ii>;-Zp$z_b=VJg_L#EL%^6v_sfAdABA^BdEhx-~aHfL&C3rGqg4}$Z zmMMG(Nbtl-kiqhEKr=WlP&l=aP9&U+Gv%vrWQiv`Ha9oRl$xVvr=^4!jL*$4#4M_a zB}hWk#;4||rXdYAo>q!WZdPtSzZg`6XrsWhQVR<53f%$PN(Ym?fkVMVI|ZJenO2B{ zCPg$M5}KD=kXcA=L6*FObPtv8Bu`>EBm#x0z_bZ!5!y>&b}kwR34S;Mu}Q6&H+21N zIE`IGC60DAyL2by);qpdPb~_vJII_uF3aIVPPKBvr3+@QCKZCIiQ;yY(2PkrX@n!S zZaPVa$rv8zXHI3kWq^x3;pQp1`B~`&d8uh89IYwh>@2;Aka1JvwVsrOyGT!5@C6f7 z>9MO4ns6=nT6Y<7H^qr4H4}`Fb3G--?$TA%a%?)g1HqcWalO`&uDyCcA^burYa*Jq zffc5kb2BmuOoian7})U2qT8Pg4627IW{|%LEs5GAZBoK2LxPHN7ur!1yOhT0O;2Zf zx-ueZTK?|Gpc^4}g8l@froxP@)N$s537L6J@qq<5^?i_%1?Q-XI0C%+kVT|6E0)=N zL}Jc2f#rd=sB07X@O0-{P#l3ZZ63`$^?qvVo{l16HGz@vR=@jEdt-6BxVQdfyw`wf zX>=}z&04@WQRkscNlGd!c9xm31{}wld+nJbWK6-Lr!g1M@e*ceZ?KHgT#2)$a6_4s zErze_ssHlmC-q{4Lew60uP16Lr|_#IhKf^oRgxB;D%7+0C2m7~d;nybvu6tnA%A3K z=0ND+1WdP~fmAOoz!0A3q(GGk8tijbJX3$~?t6*9Q>82rR}|9KfyE@Y322CNaUq8i z5eWH)9a%80qIjP6^1`d&*gQy6?qErm2U+lnwvAc za){>;>-qL*=W{2N*QS;E4X_leshOj2+)7) z(`}&3Lm%Xkj5`&6=eD=bv!mZ%OVGOd@EnFU|0QSV+f=BB>yOzQ%ywpGLDoe_nq%S; zat}cLSYB%3c&H29)n}WYMY3qTrspEDXa1tZJW5Hok<>Pxut(F>b^rQKgk6UC z7BpXc9(ko}Gqy!x;Xq||jjI$(r$LqRxMnm{rl+}>h%U?Y$hSgvioBrt~MXd&)@VDqDu|u`Z(75+}By@#XCGq}m z5olOD;D9yW*p&|Q|5qG%FeqZCFDf)~;T#Ang@VHNG+%t0ds@Fo%(o~pd!M6fwwh~< zi7AxLrGYUC@E%Qb2?*X}Z$Kgl2O>KC7ZI4?B?RI2YCh%} z0XqG3m`5j1Z1G$Q5S(R(v4dy0hIIF8Q)wpQ-~zQz{JzX*{v)&Q(XdaW1{TO-_|UK$ z9j!H~P1lQ|xtepmh#P3hEzpu@{a-A(XVZNe1TexA4UKeNL-kh*YyGNM3VQ=KdZn;7 zfW8ydf6FU{d;e$U*%Rr>K>AUP&=uLyqx?#LBu6pIr&bZfFZTZa0wU0exOA82c0@&o zljFoTi^GnctyPr}eRiXTJS`K^@rM6dZmcqxzbqTRFsHvPQ3N@dLVI}!6?yM} zE0Pw@{YO`%ClhIlTD3Q!Ry~-Dj#xyD^;TGUZ(xl_bl#Y4JlZA`c~_vL@W1FN!(#a{ zdLDavWbIqsX@J`DA`!avt&F6n#QJUOj=YZ5&|CiL{$}?q(W$>VZe{MVZKS*l2o)fIE z22=bs&?R7{bvJxIh+W8O8TNTLD~|caIXlD(Mps<6Hh&EkZkC|b&m0JsNVtTsGT4S*}M#T;vgCpI8!VVDg2HVzT z808tm+L9YZkZ&u^F2rh}ps+x!m5VS_R@@0i;C4b>06Vr8n?KC4@i73)>@LTCJrVnk=kP<&>~69Q|Zr7B*&LoqQTL7ZzZP z04)Y5CD$t`oy<6LTyA&r47)R{ZMaGf=OEl>!U|MdG~cQs5=Ci_X|4t|S!^NFed(`H z*DYgXjZRS55vZ#Bi z8gCn<;X+#mGVv8gDN?1Tm(0wlaAiAZvWL*gERtyWlSi@tLlch8C*tTtvOm8(e`#0r zmzS=|g3x-wA`qxqIyfhARFnt{Fg?tmC)9-dEvq5z1UVipd_JU7l}-&u;4{@ zf{0*;zgKX8N|R=FbT!NSwZVGzZvz^OF)>^Ce6&Qyi_i8VGyEuBSLQf!%xeat~&SK^e}Ol(t5rAuyki0dF$ zl1xXD;dUdNR_shbh}wqTlaeS<4g!tG9j)bJ@PMNake5h=JchjJwr3|L+2#OAW^op0 zsebQv_Nl8`W*h-t(#)c#4$36t52?7KggJ2(e3s!IQI5soKn2XC@6wsaH z41_;){^667WIm|m?=~@>8alPsorSRoy8pa_CMEHxfQG?{<1KG-h+CC0#&D-M5`K3# z%`b|_Z)K)2ij5P)E^h&gXU=rkW@3PdA&om7s?q10>|Mp=Fa+D?EtnuVTwGwY&#^h& z=}>t#_z*x%X#fH~=`CPIl@&@!cM6oH)lKlI#vF$LhCXPJ81%~BhNDzF@esSk#>ezA zL&dllI#S*hJcLvl9BRiT2n9eY#)N5wykZKf?UngcvZ}xqB9NxZn@ds>xzp*%k^$Y@ zXd+{15M05lm-hY8Nqh04mmzfW#To| zM`8>|iikQ&OehG>InEaKcwJ*fh=n329MNu|j-Y_Ea5_>NXl(`PVgz+n@IqeB6$0S! zvvK~l&6ifsx;m1q;}}QeM~`N<9twUC};oh z(;(a`4eD;LMxOE}7f2c+B}WiOy=evf&=Ql?ZgHjIO7fZLIdDWb^%;}s|NxMSDr?R^W-9d?1IH}x0x)zn*QfpjQ zc{PriHnEC)@E9B&fZ9W!E}Kg>&K8-+QTr~4*E$!PGDj7NrJN%(37*TT;t=6Em!dnc zTi9VQmdnUkI>OF9zpxq+gd~OsKo!~P!*Psw4M_w3m`M6pFOey!FwhBX$`TX4w~{_g z5MMwXB5U>5NHj6Dx_rV%|BbG!XkuIvsqzJ`5DFx`_s2%Hh&ZmS+@OkE+o58ZGQIMy0znyl|pXj*P2BKu9& zK)oSalk%esC9yO=DD3YZd`+@5p;;5%Cm+Fyec@;y#5Z0bj^<`&QvfQ&SXWcGU~7Vd z2u)Bu5|J#;J0BUNa5@Vj?u}W4=8o87At1>YYpGMnvRB|xF6^=wQ^Z?Emr43tqA9Mt zrLJ_n9**sn?pYPy`RAUi^N&g7z4AMhtQZ52* zjBXteBPyD0p>8o!Ava!$jdqLFbJ4*fbn`{N&4q)Q5C;h{@0>Fy(YSvuC@ff}m5$!I zUR5g;sc?h(8>#rT(I$7-nSm(_(S2%JkCV$w)i@|s3PyY^dTSU7HtBYUs}|D8Y`U}D z;gTW_k?P+F#Z;-ORx2u&7|2}&l5!ilWEVST!-?v4tb5>%p3Uy6< zTp#A)thf+%W-2a}noW`Pc;+8hoK!HKMZz@}qv|x6)xDM+LI&~Vyr<@v$VPRQlM8`i z?vW8LVZr1YNzPwFh?Pf?nCIGEWi3R%qCB=*?Nw;9fUfZTlvZPV!b&V=Fp?jiKN&Vz<7n4`n zvy_k+Dkdd~H;p3DTByp(-M*m%DleYtIh-b`l}Ti-l0r1ZsCQ!K4Bo|< zFFu_|-3xJu^aKZlSDH%RLitH=U@AE#aSSIJJ}2Gaj5Jl;iT(nA@}NElBK%AaMk`sT zp8t?XG{Xw1Dbr}sFmc@$QG-V@Iv56pp|)f%Z}r5n zUU(q#)nEvGR!}>gr_`jAD{xskgqA-!5f7o_A|&WS74im+b4FFlq@@EVa555vX~7)G zr+x%F2_(*`pf^#0y^^#kME$Es?y}mQ(8O>J3pM^5JYmq&RgzBD%6qQ2)I|zoYxyXT z4}qTtaam{sOI)nk$*XV@aT;nXv<`Zlt&;Zi+pJtoTUAc|CRO31loBoUKyIi>x23j= znxLVusnUX7F&x~Ly4O4u0f+kHmQ}ihi#lQ|im1m-uwJe)=mh?$uWN;1l|ez{f+A;s zA9-8B0`ACpXfl%bMr>o2JR=B_N$g za1ctAF!-<(y#+aw&WqR2Nwf`fb_v#PxNHK_nHUXvPg)7$;taAi6*{XJ3J7%}3`d5Y z8l$2Llx91LePi=lFB# z{h&&*i3yJ>Wzcre`V!s)Z@~JUdTWMKNn+qK(|AyoQXplG1<%(aNx?+>VzmlJsGu(&gGPb`9cqw(-#yA3y0A;ONNN`^Z%p zDe5O9_1|ncaxsB23#`hnQs1=y{9Jgj;PJ?jzZVX}$)dKRq^i7-GzaJIO*s9UP&QEy zLdGJAQ0V;bMs>KGO?(1Z7G6v(JKa`VTvP7CS%<}Qt8sDltw65QXbKp*{L0&1_fi{QpF(nHs@uhvtIB={qGcr>={)K;H|30VX-;Y zewcXv2k0F+4aj9!q<&t7O5yWt)WvdK4WKNGG>DN3Tv5Xu!Ao)TnHM=q3*OCXdyQB0tj2-i+mmBc+4HsLHo6u zNeV*v0B@Zmu`waT14TG%o(mX++D`83&n~X4DK2-*D8q^C==JZ!2GDb})eXULasj@jN2QOd$70<* z7(WA!_XI+@crLF}S|Z~71*np%B64i5xmAwY)cU#1v4ljI)XJIAs7N`N+V@9FMT=I? z`M5vyM^u?<#g;O;20`}21HrO0z42;l&flZGHL8<~N#NAKlaQ=Z|0v{MD;UzJED#YQ zh)xb%xkyZExa}nGq&ZyZ7D#<<6C+sw8zk!3SfK>ql9K00R>(;-L|fZv3^9T?dl`!t zQVGVeHHhMVio(av{d{(4P?+;xt;IGWr>p-Ha_S+f&@!9@)Fn%yTl6+=H7HTWS`RS; z-2kye3{W^b#J$Nx@MS1@CPtRy`E3SH-V65UoJzBjoEo=TTw}zkYjR_>5rd9`m+c@&P$%&o8o#BwyttCaMkL)Vq+U$Fh@Eh#G=5bIAk_+q33B;Cp{=4?b)zo6JIUty z1%4Pba;vXSDIuU4q>XaIa=k3Mg-Jm+q$fQV^{a+}L0 z#_d^9Bar+>75Wq8DZRFUN2x9r;u>w6Mo2+ZspKlj2T5jf%SDQ;q-roKgaSjhNu}wz zm;Om))JPV_we*~+%~3mZMw10}-n&T%5D+Ax0d<+^cBH(ja=WFLr$#4@LtrxtwKA3K zS3;7i^-huNx$5X%;T8t7XqQ zgNC<8obUD*_Bsl1+kbEYG(sPVVl${H4e5PiuzivS@n4^75FZ=MZ19)YoOtotiSY@^ z%m4IbG)SW1j|~EUCQhz{=G4YjCy4;|M=pF2mzBXwB!V8{_|)&{=2{1jJ=RcP(O8Eh zy|jGXqza*GD83(WV(@q_p%10$+ssB(bR^ul#Ze(F_d(%wEh|&`hF|FWxEP!ScBp{m z#ABwZ61qs6sRBb@l9q|cuElU$=S}(K?T}A14S}{@fy%g)Pc&+rKhJ%Y*N@7x$+JO7 zuvh)KQZvm;bQ!40s<}1QT=5i&)kuniE?N3i)zrMay^Zxet7wrkd9>MObp7NVa>o|* zgo;jHELDmbpXA25a2&l*(?uaQpm-E@;X zEEc)yS)WjK-jb3u%Vzny*S+;Aqh1)LmI`b%hk!3kTk!<{KpRyYC0W%Atjv7SOh2tn zozh5x-c}(|ytt)NKZ>PsR|jus!A;1L3c1pY&aE}82iMZQP*|?4&PgcK*tGhKZp{!S zq@_hz5GY4?XAnb!od*^QQCNP`0!DY5btt?c|3YCs;iv*Jt&HUTLkf`jrZo{_Ze{Kmj(olwTW*JG4;5=)W=SBiZbV|ExTF4vI*# zOP!_M+ex1!d6EtZRYHR3Kt2;x0YP*tz7iyTXvRGnG6f^jk%|syd|2ZdfJjd}aiOX; zz4Kn$G4^YwiWJd}>Xp zU|bqkgUm_-vuT;K^yN}6C36JE|d+(BGbY?VqYB9au) z%p4o-^`i8S5~ISxpn^g^b9x4{pqQe?iUpco+h`OMV|;Z`zU_({EWAZfk{fS^U-t?J z5FG*OTA%{x;H+Hh2A>oOt@5dY+TPBzJknr?ArQeW*9*e00;<6@E1qi)e zss+>aPDoxPI?_CExt!*uZ(4j~mf!LCUg|m9uJjMG$MTe{#PUtT`9$E{;;i9^7oh+- z08OD>g4!Ec!r}`j;y0b_ZNB(CW{fENLr71muGiun$zsnnj$Gd^c5ZNitQB&jHf3d& zMJlvuDx^IhAfVR7_Byo+sQ#X9wEi%{B2OC{^Av-56Y{jWF;ArCroz!RR@vBMBI%iy zkWE2#iR*?SX{h@Yh_*?6ZnjsI)Rgj7AT*dcw1d9{4M*q8_(JYJU)1H(GZ$~z9%I-)F*K>%%enM7u1kz1j4BO6D-%*;sDd5`= zpMSXj*}HDN{$W%VhmT$U>hjqA30L0z=(kTB~OZblCjr0{JwRsKl;b_ zR|Wl?X()SYM#=`pe&g_cEu0|>{9k-wZKoAet}(2d$k<>5r5or!ByP>v6|)~*^ZonQ z8MmQhyNtslr`zxS;e|u@@7=qv?Y>>h^B8-W!z0rE)#Za%mVOrWbKCXb_sGg(>=cLl zPrK>ItMmG|Y&R$G>kf0n9{_#$Q~bGG*5rJA_KD2z*WP|-@Vb8YGIk$_$0SB>$hLGi z)Oqm1E7k`7h}sE;@-Wn|-?Yt!2T~7}JZ(Iab8mm+Z;XxN@H>7vePHAGlReL7f4cP4 zkUM{1td_%HxX!wz=YXMyH~n&d?cvCKHZ!)4!}}z>=<2rg@ODerAD10_b=K{Sea7Lb z9c@|tdo3zEytB>XH+#*nFxI^Vr5n&HdEV$>9vC?Mv3|$iS-osHV`UtkFssixYtE`W zjk|Xadu!S=Al?le{`IY=9^aif|K;r~?)Qs+@1moOeZ%1|tU7)B)>ZGXd28yr`CG1v zZ^u|a&`_vf#K&zPsOb3R$~l(LT!%vrfs>j!eBbPEj~l=Hn>FRWE-eOrw|hV8m&4O9 zsvUda&HLIfePY)epMG2hJbcaJZ4$mNwC;$>dcShs+CA4j3zpEgCBEg93-hHj} ziYE#e?r*jCJH*4`CHtP9|LZ09?Vd5c%gEQJ{;w>iA(>;0d9RCfJ?-NIhn^YQdY zKVz&{5XIB`*22(^_gy(}`18+i`}ZfEA7QMB!)L|35c_iXs$=u~SFXwkTl5}dH*)xj z6Q`efYSzxNNjuV#yC;3Sjq&+cy5`-Vq#KKMTSk%=3pBmZkS{3m1AEVlUOFE_t_ZC>&K|DB9|%Hdy_2kgFLT3*onM<%YU z`|`Avv8>h<|MJ)gkJYR?`mbLTdJLc2HyNj!EamWc2arh%=zN^@^ zVawGo$1nKivvs3QjNQfI6)R`ATKQIZc+@MKGP-}V6Lk9-hsU*8Tyfi_6?5j^_|iXL z|FHNg#x4q>_#;=0dj8W1TYtRhk5;RHIkapLW3xDXz@D7Z>~6bXv?j$T7$-CaJXUcTE`x%<>E_TvUlJ3kDrz?b{mJA zZomD5Pp*CBm4uOd9}8^vJUWwo9R7HYCGk%C(P3RSWnXJb$SP;74Mq#0elI>y-RI6j z6Rv6dZ1ituyPSC%{R@YWygK!#_rLgc%$hEnzTem9ex!Rphrb$BJg-&PT@yFf1(@gD zk(kd|AaD`tcl(Z>$BypkwtPm9mBSMfzBvs#LBF%CBYrGNMb(a~nb2|>OR>hvX&g8& zVZ@-Kx!3?vHP>mJjg<#QG0{c#N=tc-)dp)+bW}`qY&_mYHCUojWU0cL8#wf^!d79a zt~EQO%9u5&Xr|p2>A=Q5XOURN8ChLk97=ur7T4*EP#wILO^TD%&JNRyx`36 zg#te0U?!w@E@?DJ;tD3_Vhx|Y%75SDMy@xi|ZrT|77ce6J3$9D7Z{%3K;E2?EY4#X-gl3eu)IPI0imc|8^ac$_SYfv~s+?7&F5?`# z6Dxj=(EI>bMX}K_iD-`%6*btzS6ej4Qsja@%UM+6gf%8UDrQ7f?8xZYIJGsq_;Lxp zN3zL{w!~RYjKUWRLNkvkf|?OfobrK4ZJ>tu+w28bRH{h2KFJG%8jti zrpnTkfDWnCbU+*GEOOvbR#aP&!(n#fJQhnC=z>CXo=Z0shl$jSwdb3(9eC-S#27M712}qLDO^S>L(Wa%+7%nOMNfSG{t5|9|8)3 z0#_4v2_R$xX6LhAo1&hTQ6VM+Z++8xGwGY3}Nf zDWWji7-1`^Hjc*2UTviBc;gV`bPfQV0OG?bJ`&(M+Gvc3ML@WXj5S7b4}io8$Otzi zo^d^G){QyEQu{ZNaQH;833f79wrI zEEcx6Ic$Wq1+#3}e&?`>(iY4x)x|1V$Bx&QOo%8v6MD(x(IK6`=)JNIQwA(Osc0Nj zwsaPov#5Y?ypPO-x|SZUvi08ErrSztW)^w4ndN9Us@ht@ewb8ue97_g1(T=TXbN3s zI#XvllUJABW@6b{q**s9DE}DVY{{P$iA>6h1iKJDe+ zaJmmqI4{U4*dp*KW&$kZ@el&Z?1tjI6&Bu5p$V~f;~B-qLEY{)6s8rPbUbu=nJ|9t z`&h6J$9*?Tch)|XQb@r=sSw(PF)nV81sbix2znTbcvqR7*0i+_BQK?xL8x}l$B72$ zsIdC2b=aA+XV21^csL1$AI4^2xnb-_c%|4CLwQTVcPieG;!R1f#nX~amA2NbNZNwg2P*7{3RA0US@xN_>@&yU!1xcU zAn(TPZ4>J-CnQ0rMBxDyDynB^0QPk;_7t9QY(Hh}1#at$UrhC&7?jb?92SG$r@4(P zM_-Xtfbn?9jSN*}8%;&70xVlskrajsoPeh{=v^4Ud?^d6t02`|mr$|pE0}P~MME{q zWX)2Q^)t$v?I^37YPQtD&j+Cc0eLktUXhd!#Zcak_=)lil|W!+VL0p&cw^}TmXorD z!}0EqHqT&SX2)+f3S6n*U7*!nFSawipU0CU|P;K3K!!%N7>3GPE z%v2qw7XhYkG8Be#h|PM;0#X;o&%L+|n8k7xu{4b%mQqN;L#a?mVU#9Ah<&oNL~J{W z*rx!1+ER;AqY@Br%0npD7XYcCHDLxz%x%D@z#Q2G=ExSzcHvjRUX!+9rp4UWv*0=) z>(XU@D&k(IOzR1>H(=>_6r)Gm6>!j_jlxjjF=NS!n;UH!!ZRX%#Za1hG-1sZCopQJ z0!?HSXd+uMcH@gi+#1Uig-xP~n7AOYlOds|ppzkC;LT^q-UjxR0EHujY~HbSN66AA z5&A(qY{?EoUKv?t8O{=40Jm?$zxj^>3R-45%>kZa6z4Wet~$+Xrio9ULQO#24p){2 z;Og60_>j%7Eq&ePw-?Q_W^FZ2fvSU8@Y(E zln)V>*r*7*9kzeq3FHERa6PQLehk}c?&^(>NsJheCkPK2J)@2ABZlhPV^SER;~((+ z8ipTk{3dfFZMTCjM$tL{HBi=$)e@=eEA(KzcD+{O`QC`OZUA^e#cAq59Rl8 zd{fi=5#KUP+=Xy-ClF3JAIc$IjN|R@ZL~iyd$u3%@9;h#+vDS~i}px1(H_Yb%-+PW zfFTUG1+(KS?1TzCqr!+Uim+{@tu>YaD6sA-%&5YKs<3DkHcEx1sIV**mZ!q3Dy&R} zX(fqc$QKE5O_Ctm!mp4UsDBZ1gAq0%H&A1I8jp7YkQyjeJ)xb9o}BLhY=VxQDNGwY z(RlhaO>U^Frh^u%9HSedaG#|HBB2yKilKZR0XkdY9WQ|>JtraR>8Lpj!8;P~p?FjN zVdw78!!AgPY=V@?7R*_OfDuCxFl`SA#@B4J!$PERu@2i2fDyK-ZmsR{!;OdR;ECOI zcu2uRRZ0Pc(ee-PqJzVtHcX=u3U5kZ-ytekBf1h;Bb&e)*@D>){0i7EX_Fmdp3)%_ zZEw~}$91o9st?)n_OeN*7hMG=1uoY`?I5@8NHm?UX|>z*6snkg(-IcE*$t+rR8hJU zz6JRcvbNv}$Dsy{_s*g(+Qeam8NGZ`3|Jl>aw9V$oUrE}32gu@OII}%hA=!8PhTG! zf@lepVhWy6Jnp(WXG_4yC{0Y0;}{sh&s~V2%7xuuii1YJ(ehc!Gc^(_=TJOkqGcn9 z!JA;QcvG3;B%Jz7QO#r%)l9ZvzOYxoPUBm^bd5ufL%rdg>MI?OV)QcMm2eoR!#RZ^ zOwma09ct0sc#J-k=3vyG!qP;k`h)heYgPIv;6^o+HjOU*@s5zt#|(mjti_x1v`&7n zgI(Z^YyxLw3+7l7upRgoFdfcH>sTXb>w;j7p=~ML^K@vVFoZS~kCoC7H(t4jQC<7b z7tG6zOHIVzw$2*-A&npL7kCLm=(e z0RuSJQxKLOGE|4sV2~}^xE{xpCW%sL?U zAyak;^eUEmm?eDf!xM-Ntc_uDC|pzUC`OOPE8vi=!y<(tEcV0mbCa=H<*;LCa}$wR zk5Va3Jr-9;EItW0fkm%F zByH6ITo)_x{_aD(A)DV`df?n6>=S>SJv*^(Z=LD1$gxJLxXg57$yFy<$Wjf00=(-E zZd`ioH!pefC@BzhTo&ZmuU@dL4<~y zjvl26*lhx7(opIIbpY9C;@&*Qzo8iqhUEu5fn2{N22g$Qy%A41$w0j02!ue+*ik%z zxQtKHTugxNIEPKa?^-u)V=;b6|TBHt(Xt z)o>+7rJr^gLa}-#O4j ze7LSXxN;JoR_O%RPct#37m7AY0WJ)H69ACD9*QCeBpxay;x;iNOQcfzNvBfMYM;n! zJ~9A9UXSa%lC~+8ySlYcv*ov|h%{at=5>Aft!mGlnCZza9Ybl=@jN80qp$ZsV*+6YMIb#%1K$f8Vu_%GEpjmm=Y zRV3jMk9QK@xd;dTv~UvMqw%)jJqGVtc&Fe^w3CWA$p@s7 z6MZw;MBhxdVD`0iZOzcHbAQ3CBT^9lh(`#2@hU7qg{7-7%9HR{sKTbIFyav+KGJvz ze=Ze9+(N*vQDMX_1ngE7cBcw^M1`$UVVhLgRu#5Og}tW2-cezPRM=4!c1(r+q{2?C zumE6Glp{#mf?2o<>#V|ts<3DkrjGK61u^vJH$ub5?VA2v4pfK|M4!|NHo=cc#1{Ox zH*A6*2f#)RECP>WhQgALhup}}xLP|IH!EdUN?rDL z?y}6Zm6TCb8<+^&x~wf(WF@wSRa6*ifE~dj#+^sGjk0||o^V{T#Mm?3R)}8_f+|m6 zv1Y)=<57%$y50eYF}kr6g`tX_ipS`#Sh}%F3_SDmWpBZ62;lWcX{6u@!b3=v2KCpD zO%IFUpDoy4)S-I>nxOc?o6^)*Tvu6f-S7q%#4diJWa=d=j)+}U9N9$0ku8|rg*fTHch(_bC)4of)-&g0LcLOBi_pK zN02(ssblbh8QcId zpW44}(iw6a8^Bd6ZbwW3H-=!eAYM`73?hNFc|*Dxu8kqR9PT4^NT)D_^r?9MaFePs zG3hJHTXxi_0rg}{X_00{t419p$#gK@l!qbm`w7@Z1&~ct0NH}Mo=(7?!nc6&3Lt$I zCrwRH`ZBx(^0up|P-K*);8BcT>v9bo#_EtoVW?dbqn@QAE7dG6uA*~r>{aG!tYvkT znydKz;pbAsbZ2e&5%-7?#+)kx6=22;SFUp=t4AW`!HAZqMPeqXmhv?LZ^~Piq~g0_ z7f2+VKqA?KIS~rCN!v(V3lPOO{MCZA>~CHaO+Y?F*~ zFCOn)bTC{}@L){AjUL-;0gcvSo5E13`r=utV%yI=$5|*~qgfO3HNg!_qirSJGiAnSQynw;^=0mkFB(pY zp}d~Jqpg*zT8LU%h&PpCG2WCmb!MVg$R=uqY+|Nbz$h*OQ+Z3BsWaA*g#-Vgz<(Rq zgC_Dis0&@P$FD9WAWvBy*nOGl%#y3lu&an^gAbnlCJ>XAkXPzdp4}7iQw@i6ZhH^6 zd1EP);WD1P;s-`Ac)SBxtghZD4AomMo@>0-o0;xvYiJEwv(y|_J=I(7QoS|fXX;60iG2@WuiJE91WE~yR6??coSo;#GA@oCF_}5gQ#b+ ziFzg*#tmq{0@hjDWY0^>(oTk4W(rzzJm^Q7)sT%W=jwyf?KWa7o8Q zStX+vSf&FuL|0`LhN>(AkHuYOrNt%A(sM{FZGl#5Whr>fQ#ta)>`ycRilO-5ZsFNH zZZU}Fu>x;OcO~A`JV@#jXd|0I8`*@wB4Ce5f5EJuQ_MazbcDxQxW; zUUZ4cxSDcneF+YhiA z@$_VE!>UN(#0?hN>IMeXkf>K_jq8PkEttK!KjL6Y^2PyO*S_~nmv=83mmG3MLGY4y z6q;j;*Id2&vtjf7lG(;h@9w|3XXS}s9D{8i^$mGEgV+)_0vWJl$zH$54({KIKqjP3mE;)lPsFC0JS#%_y#`lsRJ))B{6 zojo~c*1`UtEh>0r<{fDVuWwb}vFx*Uy{dwe-rD!>=9gk8etq)zxFf%R`fgxi_oY|; z)_Squ#+a{`Z5cHVSv=eKEn!-HG1-&yrr&W6^WP-ey6miI^{*QT+;e5OvQ3VbuHWx9eVzW^qrnSqy2`)igPxa+y!*-LCf{&1 zuR8n;OG>_b(y5QHsf=%Z&)JRh?^NKCxwjRay7b6%cW=7%yMwQ6N~`Pkj5+f3$rs0* ze13H4)EyuH_T9qe$J^ZfP}!tsc5Z52cra$!)Wl)08Sal;WHW{@JaJ^k_`cH@C;u^O z{iNzs4=!pw|IN?+t3J>Eb(#`?3hkhcvRm)4xA3F!fXZEqF2$*l zcT@?^BbA0o+25cNG>209-i_jq-Ub%svdwcvR8*2*a6QBW$&8oz;}-{)igNtEV0UYB zcN=XBd1LT!wBcezM)dd1jSZ5WJLHCQF? z?QftyNlB|Ew;kVgu|{)E;k9W|cYz!d7^b2{-={>mdfXgBP8y?4D;RKp!%_SyX|>|E z%(?AI9MKqUT7)QnLvQIi@S=Z~h_u#Kzi-zBfmNFpbte9XckrvE)tcKBMn-=j$f5Sb%A<5@t+VZr1IZc{otCf z>7y$>`ZCY72;csOPBPAc1KwRM>g&W0f79nsL-XX{-*6niO1V06TTRtuY7QEsEf)!1 z{syJ1OzJc68j;p5OFCp~g21XR7xkL{29o5Iv@YVdOA7j&(1qglW#u$YsrVa6ULYLy zxpm)XBCWThzwV|Br72fe9!g8|U3gj}i{6>53#CbmA_V5~OC)~zsPNUow(GO;ddzFm zq7k2G`|8Hix~hEBV{pI3AP=QY zYk|~0FBX>i^lo>h7a(olxq;T6}HK~LlXp6 zEe?n9P{gSShrfUR^B9p<%;@`x`D=_eEozVchM(}O)YlN6)~JfWothx9YSW73p(vk} zmSgXBi%9Fth|W}4jnSqR1-QSVyM_)Ud0IF2j%%b}rtZeyFd4su!@&DagI$p=@r|!f z;iWO!w4wp`H)Ltj8phL_7v$Wa2?DFOTroTpVUo&K7q|Xmkyga)p88%-LmMRa_#3pe z5yR8UYfYO9w8l(>T@_$NIXDE;8krbI5Hd<)LsUpMhtrSZM+Sml1>%x^B2~yj32}#7 zp+cBUYrTZ@P(!^cA^lXy;d-IIt_K0zQ;jGENe_w6op4Uv#mDkMWf!c>S&LI$Xi z#S(In3UNzzO3cqnKknN3wjQLr$S88Fgqk2BEmeq9LVBr?$0Ve;3OOMm9aKmc$&W)+ zNQQ*;1w?qCsq$<}T|07#Lyr6no??ue`Txh>n*c^tWNpJY0YeC2h%7FkG#CMqB?$pS z1kzbL(2$KJY#MDs(jhI`>~vThk+7*4byQqm_jMd~Tp0xi6%fS*_uX+6lu-~D6jW4% z|9PtF-oAa)-E;tbzxm&}(5bqoPHm@7ojP@@Zk3>|`OgxS4r3u5uQ!&peiR4+6b($N{^*C+16Fdn*IPpNbmE3iDQ5hOPL^4T+B`)}dW z`Cg^NSb^oC7UnO{!oS$x375{`80IE*x4`m@1+-nXu72FG`+GHZ3-nfh=BjiUD=-}l z!$^m4K9f2*ps9tX&qFF5#*$du6@;-Ro{5v@!!4^JR6kCX z2l!x7NUaIsau|Jm2$K`Bv*5%OD zRDyHhc+pRWv6=kdkVec&9YF3*7T$NDlUC)X&z#bLv9`WaDTs89~~w3+jEIss*`CbrpKl zY31HJesiCZk>o$2!ET?NnP~?l&OoIyvH}9K9Dq+JJV{>(Cc49(uSg)4;q9idEQhN= zL~ywr;!_5>37K}GV zge2364EBJN8zd1`DU7XJYQ@1GE}GHmMlACNuW(UIGLc{FLZ*ewEfXB0N{J@*FLhXJ zlbPvY3n%M@4Yh$u=O{ZQgS(;$SCcJpi6fhE;&A;OkK3NAWmp#2?HS1#8R5i?-9Fl$ z>Y9`Zu5)GET}df9ld>l{odr4ejKu8RM!ODA$}T7>$jY3MZ3ifT{fAHWcakg>W^@5d zpv#r#EO5A7xXsy~k(3d%^Vw4;8l}m}vyU$*9G{(;nPaca7@m=WW5hE?i*v*?QshD6 z8Kd=+!~yXd<;}{sXFKz=vYZ7)c4PS~V}z6+NNI%XMX03{zln%wE!;tx!CX#9zP&Iz zyJ*71iP;gC)0&;Zl5JpQa~ZNH*z>ZAii(_$@%Bt-#t4;6#t1CIWsFcQk}*Oq!of92 zl~Z8PpEQ1gGs~H6&#cQB;b+v05pq#3Bh8mFg3EG9$A^dh^MAvn7vKM_Uh19-6Gh4I7baGe5~AMkNg&K59f#ni*=dB_}0~968cvOBSv zs!8^)$k&qIB!uk-&bX%pn#KuDu=KcSGXXd?PfI+iP{Gn$0{AV!u{|U4sFVdukB1CQ z0M7h%5-(JGUIgCcG{DSdI72tU= zT0M#%AFA`g>dOU`*MYO|O@Ss<_+aUA!awva9I%5QA4Ch9-dBLn0nW6yi6sr6!O~-U ztWY=t5r2Y}kLleCycSIU_=IYYeh7OCIG-rIQ03bKydA)K@m+ZE1g0k!QwZm@|5xB7 zzsEN@2?|y|R$&HkhP*G(LZ&wu!7kvmD7oR>2(8q z`*#vY{~Ihlw(qaNd+mFP6{l#&k`>b{b+bD0M3ORAn?FS5VU>S9-D#F^;cqrZjUiYFA+F1_es1^>79b$ zdw}z@!b7y6?LkxdJHYw+H<@0z_UN-;;^=>a@gK>S2E3#L;nQP#%u+bv(u+m;t^wZ7 zY#2PD$~O>UuPGdXh(E!~*B;6I1iW9P!l%df9TFX-`S9Zts(slW7XxP_zEI#3sy!}3 zSR69Hk_EsMN?zTC;5EQGD@Njls_z*{GQEPU(|AI)FUxl`a29k4pB{(t`+?JZw8W!+AFRITBX}EdW>Nvg6KZ_pIPj#x z5s3H`EIoGbZ-KWnA$<9m-igOZoN(!}{}uypVz=<=jRfBLzy}fe0v~e7@Frt;$DvHNO>}y;b>60p2sM@IXJ)(jxO^J8g>q zk9y{g2=G|nUn9Vy-V{%!Ha((!E#)J>42%#jDMGxo2=FKu?GfOyz7vDt1!>>2TjRBA zU-H$g)_ASj?P%a#5CL91@Ggx2kL`P71b9sEZxP@zy|oeGF}+tKz+-y<3WgVi&fm7i zYei?ugWaw1TG5$!KShZ5YlL_QBE)N_pPPU(@CnvGSiTMs;&qA;FFqKaY4MX~VZZDK zyj}{IPL4zr|3qasX~!*U$CnN#vg^PE}f{cxE}MMJHxGO3?!SZ<~> z&zYO=EXmI-&7P3n&xO2QC8aseLYK3o&^67O<8YM}IkKI(PDgRcSVl1?h4ixXOLHvH z!n~Y<%zQ@)z>XYeX=XuAc40xOvtWvYMHENTyaXkuM2kvbxexDbc`xkCjScm6xXh`3 z);TyUVoX9*UnKdK^pl!$*PTP>WdaN4P+lEZT zg$>iD+lEwn%4gSsSe}Z;^op8ttZsuu`9-!Ng_Za%7-AceGqorie~UA7T&0dYN4}%9 zc!n#-S(2HR=g2{TYeHs;%US9u&MYk~cI7y-ri>r&EEqo)w?yPja~2H8)e|}B9LgiY z0nuHoYGn~Y^d(33lwvIW6(W_QVn=pnsY4GcC@erv%Wf5xnU_~M%~d=FT_)ebw2CuP zI=zoFw!{c5pDWKX)sYtjEx#n&HPulZ5R#vjU4n$N3-gPdc?<);iAn`PfPviEmB(7B zo`Z$7Nv^4o4uwFck@W$e((ni>S4;l?AS?98H)u~ReirjnXP#f1|c*$`UAV-MO7 z0xF_^y2cEH=Q9?cs?BvHyrghSake9QEEsouE`GJ(qWn_u(|8cF+*?tdUQ*%!TU0fq z^JY9SW<|QVZP+FKIP$Qh0_SxiLa}WKJax4VNFulX&`Mk;c5aj*fy%>5Ab=d^t2t0k zRIU`AW?p6L@MPRW0(Zn{^f0)oBStA#!c#}!E)xMCE!>g3I)(V7BwpHZgqP!<%?0PV zS!wh=x7SbB~Bzh@rhzM9&q3jHeG zBa>BT(|k{jr`)@sY-&j)DNj?kbWc*ZbUQ=c()~LWZwi)nOWlpWHkUJPXmXie(5BjO zB@3vYIa*_Nxz}BJNKtVgnAaC^%mPPg?(~wJNoA=+M_P+LUBgx88gBd5`U)&Kq2EO8~Qr!7lfZN4gzA?tZyEr*wu<;^J;T>mv$B7&Tko3+R7q+1|rlUq3 z5^jcVH%fy}nwR6s%`40-#iEOZMk{DZX)y+D1Kdu5r(&EaEXHYb61%+uPo9Etxwrr$ zlGalN9i@UeV2yVa8}Jwf&nhg;b7U46#p$5nB@+sZOYz~b%pg`lvnOO0XJ#W0Bb|EB{K6bZ9+d$jq?-!C*jOMmexpp?RS34*Oer<0 z)@@RHH~C+M+RH_2YTRl>dWAaaHi{3n=CPqDWOl~hg1!Ko4*5;&b{-#mQy z@W35i>FJry5~zQFLm0n%ttLCc~~6t(E4u3UhNy9Hp*ow3cMhdRRnbHLxbQqtKb{aAjqd zI7Dmh?!$w%OTcGS^IWBwd6U?ePC+4dApq83bMH@2FLsm^L6@bLTj0PYMG_4Q0wK^a zq0F3w?J5#4Iy9aGeXjtGttZ(oG-|d3S?fu*4~eH2)kyNFkf=ovAf-lV3i(wuyy4nMFl;GdNR*x+}TZz-?8b0NfIYuN(t6Hf*{e zQ~nH`)72rt4Sq_r;$~wPA&#mmFLC?Q)8~j>N()7|!{j9wUGoIQJRKYbF<3mMq!cwn z?TYd;3mhey2Vob}YTq1A_FHNlkRx9lxCVQH%Qsk!2GX$(0(ytQE`taMDfE8*}nO?n|m)7WpL#dOm)>)RpDY*-YtzQ-Y7~W z(n{(6B{K@LT}Z>BT@H*0Mqe>7mp25C!saUkS`Wc;+_u84?^Y^ZcNpc-$*(SF zqhlM?I>SRN7*7Bhb1Z4kM{bJ8Mtx{2nY?vcw9TMy?4yuX(_9#d9T?Q98t^tDn63zw zW&sT8iGY)-;v_S=N_cm*3)U!{{@|)>!fo6>Z)2pYQMh(!U45Mi`Zk$} zc@UbgaFpieWsY~1OmY?(82F~KH3n^-xGkka0@G+83`4aybt&SYT;^;b%OUVEEcH_1 zQI>E~1U(Qe6cAbD&Y@K19vCPy4#;5I2`qrL^-zz~O{v-vq;YU*tM~N)wzBpuHBOKB z);BdMxtpG@dRAC5JQ!tYEl#P_2jc*aI<2vt6L7J3jT>Sg8`#msgT-8U#OkUKH*Kos zP-Nep16!!kW)^zDVE-ti<41+XPc}v+PHDb8mFbtvC;|JEkxQVwbxs&8a%G5VlRY$z z&Iwlw+qoqqV6QZ^+*S#wJ=IWuTBQ(dyR~-Zkt4j$bS2{A_4ITHBqQ(2!Vc{=HAX3l z)S8R*)Q!756;JEAl~i~=4N|uV%3;HTrYd?(aF+ZBA{^>iJGb6bX&dNr@oGC9)mCFW zSm_6yI*@TrZ9M=S+W5Em4=%i=equ21f5d7tH}cxZi$}$$Ot^_ueuKo}%UM_Ho^PeD z_1&u8gcuu*`%P6g{#;-S4$e$HqW)NBvb0B_!fWe4*b=V4iUA^YFp?>+ZL|$KVhtPp z2a_e@LGqw9IC9L*v4P@lkygdKZic7K@|4r8C!z5YnmkfKsdGppgtleT_}cRMA_@a> zLCzvAHlbIFriC%fMWQTZ>&&1_)=1?zt}l&E==;A|0CZo>ZFxDP%cnJF9@G;KpzjB8nrS#YiA(6 zMMo~ZfU+Kgw4cPe3!b`$CSMgkUItgDM#UyLResW7KIV7nlY@^~s@ap=3-a*Aw@fj( zwf~4^7Hmpl8>eN0YN`LFn!7e~rP_wM2dSBjtrHZ7(IDY3NfC)dqt9@fcPN^yE;E&? z{{M>dp&bnx;M}7~2FU-v(jY)UQJ6lX^90O=0g}_wh!JQ7IB`EV;iV&&9`tu5dvG~l zY{Hd#%Hd_uVYgg3D(FOsOiw;^9Z~xg6~6BOP=y2dk^?6ffU7+2no8e-1}rFRe*)~x zLm)^%YZ|rOnFmm&10>jKsvvDp9|G7ms4XTUeIa-0 zFhkd1u1C{&g@YHZ(+8n`Z8@0Y;TJ{Xe-1k4L%z;GDKn1p8 zhOP^@fcop>k($NmuVzD#=0pPD9!3Ht756wKwH8TH->GyrR&X@~D<@EWHlc?+sxq<2 zhW}k@YzUY?tQc((PJdXTB2yyKU*1MT-u&N&y5X4J8(>`tX*_gP8*V53-tN#J!Um@%*b?x8L@&JFj&Js}b3OCjm02Di z&KadB95Z_4IP8^*O-RR1IcG@&b`+J@U{L|v$#|+UL*BF@8jhj#xt-WK@2x7YaOc)x zqkC)uH{ceP`>IQ!R^x+R1VW?khk#WuFuEFDuHw>CCv(Z>cceK=@visc`-9ko_i*(@ zb`B0Ut}SoKr7^O^bDlfLUD;IO_KryzF%FxhkvD}m#I~uxsLwcDmxM4TQ0%VCFU5we z*n}AD$4_*zDE^ERUAS4xTb{K5AM?0UQgLT!Y{IQfQl?ir#*(&0bAVbIj~LuWrXR~H zivCi#q9+d@r{yD7R#(sf-xGO#E>s>@2D;{!;}B|)*5zq*)z$m(X%p@kb=Ot6$6&4r zF!s*k=1EsWJ*tSqH*JIDWK*`!jo9K@fo~(rX8}c?I|^cR&@07}1KHUNDr&GE#k)z_ z)Xg~Vp|~^;AJO9bm27+nT7pk^_|XWhSkIyOs$?iqji*tR$X^=s2&NZdF5*4TYQuJw zZ{7WTDB{^VGIED<>yE57Bj5FZe7=4q8v6ia6SjcSb4xNC7t~eYBv_xfzQ*NqxdioZ z0dtg4A(0#+*#FXS{4q*0RsBgiQ=xZuMjk$NR@qk*m?IlCXV&c8T3>$SZ0!z=B8wFn ze&=cG|I&)$k<(!;ob~(H=MNog{_xsGtm!-i9mX;MuFcE)wBNUk(_&_YYB9kVxkhE~4OiI!??E#c~pz4rE zWXv`z21i}T z-YIo+>gwm!3FS2vL_1XXsHY@4j zRC$4O5~BTr58RxF_CC4E?Onj@K4z6y%)y7}u?gqnt1YMTofczU1htYn9TTf7uXUT2 zGx41x_5+3vPfus00z{JEporN4j;TOdh9Ks4l*RHreR{fkE{Nokmkng<-`Q)Ufxb0j z^z`(4d0f5Q<<>?Z>L+c8$`t@a8;5BB3Kp%^*Z%kzIN4QR<6}gBiE|PE{X>tRp03Kl zn!giaI!(M7#$SXiM1A9sqNb;dq(Fv2NaNLDY51x!;j6@b0RH?&0e4emxTu~UADNID zHU^7WK6|#;JsUGXOlkc2utlGW7~P=cFhqMYSTxCUxJ%mYK_B$z!}>hZh6qMZ0}%1S zU=eHUD=~}l=fEP}9RZ?|@^D0m?uQPES*`j;aE#%n4DnRB#iTuXu$=h92r7nxJCIAr zxpZ=xoIz${PMBRP8m6SdQ&&7KuO4C{5qUa-g`}r5oEH=+0d#ZNOvd5d0Xd1W8WHj^ z!OSmjoP%UIUEPn9?M?PrEgP^doRdQe$vM;*>ql*3(kXYQS%YW|01;?(xISF@QpX8n z@KtOM3QWI^K+Ko_%;{Dp_yb+cKb3|Er;gx0*npfm+z{eT93wHKqotvRnMn)4LFd`B z9WM%3g%nt7x+B>~I1rSGPi=W?6Uf>T&?SiKs}+?zQy2tbO_+l#rredhdPU4Ie}OD7 zF2~p5!nATDY~{H{j`%lBFf|%(*u3^I|(?~ci$+B@n%R$_EhZfhQf>2|)4P23* zGXghlHBlRAhn1p#;AO*ykgxcu{Oh=aqCs{+-Q}M9_BIhRh z`>J8^MWI^FXo4P^piM#&BTZel?Maw=F88?nqFSKU6ip|hzIYh4JhFY!n8`@$(g3-p z#F@0L$>CGTCixX5`UmC4)0Aj_VKxn*Qp|NtZEHvnX$cx*DOPwnGEVhItpW-6#j?PW zPB>tvAN7m-I4I=dIxAl(4hoTLz^mnuN&78%N*HfBls;sI<9r4GvWXb{3lBEjsOzL_R}K?3JQ|dHPzIhj4tSKJrVIUooFl%r_-KFQBK|)5{NH|cq#Z_ zfGGl9Fx23yULhdIiCFXWU|EcY`bMDyCirJYxTh40Yh0B40!pm4V6LY2c$>*=8XtFiTNKO^g)1}K<1bPdbtj3QG8&FO8>_$;_ zFMB-{Zs^6j?k(V4h1OSzg-Hs@P*88c${En*oG&#;B;5yT$o!-P1S;2xpI~`%LaY@h zj~*vjMl3pqTykc^?dmV-Cp+yJj`{eF)3{Z2`k_yGWH+o;mNJtC4J*@KkThhJ#F|IsiltP9^(n`E;CW=;O-j+iN#M*naF2N;2bzA7A{ zQ?Rm4ZW#;ycXRfJ3Q;QV6n(YaC&u{Ifi$)%4`g2xg&=1ow?}-8gjSCnpZ=XQ2~a91 z(0yn^(V=lBtihSw8?Xxp&p?@$!hx998R!(SxZr}mn|xdKzJg5f&D9 z{!0R3u+!DiCR-^+u2+p+2w4lnEKf{j_O^?K$H zpP!2Ixd3}5u#Z@Z7Pv-i>M~Xh$bv}eflNukJC*7!*_k#k(LTG;H(dF%uy4cXmXPBp zXdofE)x#$QWG7ZSuN(#lW2cK43q0(Mx+zeZ{|Yb&3K9J`8W(|fXun|MHv!#_45bAKDIA=|?>JFsn%xq|o%AMf3`GS|gqy=uz?CM$A zxx*x=ry=E9PaQIF!GePWsJx=Y|K{iiQ;J(IcucFtiDukiB1YgxutBHQrl3q}3_@p` z0It$2r0=m1eYWljJHLln7D1Y@9Kr8N$J6T=RFDI-R*?I@ssK$Fx| zdgh`%s4CYUY$wr((V}fjoSPJGX7o(faX;b_Gf?iG>AK)lg~e+P{A(0z~ixl&D=02_x8I zLG7&ing|ai68!5x-DEpR9g7;FwE5kL=J0o$)HGo%Je@r|$6Zz4RO7?B+!Tey;Q9Jm zqyddp;9LY{lyd=Ll{HoX#GBYh$C=d+femYEvxAyU1iy5KHA`(ps}#o`$0q#d@6fpr z4sx=^3DBv2HBH(2IR!({5qkpDgyBL9gYlEL^i%;4p>Sbu9_OsXtZ|hE zSlSi7qTr+08=2}sNjZNz4G|zQY0~Aalrxm`Sw@Uz9`+;5Xry2gTE(frb`|C4Xnlak z@pl?jcHA%zy45#%E8LC7I82%U5k^PB18N%<&CfTWQN%hMhgczF2C&F74+>IAD|Xy! z?tU~DPW5Rmd8DArFJfF&VwgPGow1~afk_u5QigEg|=9YnmaMGoFJ~BXcVJhe<7(%TgBPAUGi!t z!Ch0s@kTNR3JMPjdGxQQnsTqRwxOv8-$RkF^25f(6pS)?LO3L(&++UZ7%mNcG0#&s zr_p?8g<8I4pLv9<{{ATs2Z?vl`70V~%Ii2c;&i&1qnLFQJ87tQenShOX@zQn+I~># zu5B>FIK=m+Zf@P+he@Nbde^pL3^0pheS17b{Cc#iG7Ac6yvhHbo^C!%FbT+Sga}Me zhy6xO`iD?;88QoIN+}dRY88X08RBR{Cih{8z~ISorCewoLdJyDIk^986dRnP!aC(J zQ=!!iA`3CI4ke~(X^iHuc%%_-oljXu)uJ#d6FYdjSTL=kwpGqgCDv^BG`Ka+BXDaeo^qP|Ma;1uXZXbl1Cx@bn8P0#f)?gK&@ zDA%?lhmgZE%$`?cC&8!0F$9}&w4l*q)Chj>QS!)rB@tq5{zLbPhbTkDUmVib=%@9oY>we|9C@*#+fdRpOP?Q!j`+N8GZiKrAuuRg)D=y%Ry07O z_&C&P1JTystDO?zzJRirRoY|<3*NgTO!1I=PK4=4+$% zq4gQf5JcS~=xP0qTbLpOzO05#ixVKKf7!*j3KvS%V7xyNVf0j?wh!i-t}~3?j>?^1 zN0l0MKUB`rvz+=naA5=#x^X(hp$=B7kxoY)43ut1E#|>gp~++yVh(OW(_ckD6l+hX zL5J0$DlPpLof=2@3#^*fNdHhUYwNT!oi07OT(o5Uyru?Wjp~XmN_v1LTfQ2$ zYf<06wpPdnS=90#zknIrI(x6$xC!H-Zm5_0my$=C_qvP|Cf|LSHdxA}?*dfBlf zT5Pvz4vT`m=if9fW>MW+7mZCL_<>jdSxBY7s%Z$PH9cFWU|AQ^Qh;_+Yj(DvrKg)V z>WVG1n_Kfwt2lazO59w2z#CS)M27p(ll4Hwe61quizYlag4431}3K4`i?R& zJL?vVEV%Gm@v5+w@l0Enai}ftc)(6)V>v@#0q4dsUJxg1$X!X;OQ`06`;bD&AqIPl z7ZMsnLfE*nHZffLs`;QU*+WjTgD)$a;XH5e%WCY&HG; z>X-=__A3B$D*o8ghGTt)Rh}B$x&K*Z4&19xqcDe5^;sxish`sPgeIZ7I#4Vk)k0le zjkh$#AEwz+06UuY9t69vM@)VKBSdmFL0}9EH(Hy;`i^FL4kbU~Ke6P2jYY$HJXf8l zr3fvCyQ_p9IGZcsVpYz+*H)~`=?#qQqPg{i7REfTIgQ7jFKJH{D_;;-rZr3P&E}#& zSb93nau<8T8jEn>bbWcH8dJz5cJRzxH$M|&e%mOhu&1b`R4lsggT^RVcd^-l3v-Xz z*Qga@zH{G>OTDM!eR<$Qy*@su z5i3ytk~=?1^U0ujMPrjV*a#IU0B9OZNvn78);gDz{XXSY1Wj?-6QT)u^XS~u;UPS~=!}!F3yiLoy%TqtAsY+}h;bIWRmIlE( z>{veT5kL!bLkT*NzEWhU&c<>PyB)986pU@M5?>Xz$a3ZNBo-praZZA>d$8jMPGnG! zJ@~DQ;gy^kzF9lvtjD8o%Y1*O9F+IKSA%ZxY?=Jn+3#Yt zQNYvA>34r+!422jHfREqB^IRg}nLXTj{rfDg{$NArC9m|ES)pmq3ix$D?S1pH z3A;}^kpJoOA5OdeI~2Yh(=UAD-hxjK{LT68eb-(ecmF9jgZ%~ki`Sbw6!y6Fv z`PegwSHG!g*9-XlJ%;VwmT}6;tsnl{^YkS@Kd)(91^nrYDxWxMz~B#7{dDVs4~E?I zxTbZ3@v&=E*WrH|JF+gO;{9jW?6~LtCmz7I8UgQnb!pcgx12wJ#8Xc_`P?9&pv+C3)6poNz=|0@T+$1{rkh`Y{*Jqmz~i&{pR#h-C&>W`y;j=pi$ z{Z~vq^Fh!@!0W$!vL)`A3eAH zv)CWIJoN2}d3l<)U%=a)b@}%f6!q_L^xUE^yUpu<8%CU1rW1Se{xys4EIaz-&5ow7 zFO9w(^%d~XT?00qdsb2Gd3Q}-+49BSN=^Gkz>gXKM$gn2PyA`krlb2_(z9|hM07`{ z^X1h)Jg{l>dC#uB>ei^FcaPnsX$u9sdP&zGPk!&}<4;}i`OEF1&O~{h5b&x?K7Zt# zE^khs=^X#qBfi)fnzl>8Uz_vwSGI5dRB6BE_@f4Xv*`^@8x+U%JEwhFTDdMc@58$J z_q}w{8VJV<0iS-_pWD6EV`W|RmOr1m=e?!#H0@>qziN5O-Y1X0^opd%UAK3dGZuXK zg@B*D`QoQeyn6D6S6xf8W46}iYud0*Ouzlv@9o=tT;a4Qo9_H#;N{gjHSJabf7AKv z^?%L^fX_b{@KG0J?)mWZpU2&M{HkwX>vt>gla6LO*RDHh`?htx zu9$h^$`NU4JNIhZ5&^&ax~k$;?Z5ulQ+M`1@IO~ye5aH>~eSCFUOy>?T-C7o#J>-n-2_r$_f)Tv3phaa`1_L>>BbLU;Q{;e1P zRlY;h{wm-DUaHQXc*)SX@>lvgzu*2H+VL|1Pg!}~1*s1{@>s(u@3(AB`x%-0)ET=FW$5N+l8?|I-{!}o@swX(-sSOuZO#}`}Ohj z&Yk+hlkMNF@xG{OPYU>JM>WPTYWK|3_w~GL+Op^yCTrT40v^-uwBh$=T{Y*Pd%yj# za^^LV|0f{tu2ET6Jby*X8)@g?c+b}lSA6vt2C3Z;(Qo&}pUU*I*&g2zFTUVwER)+c zhcwhQHS$;1=&dM|dsfP3H8xaX1J}^%h+`1FQQU#shDbhas7x+v^3^no{fBLi3F}hD zoJP!qE4&qmT#;VZ;H{qxTc1r7$2M?&+Q?JO=Hc6r`gx7EIoOm@mYh`PsjH}Is&vCU zG-+sZQc5b^vL@`_DHAJNZ779@#~|>iNM7>XhIp)ZQkhR2`QgK*292Q$U+byx);HEy z`D}ANjo2(|!_2?ZQ(u;nlsvkuqQ17a3EzJ$D4SbRCK4*EZG<;Db!hU)p(&%1QidC~ z^@&Aw@p)aujVjv*jdPGfMo!@h7NgCSs&(`3`Fgf-q#P`ZZZJq~<%rNUZbR|wab68h z1f9ppek7&wDpQyjMzqE}#QjwFIkXiE#|=5+F7qcnG8TXG}`DiRv9OVTk?zMKU! zgq(M`AulN&T|PuPY#CRfvv8XlYqmJ2eJ;*vcd-Vc3v$Hd)%;p~$HZZw4RpfCWz{vF zS(J+nX!l0gIKU-XMfwBE>#1+7npb)F?Soz7qGgU;Lm%-JMS?E$_bSiqHnff$^{VjE z1%==r(I$pnFXCatA}zeGMx4}CQH{ECp{tFRm8y-{LvtuG4c3iRw#-Gtko|GkA-;lY zLza5KQSKqcY;#$q_(Ttv2bUwu!)ACxM>qm0`Km*g=!l6poIx%X0-ns!2BLf90CGrb zXL1?N6R+TT%E*I9my0c8Wy-XbBa_vTIi?KO=y5e zqG)J9A6?P_-w3~3EO@f8p%+ry|eHYZx}^0@@^|j-G(w? zM=U-NEU&>{7iF8Rk2f zwXuYu#b|j6`+I8|PYk{Q>!6*qmC6^VrQ-YR8UagFzBsJ_zI_5#tbB1=6MVG-wm|vf zv@78IO~9^JzBmobh+3W2qsN7_CMA~c>pJm)r1;}L@4K=E%QRX}df9lG*m+1^V_Atf z5n)IX%N9Xe>!m9LXlrhIXlAm;>-^D;-* z6^?x^j(tTf`JE?M9{@(nl-OcH)TJA{ZgT7cL|cu7G|vkv^!fI2T8krA5xg&g`U--x zWL7dy0&D_)vH0=X05W$pk@-fz##qSAI34k0jd@C+e4_mK4q=b0{|+M3hB?^rV=k>} zL+A%+E^<-9w1C9*3}n=lpwRIVXtvd(5m486%vKw1ll4Y>ABsNfp zmc)X(=)GWuX0)1SgG+Aj3%3AnKe%VYJsEB_+(fvnPbOMTwj_PBCFzUPHmcB0+6&63 zdUa)x@vOaQ12MG4`n?IlJA57BRVy-&UR{ZVq`$Ki0gly|IaagF3q%E5b(v!oVfrYk zzz<*McvymEW(xekWsV0VIL4gFy_Y%em0(#Og?-m$j=Ll{P8Jg^XYZ=1(AzF^+$KY1 z$rbpf%N#dJa5p`YY1rm)C5LV4>yJuGU$Wsl1HRJ*-noYFV#9Z<;d|Why<+%w8op?x zAX8}%n03tRick_*e|GgC$NE(R=2v2oS&Tz2=m<9*nv#61GE0|N@`I1`^uTu^x0taV zzeN0)pnS~3e4;M5bk1(pvEZ^CT`@jktBb~+hI}pohmL@IDO_^$WpF3Ly&Ue@aQ_Uq z3GNkefumgs7u#I4tKdEfcO~36;9d=vQt2AF-@?5XZVd9f4lawzF+%nL`eYBFFHZ2i zgl$%MCKZGlonznb_^ysvjAfKP^mm5e-riv7$JZ@i7r*>L#J(LrZRxt`qH221i9UeV z0bpZi@h<-8px70Ty#f#zM-T42bm3mD=`8sg&m5ZC4`1iYGXZ=jhl?No_zTNl^hIq( zq+^3;5jz~E9tGXZkfWmM z=m$pVC-4mrp~3pjF9@B0Uo3unsPCEkP9kEaS^5s+kbl0z@8<;k5l_@qv38k~lb){o zLLf7l826j7erUO}OetesOBWKzfS&^;M@WXR7koKazcv!g? zA6!L)T1RW66PPQX!GQCfBLJTy^?sgw)l$^^3iUo*z5kEp{Ymwns>1)J-bdhF@7JnG zB7`(50>Mf1!3y^^)$h|W7SHQBA~#+gN#FNipOuoG58~%s37NQ8;9nYKRgVha+*2w6DS$R3{B{l zHkA_{mZ2e9?zir);6F!6*~%%cY)krNThb@B3kiDxaU{%`-bvZIboDkS=Q|EkNNWBo z@>jP^S*=g=+N(hr%B*%g678-9BkL%H>fM0JS-bXfz=|wnWgL<<3BR4a@kcz?VbQF- zr>9?Feht&*wP3oun6ydN-Q0ax4k~=Cm)?D{RW|{vG#>{z)ODe{=jw3aOOofnCrM79 z9L^+cGvY}YNWS>1i`%L3Y4~$19Q&Z%iHS2tu4O*}@pk+$azzCnxh`8ifB%64McW0^ z#@Ln@giqq?BbG6s0r|He$Sqw&?DbKTtLf3B$$_rPG_Hw(uF?eXoi1V^U04!Y6(Ur+ z@sGd0{LR1tP}NS)S`2_cqGDo3DvH;VAPCWNOiOG_R`&z1llk)Z4Sz+{mnIx+OV-{4 zp<{#+v_$xZ0Cu79jet*%k7MDxM8KTzQQmZiUWPfB@Xdfvj+rj_9DN)0X{jlvb?n8#fY?|FB|XE@eAHPCn1FVM;7Ok3=z^3osaL|;YWS9*wQ^2 zhf;@9Y?ymRRu%>|%pF{^`zRgG{7B0KHdM-K!oh4n^rg~yj(}!aorqU2F z0JC?TEF*;)fQPFz^#PcQ5FdR2hH@$%eE_~wz3T(;D$Dy<>Rlgz<3R#G9Dq5%Q(Ewu zc&r?dg|s${6w=NrQlJ$ylb&U8ITE6f&7>`~>}Jx%0lyR}^huFIU!3-~3hgB3{Svm@ zfc>O=akxNBrqW64pnP#!Hv@L80Xx}%k)LFG!wuLd14f>bWf^b4XyK8tX$GvqfXy~w z=NqtQ0~Rn!|85qkuAqmsL-m921mxabjQFALP*uRo!H>Oxk5wnYTn9FtKyxqSu+_+F zU$(J#j18j^1Rc0S7@@vL-qZ2ZAC`$+7YjE}0U;3ucVUogMyIDL+svUHvy0}DaMR&V zfO|UJGvJPa%Q}sP%leTABv;ZWxspD~l@dm&CSd_B?1-I=$(n|_TKhyHzn5<0oULj_ zlz+n09;XnjWUlLS@Lx~l0z3?>ToJ|5*D zvW(3Pa6Pm-3tIBhdxN!aVkXEF62mWq2m(j0H083hw*MiuvM zR7pMoW_6uZHuEuxVK~`LwvW&ZhHgt5QRmYi=1sFX#s@K|6aLp|$$t02Wtr|*?;JcO z&FGUfqc2XZ$w=5b;7eE_JMN2rB33tg>sl?l#Aw71&V3Xhzl1k))mqn+G3(V8aUTsrK5iW5PB7d+k!N{DuSFJ(U9n z2%_5&mp?viJM~}=A*T%1Ud=o?;YLMJ6Zx!E0y7yvNn`pXjp>WS;lNP51Z=hPnQ1Jo zpdhdAX+>Gmvj*{FXl@Qe#lZ-*nSerKm`=fTSXQl8W?6DoPlsC}E3noEMnoiYeQTO!V@vn6k})=^3y8w9kquTb3@|rujNS! zYdbr@0~Z9?wsc)X{6mhL)^9m>g#(eduiw&Tg##&X@8sCl$+2aHW8VkH7zQO;qte+O zms;V&a`^EYLutJCXd8dIJr30!dF_ajy&d4 zG;_1#HxNI+oZ&#Js}p?@;;CzBlB>=%HvS9Z-cu*i!tnxfC7S0d*EjiyW;RuFIC=^{ zJe(aeF^R-aCg837c?g#{jG4R zS$zhVRr(xm0o*U(&VmbGYF+?$2i#lXehK$pxZuF%RdBzB%eLPImn}%$LCPumq@1EJ zPGhbT_O}DF=Yi z)MvG}k7y34>yCY^4=nY+?05#{1Y+x0zHqTt1jZUGGE6oy93aF{RVPb^Yqa^uxzl=< zLYKUH#xe<`%wcn<8O2oQrP~*+aO_#SaL@LICxosk!oOeW38;Kv8f(4>lb`m&iu_$Z z`_hHGIyI)Rp?&JK{9UV&pZ3<4mMMD|e@cS3z|Yao`QCG zy=ujjeLLqMyZ8$d4^D@jnJp;$I!NLzebAzDYh>$~TU0dS`t4mpWmaX(z@Ft`FXbyW zR_Wu+X)kIJBUV17FPH?aL2oSrt}a23vFL025teO{pp3&F?S=~*ka}84P$fKtAZ-*% z8Z)xv*A>6u!jqwa!jpp1Dm;0{eGuVE4w=eU!a4fksr^1~JHxurk;7)?O z5N-|JMR3tGX)0{K0`5|{cfef^m+IriaG!^Zz9$xETj1`&`%1V`$op!zz2II4cNAPm zyyhIZkVMUs;ob?CG`R;ZO*@c;&D7)XhkG8}2jE@=_aV3>$fI!o2kv8V;nyHBo1cXH zINUvO(JPvNgu4drKDg`Qb_6Xpz>b8u~NH^ChT_XW7+a9@T?e%TC{O`nFiQtHwt zr7nGO+BOy1Nz6$kjMh7e*G>82G`j&~eI=fGwzza*tmf;<@!Bwy!*(GzIjlwuO>UKm ze>x{FbNM=75A>&{>oP3{c>?9?iq!P*uJ%?1BpfT?+mYzftA|9FD2z7tsJ&T<;Jp*@Crtn#C(F*qL!GEMjr;Unp!MeSMv zn`nfRCE5Hjn%96`4BssR#^G6}au0lW2-pJ#Y$JSNGsNYvE%Dxl?>+(h(17iNZyI3T zwV&a8P=s$2y5;2bg3LQj9}Ji-CJJ=Uw6nzceLpzM3VC z-ptUBA2Ve_>It?gbv&d^EW&5@fnX4OUG+mfg{_(LfX|DNmFC4}{k=g38{wB)-tV)# zzhHTP-}3&O>D@4C-K&6f^zKC2E!2Iu&=5t(#9-Y__<3+`aQ_5%AY5ps&12v;BnT?UtG{c^Ze<1U1I9bEXE?}mFZ+`q$J0ry$Bm%x1kZVTME;G(k4TjBm0F53!1 zP?Tc|{8B*BCj|t3aT;Su*n7$sr+sF?zA#|B4cJcxtQ}I2aXToVw69Cpu?Fm918;x< z8*acTXk}Tl4cK@CR%XCv8ZaT4@}Lek2{f))IDJB3r$WvGZT;W)?bm6L)d2ucI zs}3Yy#u5grVyDQe7_hxZ#W9N5*6lsk_(7^@K?$tl&S9daI|oXquXLb%;@R0vI-R9+ zlyH`S zlPjC-o&7`%^gXq*Nn3_Y`9}C;+`HhDaVc)@lh6GH_?ds_Hj#b2m5fW3pi&kNs2 z`1_LZeTKiph~Y$2dsFzn!(W*SRirZn3_7KDrtr0gk2Q!9C)b@Ne4PP1Tll)d=Mui| z@KJ)qXzf8=>zH^PLh}G;7@s@42bw-|5N_SY$T(C|>0aB$F;U;kC=_{SY{##&`oZCY zv9XKRnbQ&diPw(OUla2Rh9_fnA^?zN0i=w!0@AF2QC0viax^EJG6DcOAoKidemfYT z`%}_VHOE663qP$eZwE7*V~E-jO`uSN?Hn5^La{pl$`%KAr+U{Hu7!{WOkcRhI4d4~ z;Tq#(!27-GU0=97^82JrW?|Ocd)VrP^xsQ*Y-yF+(i+b1dqdvyRyi<)6 z6a69YP}!y_XPE*%hB2FbwF)jZ&Bx(>1osKJpTm6;?moDXCe1WGY=Fytv=QzraG!_! zHryBB{uAy?a6g5+8SW0aufm17M(lw50q&c4C+ks*lsW=^Qb(XKPD6==JnFIu&avNjer><^fqBu!i~# z7@hfks~CQlayg7j#-~p*K7Dc8UBH$w3K9u3lux-`F#ef~Dc7)q;J6pJ4p z>(u%Vz$RLH1LKJL!u=-l_Tt5TqPdu#9l!SYF&*^;Yc3AZEE+%D;|a@LK4BCZ>+oLV zu2bEK?PTsvEF;?qmRcX!js^#oPAVykwIkoB$4Tp`#vOWBk(0GxWr$)RYMGu(0>FG$kXKv4X%Sq}&(7^8|?`{<6GQ!9PSb z4rZ{;OfVTPdr=D9ad07ao9%ExInl_}`lO(tPc|ZbaoQ$eNf`Bg38T1|ussGWc*8E; z8f$9RyMP_8RgctA{uoPTkzMQ}Y*h|--$mZ4oLsug=NyriJ=loes%2SbYs-GEWE&MQ zCiop(4(S+X#E_2JxERuZgv9NN5 z+foj0h{gT$aufWE@t2ZS`&28VrZa{Bh$s%V`~uZdb&= z11^hxr+Oc6GzNXLG3bjE-9o~?0=|R=68Q>P%)+#!8wdEeL13Azd$mN z>ANE5UmRUhSDDA_pbt%75<nu^o#Ng1Fn@QiyyGcL3ZSa0kQvQiV@6h)tg) zHhq%V5=LT6SSVsg``SMowKFBXGJFD<~P*RF!`XqJflj^C2y#Ra( z6V&BGO~71v@z!Qwn8w(9@wy$q-&=Ef6j@m1iCJ^{KJo^c<}Sznts^qT9#na1HO2+Tp^^Cc06c(UA1XhNLe}tT#&-EQOkcag3EPj-r zom&>}TfFHugs$m|KP^pNci-LOIF1u?krvnX^Lwwjm@jG+KTe!4BxmI50AG$O;CLta zB&-g;Qow?b@fRU<0)Es4_*lQv?1-4wF9R5dJ@^9rwnR7pIkD$j^jv0U$1fH?CZZnG zq^H$ED~8qmST$ScVLV=SijuGbaKW7P+K&#a2jDzHUSrDbiQN$-;^16)fzO0kV*<+? z8fq3`lcvu--v=^uN?;f8;pb66aVMB&va(G_p#G2+lq9SUY0jrgG2(2v%(@ybmE?2a zmcX3@7dToCTrb>OxTGaoN-!o(xKhHwcX#z`+x`k2Zxb9o>*=bV91Hm3eqIcEt1tfmOYVWX1@UqvWtoN`}&x%zgH zS=#X{heNUXJjMEXnH2mK1o1vYJx%@;T+(>J-Lfa8r zTA?}2CgG<)Oy6pPZU^bhJln%%zWT7sRSn7X^hr|E7pL6@ED5_y`Anq5wnc2<-;RCh zTd=SGg{43DX*&K%xu0@MZ2S`&a7afOl9E`~h0yVUg(GAQ!be*O$vCW(9lr~Y!5{JX zcQ85|ojCrTcaMb8UP#j}kU!*X?nv}VTcnk!%!>;b?cgSge8e{(f~d71svWR8xa7}K z22tsgM5QlI?538mhZSC%h#HPh4~3|+QHazqL|q<~s0HN(ZKtQuCCpqJjG)yZARE-9 z2zrhp=tzU0^htu!7bnh0k+264Pr@vsx%Ib?a?416=l~4MY9H`nq&Q-RgkFsdgg{sg z7Xo3m5(p>YjUA)AHp=h?Bfblv6Y$d?tE47JkFpS-amYcGZTtPAK|fjr_cu1;s!mU3 zm@%FFOnVp?#5?rBn5v&OXys_;#jk$M9DS-H_#n6}!)fY$80ss<1bwmr=#v~RVdQ8D z6Ai#!^HMB{j`Km0V#Jk#&7Hxf4+T!uI{xL z=K;xK8N-wIE-D|RO@;45;X4z);qY~*8lpn$jnIYg^%9|fF+xc$8Taq-rHIgAZ1fI7 zi|}I@A8ze7FU7q9n03Hs9J0}7{CqL9)$x3)OY;yaFA*NmVa0$DiCpS%M^T! zV$ZQ~j{__NZW3HOTq+RRaGA3Mt{ZMH+?8-)GHT{9kF|_u(g;)XW>%64yJU0vB%9M0 zr+uhGJ82&)U!2(YD)D|ZVBLW&VaF+-67c@{ieXo=hm$hFSYZURnSh`ESS8A(2$*J( zD2&6Z4aM(=NLit}zNw}%%PXe-1@(2#N?b%A`UFqS#1zH~Eww+3gl35Yf(g?1 zfXg!WRPTkrlTAUNYzq41H`x;QI`AdTBJvFq+m1AeFGiNu{a9ua?`ac>>wHrh-6a+7 zy5Ehw@rs;X6?qfXdx1e-`XqVjlg26uW6zKHNWQm>}!N7V>>MM7i3u zv7x;X9q6Hui8kO%Uof`j-m4t^bO~oQXK~%hV_|E?AzRa$|4T@k>yy%hAM#sTFYevu zS0iL}7RQbsi^Oc?V;)+E_fbQuzDX?!fJ$6=tr?4kHa#9(mY1JygB+lTe3CWE`dpin ztWKY73;N>3RsjjygD4Uv+JgIIgj%9>5(>piL?e z?$B^$dS~Z(bWU!ixU;OcSz2Y`QLg@17i8%~Sce5td?UH^yPR!BU|u3)XHfDNmTL9lu!oj&RGdHCg07 zY|T7&PPeeWQ6CCuO(Jqqa4He8EY(yaWfgl}8h-l2IZ__3&btk##a0XxmoWQ@ZmOT@3j-(*$gvl^=oBKvhSfgMp@(>1@LD+vJoVfybw z!@+-%2jN#n%kFU%T;{tHF4^Ej)J&3%K1nwEr1eF@?oxPh+9{1VM!WiH3!X3A7m|;S6Z$Q%_+1M6qefX6{pQOmCR;7 zL(tYZR4bT*o4-rk<=%>FTZI?4Ft4XPJxUgU%d@C z%LuRy71QR`duu9z(0FcBIbA4MwF~&pl`OXxKE1%UQyOh!MMSyNI3pt?pg^jIzXn}* z+T%CBd(4!K_;X9*mcHG7{70vramxCvwVuYrMazq?x_imJ7u@~Xu=AoCo<1wtdBsQP z-!ptU-`EgbK{^_6J^7^f_&#ZcD`@ff7 z<17Bx8ADH;dE3p`|8V=#OQQ!oa^u8bCycwS*Wx{IMPKxn%!*_09ac5u8s{nT$(wW0f21bnZNBNL`l{>a%zE*Gj%T^vb8W18Gq+@IS$0y- zXFu3p^;C~{SDv7!_t&(|zS@N45AH0BdTq{{ukX0^`ihBX{^Im~c66Wm*z{LlTRh;~ zFSm62_%GwP{QBuTF{69ma7W*`MRRUlw!6!NFPz-@`Sj10-*fB@cRt`KoOsldep!E6 zTzN*jkp_g%U%v1EDk`XO(3dE~hpZz^wac8k9G$A>bnzU}xEZh2zIiYLYl zN}ToYU8jHPIqJZLSFdPnNZ!8cFOP5A=^1yU?U}^9f1LIDxLY@E{bpdF_=-1^KhADS zIX!LpS^Xb<*ERgdq({qA$8EiDS?Yit_TD+3e@|%WI(f>9XLseTtQ)oKf0lhQ?x@q= zcxzPpckQlu=ed#l&so?sXa4}(sSp0#<@2R$XU%;5kv`c=^z=4ekW{tnnXC8yQv2l1 zB|TkTo_e^?zc&xvwRGgzjn`c{`pcWf*dDQWZI}G(@dNLAa7JEy)YQ(oGqygR^2`T2 z6Vmo=9&_97G3oL9p1t*dHvP7@y5q7-AKv$A($^oxw!8L%ftUU5i-(K;{8ahb-~6_) z+joz5*z3x>PP_l|4+q@XX~T}WBf8zR@QoQc>5lB2Pi8(ocI9#B&CD)Y`HB0+q!*Ju zTr}*a5n~H)FaBiluIX1r&7L{_(Y5!z^>y+4-^NYYG2T06(cj1S9DL!^y<@tzFL>>; zV}?I;ZNb#j@6Jy8?!5hR`}<}NY)XB$-`Mjyce>>E)%l-2aKo&BG+*~)&N4Qx&QS`*A1`x<;UxKt(y14*!_KfJ=?zZg8gq6fBR$Qhp$d}_{05= zUHrg>`D>=1|J!ZX-SV|#XRn_-uZzB_!^(#F>1*Dqt*Gj{xZ9r+d;Rq7hXXP$ez;w~ zEwA1_a?^Q9PaiukzRw$<4)`^r$2V&?k9|1i%cZ@K|6-3bXKK#RpJbF@-~O+|{#o|L zswHQy?b*EL=(E@4WG>l#?ae<9EUYWs+GkDwZ{Oe0IMpD|?k2_rfJ5U5P28gbc03 zP13l-m~kLfw06;#>e0ivLo0brOd=PXFhq)2cXLQHKhA#^3^c#PJ|Sb363U^oU9>L{ zA?VvsE*~b=)-kX>e(j=9#b4(7%#MklNZ*LlE~g$~ddwxnoD8w{@UOyXuMy_GY$0tv zrpKID4B+jeC*d#Y^2sxUVD)3Jzb@Kja3o&wnDgp@_jb{=9Ww_$F~av|bkeu-UH@y& zi#lVw=q32e8ouT3d7aF)^2M9J)A6Ni&WkEeyJ(IIdS0=@x8l}5=UQT!XvkJ-7wyGg z)~n0QE3cHk`@EODt1fRDjw=!!RK<;-mU~@Rg+D zD}Vj}*n1E7Hj4Cpd@YB>B!R?`gb)IVU_zRWdu*jxvLxF|WXrK+$AH5|mSkH*wu~ev zF-HmYfY3wl9B@awH4uSjK|9kuSthD>i zGw-x_-g&3){52`QG-2(;e9FFZ^Z7IGqVNp*p+w?tt$y6@+xF^WNy5pdW zsMs`@HV?;vo^84WVNp+%uANy}-)^RDV%kevUNEoWYm#uDvHuGwItoO-@9cfFe)O_I zmT0zVBYu^1jb~4LPu%sj6knQj?ZSMKMUF^HrDIAE0zI8~++SDVPjhM0MUl@o5l{(h z7xrYTpGJ|_T-tO|&OzqkYfn5?T=?T09@dx{u5UG7@Td)oaxU9+8+?%|PuBz%))}w- zo+7Hbv|&;1Wt(UyooeNp!r84ntOHKCXsyNz9<^an2-&7NnsiNKVI8^Z8p>YHr44H` z=-H+c{8EH0ub*%kFRzhzZ8As~EeFgtL1fiDoXnmcnmF-%5H*)JtSO+Ula0^6_|1MA zFL>0Zi`GTy!Wj9Ja?o7buxOMb+cXWol&-cn&DA_zkDhsbs%F#FFDlz?)0_BJ zWMe9On)>YYvq98cJgi`tNYuy9HkIR-bkwwSo_U*x_4mRLDe{_2o36b<&o(`eUnQ)) z*wfs$=T~XG;87cv8Sf}%{8Fttc>aWI_|t~B>tGpcFKt-+z(F6DnT2&^o38zsFWNq*gq6p_8u|SF$EWzx=#A;j7Y2vf_LSlW z_QjwMNlErOA8ktUrAgQR%-0BnrRc-yEUd>ryX>wMUz)I}q0ctahSRxtI_rZUm-DdV z&m4VJiZ4xAGnuamsQzUFG=qh8?RRq&VG(p~9wHeCOHs}fU%J4>^YHx>KTg$bny_Xw zUs^ew#ll*-^PAM%XfAD7B!Sr`2Y!(>>7sdOpx7u6ulN_8!lAvi<&_VIY*Q(KWDU?Y zhlSNU<|nE?noAp20q9)jDTIb~yP>V4r`ijShLxkev|$|phins#z$jT(z@Dz&`^rbO ze)KY5$b6B0qib>h=@0X;_AS1a#71*z!zu!u+fhnbg)FS&PMMTiD>brF%zTmVrK`ce zx)FXa`&=Ph0|Qx zut@r{O*CtzlvgPW>kof8677Wc(uPGvnUsy=Ufc5po~{#*JUyWGqu29PKeA0UQKE!Z z&cgcc&_hXVG?zB43edAn`{9=)qO$z;8~M|bvkMNeQsAtl;No31K2 zWSd54!dl3}YMA#V^p^J0rppS4q#PdStLx-p?YPGUsWH@~%f@_ZWy8wC>bd!|xHcqx z9#%77zr`$DXO@1*$B<=H*51mrkAf3J=TI`VonZ=F-Xr8Xow14Zn)a z*RiLc9$HUP)?C`K7J;4&Yt38Nz0AY$fb7|A%0X^Gv1b{mVL<0+J{=2VtX}sW38&)IpMS7bq`4js^JgmRXyA7IA zduhX30*7qV7W^vZ)ySSEmfuDUHJ3K5CeX7@N>~p)vkMd?rR(LO~fyy=7)E_fuvJdMGG#chC_2{)3p?IZUc-Gh!z&s{O*wtYP{f48&)gx zMV1?d6?^htw2&0mmh#CYoSI7;)`6hw#~fN&Sf}k%a9<^bScFHzU>L`Sfmu*Hv zO;447`*0KfG?zB4gF(+W(dGjs4-aBbt8?NvYrNo58&(_hMYbiSYi-F*Xa*^)ycK(q zVWzpXVNs3EHfeQK8w;y(44s>jdL<1PGkDAR=6j&GUx0{07sNzd3_}xL3PDmS9h}t0 zDD=Faz_h3oY8CjUaHbT}b&!fVloPOiQNgSf6#C=wStls7RLu2)QlnDP)T7 zgTf7h4+Lc|m15$NK$MiQ_8vefA3*U8p!5mKB9+g@f>Nha9ubs0mGZHmOj9Yl@rYve zf)bx{L7A*l0)jGCr5r0LV^zxag5pytV}-DeP$^BS_$px?B`Bj+%+-RDqf-7ZD3er5 zmZ+AysFeK$Wr9la2uguUIa*LERLZS_Qm9fk3W`Og>^_o9&wQ2ACMe}9 z1t0RIk6{PnQ;T1^Mzs{x8S(i*@F8D%KAoWO{yXs*9k?IWBXfNA9YZKdB42twU7%!} zgu;?0cDD(ejnD(HHo=E{>G^~~$u=og!=G>SW_$Vd#MWpPaCAu@Rpq1t0RI=Mw=XsS^$hKM#8Ckj5~OV5Wa>tuY+e}3`hMtp7*e8`uc&njJfN`Le`XvF7f!H0b5`K;E(=c?ly z(Ur+uUSA77+IVHwixEOV8&>9iNrAzjK-q zp9cgV@}=ierwcr)s^k{yfwtC0 zTdVaTdTYiTUR-sJ)s8xlWWx;raOE2Vu(+r@+JoimV)eS5T*;0V(V90rhr4@axiR8T z$h2SAL5qjHp?DmtRHZ8QXih8QVY4l^+3G1?%2sKj$_+#kY-De5Xcad7MsRI7we*(in}A4!NKm22v&SyZ9_B>?&z=S z>j?<2RgTcg`gkWrxD{D>5M^$m-O=7z)16@SB{rK?aj4cgR69X$Wge7$pjPV=o6}k^ z@`CLMwQAg|u}qbDkYy+P$R7VZ91C1W7a!kK9pn}#25{hA)jhwJrc~N3Jv9*J~&{b4! zwJt_^`otT)+!ePL36!#vdr&AA2Cu{-XC^tmDF1AY)>AFZHGvxVc`z-szLsKGRVd=4 z{ggZ}0hXDinVfC57U5*I+NxQwRn_Ui)y{fe!dRD&<6YvRMs|#bRe5c~%IA18%;at* zYgL}IoLRHU$*KgbkMaO^)lQpDS0Z>VVHsXk__G*8Iw?KMmpH7-hcvLsG)*L0dD^v$ zuLqz6M^u`oCfdEgaw#3kR^3v_g{G=>5G)D^P>qM8K|HWTRh1Z_?5gqO!7L-&+CX=^Y)Rko$2aXObPLg#W(HK)=Q;VP#C z4#tGl2KdpOb~IEkXaV?%RfBopI+CmW!)JUF_mEX9=qJe4A>W5;k@o{X&pdl?SRcee6p9g@f z6;m6ERz@KUHCk*fDq?Mz5+}voFa)m+%+dsb#93kJgaUooqS7y8Yf4~+9Ee6&ghSR+ zw3GUsjn=9n*ii=CCau;=YpJ~0M&_2?Di;a}vp{lZ^4p$RfTIZ^+t!b>Y(ncqhT5Y%1 z)K}NK7uy@HeDhOPnX>x{Sy!F}I<59a4bDXlx5p~>L{*j1rl_j2stP77_$#a`OL|yj zt!Z%9);Sk7Sd|S^Rb`22RT;KSX+4!ido!3F!BJP^bk$ke z1}nW=joohZ*czNxw&_aeR#|PYt*xtru`V`Z>0GOw*1Foo)h?IEVU3B#9q}Xir$0x7 zHnNl+4awp3*j*MrU#Hz~JE-^LVJyuV3eNBVA z-ey&He6fvVDxlF?)96~*45P2*SR2+ikr+frl|<j4+L18NXqsuJ#-clX zc(|w2Y{!lq?8=OpTS77F{+f#_3yR7Misu%V6crRnqYtPkGHb7*GPsn?Ei0_hQqAU~ z!ou?MaWZlYfGy;__ey@Q(5tuIoE>rww1Gn#OSl)}9 zE~EIh0yE=wj#K$*CS=KlMD!qm;YiBoLaTPdmFVLYN6r5lsc^k^keHlEK9&vSw_ZEI zOE{Vw^$)~ZQ*oH5kS-Ylj>5ew9ZoYa2nd__y%)F*0!!s#m5^S|FdyL_!~Jp!KU!}G z?Qj5WEVrws-sP>g`RsL;X)?l)y*`J_BfGpFd8y0cl+gm&T{SLelXpSkH1h!tXN|4d z?Q^@TEz=_5_CRlUBA7~tqrKkeNI`qt4zycNFUU@Z%V%qF*ge?S+|cY~;X3!?3Z zN)~B;Zq`1ufO=Py|M}r8^?y*cE8Ul~AU7+pD!7dik^&LQZfR?bMLTf>s<{TLJZ_$` zx}tn$TQcmHaJR9*7T5&HPaZfA?rod#C#waYEeCY?)twcQIwc29ky%S~>OHGkAr1L5)Uau2k z(a~$^@W&Gn%z$N8pvxbV`Ey4!<_$!9!K${&oR5c|?q0B{iEdkr+qm)rgW%6%pvw+f zWJf`7upRM4;(VwytAeE^Mdj?jtP(X0@1q~%yDINIj*7v?*1Ns zr2p^`B^q@v6pKY;G_Vj$SbAeHe34DHt5~*$dm`Z;WRz>#FQrYxJ%LDHFf{F#48xy@ zbaw>WwrfzfzSZGK*dIen;T;O+rRbGLSH;bXF_F?%RM_U?>BeJ0VL?%0aVh@W`U0`U z_Q?rd^qSG4`EVTCu;W=#P^3n*uiGeQy5woS#Zm7_a#Dc?6uCz?FvPD zLoqECt1xpRpR^h?7xT5)nGK(H{SLk#EM{5 z<>fYsAsRL<#lEWfD%KA8rBS*2!ss^P_y~J*B7(uXXsmxeo|>wCu~4WX8pIgw{Jx%e zxU&bx`Cuw=j`|Ysf+|>;`i=u{8=&T04jJR2&Q@s;1hI4q8I8R4qc%jbEpfcps9drr zN31C+DbY_2Su8e}7fo;tnnAQW7~eWj1AppCjC*L4q=DO71-u;G=_oamge@GYw{WP2CQ~TwxPj6qup%wmRfoCMNXUuSD$#GA zmDXnge2$n%S(71t?JzCp6sqx3@L7iVA{AegHfAZ=hVgcsFr^UF#&Zhz%tM!Oq*T+? z?DaL*%MH!-jc$w@dLgc(axa}hJw$Xv+zz?M?Xmf=*_cyJg6j3*%%obCoGr*LumLFjPJ}DlQ(kr>UeE^^5x$tI*vxueZ^c^stj~aMq!(^Ylpg4*cux_ndvM9Oy+?&F0!*^lV{a8J1^(Y{zs!Y+bX??IIyLr*##@FCP;CdvL@ zeO)GV$IPk&L^P#hTP(cxr_xj3Q|p70*}ICE!VYU-ol7;3CI}bIJYb)^lGPIhwWhhj zPI;u3%_QN_f{t*Lt5w=Z5b&r>4g1^g%nrsAq*W3*%lU34;tvWr)8MHHqpYeX|<}_Ysx%vrvzQ*pL{>+hB5K zM$i)xG`_mQ)d^Y=^pbovZdlFOP4?1CF8KZZaICMmM1uk<}Hov?Z#>;8KX5gTuScg>y~>HvAA?BP$yCQ zrE4csjR!^X=*m7-s6|s=8;kb!&f$iIs(*x?p-}a$FKHWU<43@P*}B!|gVj;vYJjQ1 z1o*?5tQ-&YqRUQl;>Aca$7gJF)qJM*KH2tCJ4c0bw8WMJl@zy!{ba0h>NrlNwMn3o z5OAx8j{ocSuNEtaXmylyBpkO-rYSSeq3l7g(3EepF$@8sbZv(W$JJcO^@_fmpbg z2as0R`~_UM)#_Lo4F}CLWSPEmfx~YjW+iYXoyxlsnOQSuke`_Yn}}^SQO4%ZVTL!U z2hCay?4cc-dk!1oPI1vq4Z=bgz(7nPO4A2&NH@EP4?X<48K~r`){L0G-Ews0&{N~> z?{1GqeE#-G$YQZ4TP0TyPHjys;neq3V>3gOhc-wTOfnP3(NoXNv!gLHOM?wH7_1k=1UB!14R#sadC%u6wr$Mop%Daj zaxe7`Ujsw*4izfq!N?sSDExKHY{(|epar!3YTnUOPVOGX*iVpo_+}^;m|c-KMduE+ zO_bIm0{i?2BLJ0v_33_mlt514Ycx5z?-c#)+)y%OaC=lb0wI3%Ylf&x?+S!|)6WlG zu`CR&ADoevlY9HG6qqiR4G6g3IAC4XRBd=+7^S>R2Z7(w+mD|vuDgKuJq7epy57D- z2ey+yDoe9+a$O=kKCn9f7paqTwi{Rb;!wXEdvG|%^rOPtEihrk>8x1uLdk|)EB#-t z4X1-*#@H|ArXBO^qz+BU!tV=*qz=_OLjB%tvCtKrDGbd2R}30yXXJroT-g;#{{L$p z=oAzw(+3opz<{t$bEXvH5Uc_m9F&v$#P;KdK7r6Z80gK(om7g6BU*2R=@eRRiG|we zrPJoUc7I?62H100f32oR!3dWY^cPV9K7;#NO5}{y*v~F}ql{GYl^GPjpmiwyfCQia ze<;B^(WbVSCZjsSp-3>n_LoS%0qx*z$Pis=s0w0u_W#PL>uUUFB;#n2jA7Jx!=B)f zD*FHq+pC@rV4R_f?|>?P=>Nr(>uvvAAOPk1Y%plk=FnOb8k7$NLxBhe+_hM-L}2=y zbi|oP`djNEbu2ga9bLW$5a)gVyW*_R^eQA^BYOWzk3yGzrJ+)W;I%`#qH&d6VDQ<` zV4yLdCxg|!U`2*dFcc5agbr+HSjCT`hTI|oNzo1eS#7K;m|ra#!%hu3zQifb*S3=ar{7=+`fu~HVrdZWKZ;C%%5BL9|sHL== zPD6$js$AGrZyWf<(wg$Deih1EHE8tX0lot05Zwi7q<720KRK2#b0e9B#wNqa2sz zCZEqmq1b67BR}P$7qin?l$?|MQa;!^aEx8Izqf`)DZSytLyl0eFA$2&FD_dsO#$dR zQr=M8ng}C33#FaNjTkhAI_iB`X_S*Y66^5tWQs~Mpgb90*o^tB`>~xwE-uBF>vM81 zCzhO_Z+;5z6w3i-vGc4*)7)8CPWT8|KU)AH02iVaPOUOt(4t0}P`f&yw zvQ`eq<(_B)M?&CB_o1FZXg>OyAmeBleE(eTjUtISM8Q0ZcQ$$XT#Usa0c_5r#X@wH z9Tu=6v#HVZ?Scf^`vVcobzw^&E9x~9&=C6E*u{xO_IB(<^kRPjtt6*WtcMYO5i>+7 z5{|PNC1ay)!IUVhgugo|*|fGIb?yANsOQv{G5t`LvA#M5;BA#yElv5C-ny{UvEg(>5t3%cfw4yrGO4G9O?QlCdFE!K{!9 zqgJN4aG`V~;ypuD$nDZ*YYl_#ZL&*uAhsp{EwN3p54_kU)f5WBGVu2V`f&nQ81wEi zZ1T*>ErPk}^5WFsP^`IUMNf294>Mj%(Z0)acTsT#KFiH5bsU>@IJOvLk8)1#NhJ`= zXb&u37`PG{1RG$5)2S@j>D(o(?0a=2?A=h@$p{99R)lPe!2{UZ342uNDhqg>0Aw9#5y^k?2Af zFo<49GQ7FKJ~}iklBf7bAS4VM(s}fEcE&=T=o6xolMIJS^u8g()to#4-tI}~jf-3? z6bOY;E0f_+dTt(u2Q{Sq;qg!DJa$Ke=+`7epeS841fa^f1Rm%s=+w^@n-}M+&!knt zfe`D)7tP^aVKj2AarhlV$=JIts^EP}8+wU$A1fGdZ@8yvsXK~=WO)eFna;&xA$K~U zUMQeT4Fg%oR;^LDCUscBjV@=sKfVHNr~~`co`^p`DE9WWc@163^9xrS0Ft06R46J1)O zs`Wl11QVqqW~0-prL!EEFJzEBAEtz|BaHC50_<$d$vq7vXlLycC7;rs z@Fl&H3^55hf3h|lTVEpD*ca;z@s*;p7UF;c6e=2jQH$zvZpmsURxd!NgR3xR7K=iL zA}lj407s}i#Tbf_IhC@)Lvq0Hs%`VDu~o>BxB|jb?&Im{|CMMvH$8A)Pm&$!P%YI=v2Z_HY$MquNiP zc_g!wbMPjh1=#6%IPnsr+Nd%{3OB>RD|TGKb4^~duBs!$h}3|t4~<<8=;KL?!J=GK zWrxo~Q*&uC%=e-M2K42WOjK6Wq>T?RUle8$Se>fVYeJpzAvoTuGTp?thoXLv-ngGM zT2h%U1<8j_v8HTO`^PEKGS(vtm1RExFy06A2iu#mZb=}S9oJK%;KupI2_N?I^U317 zcuPtHy(Cj?l$ToAn^Ni6)R~-LVK#whFq@#Lk~P-PQ?R_V*k9Y{j|G|UN04IUPJa>3 zBFM?@M1M``uF?7QyrV_)F4QdME8@lq(Xd&hmWz%rp>GZ~g%a$eHmu2e2)06U55d5F z24w#{KWJSQR0c1&-{eK;=<2ahFKQBF#wq8jtVv5BdjKDfZ72O=f4V`hqlJ&ufge&!enUNv@f zps&R;V250BLI)jHGM^ow!OgzEK^EAF6z%??OmjmLSx!GFR2h>@J#s9O2#e!NnDZVw zZjmUC?hZzAYHEmg337GLiVNjVr{Y4Pg%oR$MgB&`NhQ;%D9rMlKfsBRk5I_O3@fbh zQ3Nx>I7>&4#b7q!%LFn8B03XYO#c6&AbM~-Uq~Af8f<~6@EpMeS;*gwlROyPX^JP7 zgDlH>`XUj;QHGsImhjt3rcr#TCms&6cxGn_hAN(A;;E2-#)j0Sj8PvPXTp@|Lgs6g z;>@FglYyC`n49cW;mcN-siPUr_h9Iz`K%I))jbdj7n^k=nWzaR0$ohPvZ%w9anQ27 zl=?r^G`4$6a!flDvf0& zlF4L6b~gpYdzlss|EHb?Y6}%vB#FlGQN-UFXGxDyt%p$#+gY*C8J(uIl__U7nguqb z%pb%w9N@gWSn6P`_XZCh9@mn9(!}$f6dy;1iRYq9`pUJK!Ol2;O$GP)be@0Wpg^(< za4%#XsCSFuMjH<$S_Rv>?VTiEDZ9mxn`S5ulioXlH8hq)2i72I6sHeKi!{?G#ApCA zNK!-Ng%S-T++tAPN=vQX;8|hYi(`DmX884ekb6JNC4?z@fUI^$S_2`926&fP}cDSdO!BA|)i&G%C$Xw3*ZpRU}$cU5l@# z;OK!+kPZJvBTA!s8L9%z3D$jAMxGH*D(v4=oM<@--boegM0FlzM%`>@PXL>D8F>og zVQ)lYaSU-cJDG?z@E;>G*bb@ecBDZKTOfdq+NgEZz*DAhiEz>OM;fh|1ihRpHHzpf z9TK7W(sy>bT75m;IvQwQrkkrMQ!?u2l48=5R7hW-M}ySF!mCSGmm+>LXiw>DTT0aQ z6WN-|mugw107)w$P|D$}gxSw41`WfplKu*{Os;Ro;*vy&Qznzjg65_5C<&%`$55i( zehhx7%W+s66Q*jdj82LX$p$p8O!fcKjKUY|Cd57}VS>?;qcUW{l0F(E>A_kfTZA2~ z%9b3xPm&-8CSi(u*lBC5R6hVmm#w##_x70du4ZBgac>BPJGu3=SYuRtcDxv`^muzH-Fk7q+Ql%tFSqQ>3?|MjM z(rOlIMb?od9)mbD<-}I)u<=!gj)Z2BB$b~^=TA_ENYvymGHh~-%gU)-sTtUW;)(>r zD-j@>=iP%Xg(|CL5qk-dPSzkM3d>QPLEbik8EK9+O7_~LF;sCSljBT^+o<%DYL;=$ zr=dHlj%?sgIvzakHts00u3qY*q7>;L-b8BZh8pQi#9}c;78xyC>{Lzg%f~{e`|A*+ z>@*6ANy=~zhGM!@qpX?uJCRmiF5L7ZLzNF#UX0>N*1FOP*6Eu^iop@;@b^U$IQ*J4 zE&l>4c)*ZmnBT%irY;H_XIAGl*c)3bNFBaS`hrd=!$C)TnEZ^zKpeN@ii7O@*__-T zllq_rx`p=vsb4lTX+4VB3+fr7aQu1O+lIO%m0{KwT)IgWmc9;ZjHw^XM$;K7P9*A@6FJ6KOs;{9HBf6E zLAH=4yB~tCs8zNYv<~y*^yPtm&9n<;`2OkIR?>95Yk@4n;rq+S}1kufOO?5)!30{<8^P!E~o;Yr_B*`=AaVQ=>#U;bfOZoIX*#nWUKMk#~tnL zL?>OeXk@ajgP|T*)@G84V~2(%BZW*R3Y?4*T9I2+&hqJd*31gcO)@!wVw0(Ff>}Ef zu|HF9fb^>`2HOdzN9N>KlHCt$5DkZ)P2BScHe%r^B%yDDF0Z~brUKF`=~eT(!)ZAIZTz1N&J$*8p-0htk*G0Cm`&!B3&;d z+4`{q^)wC408O3(6^0oJ^0&xFu}Y*Nl)#4zSCFP)=FM?rCE0p9F(@RAbJ7K`D?-3E z1k?H17y_e$w)^o_PgQeJ)t>?N?nUr4RAWIEWbqzPOkh+{`G`cgDF%M*Yg`4LKBXJ)UMb z!AB`rC|wH{mlKO&8V1|4=9&C#^KpdIZHVbL{|zzKnK`ti=s9Y>g?-OkrsPO2Nyha$ zlLSo$sY>*Pn5rx<=TksyFnD-X7`eIwKJHQ``3!G_9(w=??d-h-<$iA!ezm&fH9E z9+JH)YEWK8AXj&QZYz9Y*1%pm(q#~cpocwl- zv~s2J+5jJP5;cyMCU&o8a7@pR76dR0h3S}#_6ezD-ga@HiT^vBppEF+<& zBZdiBg5@--F&-!rSW(U8<_eAKRYJPhDW_!d1=Cr4G@Q)VY4qvp1X(>PgOGeT#Tdi{ zr@OPWu~-NDVy(f+C$U0&7{QHE4YKE`(7%Q~mO6OB!cdn}v4Q)L#>hc+>S6ZCm1J`z z?JC9AQU_GJ`FM(`w@UR)E{+tr(8GcOEeNq2kbk!W9Cs>|qqmbrkDp({};PyMe{ z_=lU)D(&qk8AIJBqhDr2O?nSC#MGnl_O&ZrDOM35QATUoXb{s4q(;PNc4(lZ7s?|+ zEsrzBOrdS5RVk&cpTfv|Qo_&IBI{F_D*3mC6mO{WaZqIy4+laB5)`NfXU^JOTU8E2?1sIHrU?eughF2;L@eHXJcevp$cBgD=NIdJI+v%fvoiEK$?jh+It``n@d*M)u5E4 ztNMD`z}0vx$Wk0qf~8k=NSvj2AM*gPnk{0|k+upg7#Ms^EM>(wqcZ-_S8ElO%d5hP zE;c)hDQKO<^B{FHCTgpU| zRE${dHBeAfU>1vJQ8HT|{NzB%7~n@KC2xr4EAWOXG8W)ZsH2Lb5UT;6m01=#OM{m1 zE;R@+-9jwln`UV-^~rWkmo4}VwU9zKXhtUh%jyxp^pP&C>Q?7Jlo@wg07suN;VGom zRag@#dVX8LA!EaWwNm7Fqs~rcGgPc1e@lMRBg{Bl&ZM%2MzT{;7|aianDer<&U7HZ zGy`ETN$Z>(XlDz5*lO;tDK8B6-egz`t|)vO$=HCNc}=V@p1^0{64EW8oTxV>b)8-H zg)f#$JylY5hPn^~Hq(6;Jaq`sp|NOs#{|6Os`cbI5om>Ns5SC(GM zDy0D@6bTurGuSLsH;mM~@Kzz@L(?bHiKAxmLb^3#tjnYKFqCgW=zXL}V`{OazN45P zM$D)DH^y9FSTwpmj;5Z-{$TbAt@dJr!FHND$K1JQ1uvhPqau8)m<%C)6T6s&( zE3g6jh=xvfmGbQy77*q^S%;Zq1s{Z_l`%A8>83fXS}c6ygOO||4Vq6gKgxE%9<8TY zEI5asEsTpd;)~Kze^88#QDm(MVP%Lm-H|YEB%O!lP+lLK;N1d~lg}(;p#@F!-D>7@ zbZk{`Q|PchEMtaOGEdI{Hn}hZ@=HYe+>;kWeL*(32P83}wM~6Jq1CDQqW=IPl>?b;%rAp)?&G5wp?sPRoj9@m`Ae6ZDG&l%_^BetIK~ zFNUQ&UxGXj#QWI6QAj`oNJ}Y}G>V@7I|Rc~YU~R(Pi{YcNg+dADf+W%I96Sy#@eJ~ z^=m}g&_CZR!)&`95gT#|A3Aaby4eU+gee>X zU1J2I;dM$JeV(iyn|g#i)51CWLOHKWFj~}|Atc*0Y%hnS?R_0=@d`~Yp_%Gs9T=)u z30jYUT%*M-s6fihlWJe9(@#|G=;LNgurN6iXv-sJHBQE~^Cw~rnd~1n> z?@1H>hKUDk-dMHYy0>2aVbZ)~zk5WIUSf3XA^y-lAJ*=*@pnI6d_?6gf5C^|5Wx7X z@g;v)P~I~#@bW`Rwi~C=`{K+Su+3A@LXEsXGKNvmF{?FZCd-#O6bH3T>rqA|tyCrGAY~r82 z?DQ{>YMef5=ar2g?z(Ei6_Ru$qkHbWw&9Jfe{_9z{dpIRzG1&hCFyBKFRIMHxjwM# z%adolblCMHzeKrNFnT#YYrkc8n69wB+K7%ah-KYNzgm0LtB$L$`Zn(@+%cfTx$;4sqXQB=P_7oJ}`AT6y?G z_nv)uR^f}gZImQ8qu+nw=JW2l@YQRdZoT2~JC7{gS&~j<^t?BAx}tmHd+SyP-cGzS z?q%rS^^E?^icdZ^fBKuC^|IY}nDObO&!T)8-LYGL^>a^Mw#x~B-0-)5ztM&KSq#}7 zpEb7PLtk)xk^9x2)z?4q+q7?diyiC9RA&+ z%N|{R$nJ9=YyIvCNh-=AK5v}&(T{zzZhQ8X2R_>Hdb_t;lKhMw{qWg$Uhg{T$~|%) zc;byie*d;4{h87CImb7C;$=syF1zo(dwzUt^3{^`38Nocbbs+fQ={*%&R%z6P3|!- zO443C692P5-+cR@4}GxOvff@b)$+*=sOOBn_(4zXZ&&rdxp&!TZ(VZ4;(H|NB1YeM zUTM+N{^_sWv-{W=|2posc1apJn)t}$4!XSbo67G@7q{PVX3N2-7nO{@=Yvz0A3d%4 zhr`Ry3_ljmzX@{4=sElTbobF$we7s`lg_^JPgGthNp~{(F1622Dt&yDV*gyW{Z_8>{xueh|hcqrWTf z|L9@M8gmZ6dda%A?`;lB(!Ut}%;Lq@^9Eo3u3En7y(w4_!{}Ydj{j!gm(JOJX8*f?%g#C&_3Ly--+bJf1=;n7mR$eTF{hs~ zDjW6m2}VEr1n=g1c0cvZ!aL+E$E;ZJoFq-yiTIB=<;&Hmwz z!w+lObkB$vBeBON=>|qW{guXD8_qxc{Zpd5R^(rQ50v??xx{DRCr`R>&vTYM__Tbi zedJp`^^$Zjqi=8@Rr%>WOT#y}?z7kW+|kz}9~k}Eqx-9u?>y(wF{l$? zFuG~h^|2>{fq9Gm8lHOVAHF_WlBVxM{GI2W_u5-0Uj1;z+$XOax$}K!l$JC4jSYdy z3&I-@*!{Np6P*?Ah$LOg=nq`cJMDs(7azaV-G$$8-F?d~lJqX4&ppca^{elGxA5BC zZ~N?-X_q71LZo?o)+0Io)jLkvu;kXYBjlCmS2jt~`HX(v`n}%YxPFf_m+!f*tfJzh z&64yLszCWf`~)m*y|HK~hThB_SU46p&sbeiKC^8VwxUE=#my_QoT9C$ur1sZi1YDa!-@PDHeANr_%hb~-bf!7 z?DgS27HH$^bJ`ME0b1AwkHPlNXb(L8?8vay55tH-C;9=*X4xKrD><<$5XEkWVZ;Ix ze^@f7jAG$gWzig}2Fz^8!NE3<-#{=#E83ta-&Y=ncGAo_{|DRp<=t;6%|JjVx za@_758ABNL+*j^nYYw4kWGpm=U!afw>{6Kp*Q+v_^yO5PstCB-rv34&TEYQvy( zU_~6mY~8`KVR)wXf7pmU3?HP05F8fP_=h9sVOk(ghxgK6@L>kWlpb~nMFT_e7!%{U zF^mMq+hRE27p2`6i;*B9&hdgkZ|~2qJ^?D+p+rZcyo=iU5|KDto3JfDq4}e+;pQC+ zGuDnxDZ_~^_Stns!tHJ1e<-odknPG84`o-JPr+cMX($Xu#wk(3h!LjF;4y>3+HSQL z2T*gFN$%MnMs#`gKsgVuR)qt+I%P=Q@a>CL!)#Jn?d(aeq#s6-v4#|dGaL^X+~h-W z!|;?MUpl!0n+zGZ-K1i5H#SDnMwMYiIW9J~48w~e?Pz9tk>WT8D^|AYnW>%)mZuUl1R-Y?YbI9WLLsWrnVX<=?0_S!|=!j z3R;bSq5?iMq;u#(5${Kj6R?2By8YA#8MbF^d`Zw&WPeh%55tqH(T5!z_o?>z0x>ebes=9;3!}FOBQ-r4qO{$FFdU6{tP1}8lq=O; z?PBHm3e9<;_FnS>{DphX^j>P7Z9aq%Kqmr!iSw5VxGpf8^NQgSZgY#x`3wL`38$1N zDW!~3Q791M;L=^G+PsJ*YV zP3IuwDA1dF{u?eO%{lS$cB)mbK0;UyU2@%=v0ut|Xqv;@LW4ZT*(_5eI49 z9qUh6KkkG-;Stj;m`Gc1YV4wiLrq(0Tvnn=8&R@8;nolm`x^NlcgJHVJf6sU5}tNTA4E5KVNZ+jYhh0qP?uWS(^CA_vZrPEoyVRiV%)VGPn^q2JaH~Z z;He7tNNFv8=d!0u@VkILU5j7t_m6nue(%5&_j@m%7UCW${atl^MRk1xPgn^ESCX1d zxbtu;7baVzI@~#e@aO~yi=@UfEJ<-*mV`t7YcX$;yvPqp8o7U`x@5Jm5sPAn#iBgn zgp6Ir6L%|a3W0p_%Y5uESpPC6cMI}*G$bO?6^_GsOfJE!xLes9d7!rgu@N_04T{97 z0ynOm;bk*;&`FgstSvPmojXgFxfCj0b3mu}gZV3)38DAH#e1=E$0Q89O2qp`Dew1) z_fp~hFY#W6ca!AF{SxmYO3a1w=uKoe<@p>&k)&rNX$>U^rL<;0{6CBTPx1eppj+`g zij^}xjgi{$OHZSvr^M43@*`*;tF+Hm+7^{YOBt+q8!e3$Ph&6xq|m0SG_y*ZqtXgh z+I*E}RcUUO)~M2gDy>VUF@0f$zE}cPf%$UGDviq>k*9yVo9OS;53g+xVWLo?Ix`Zo zqdZN=lbg|IH zq2iyyd=rsERv{()S|?-xliNZD=!we!J&nfhek_S%w7bO9XepV;Y;MpdFB+D#;IJ42i`v$&9JN z62S!4*ToIwhcu+35O3NAJLQEmv5Y7LKjoq@?m`92#($n5LanT!a6c0n0u`}_;y@~j zXAC{@jG?E|($&Is3=X{DI3ZpRRN>Q{IgPBA9=Bn{+MHwF0=J`&`Hp@QJ3i{XmjwBv zQFy?=bc*v{O1!*sb`IQ1c7A|#Xlv_oxD}*iC;6dd5!Yvv+3AYcP(2N?+$5e> z+{BlX%r9+jT0!EuNi|cOmBc?aD{;ar%gPb>r*L<`Kk==^&9jo8cvjNWXz2?4a@y76 zNn~ZxdLk{z^`Vlj+%}oMws{M=RgYk`Iq3*~0fdWsT z=`vjEa4T18b02}j+>}fwKa}8B+&?8VU1{X89x~1juVT4R%&oX{aO-nlY3)ZTt-aE0 zY72nEdJ`q5mF1Zt!)M{2;xJph+wjZ_fSz~((9>vq*NPi#W28TeCygwBHSQp1&T${- zd`Yd5$l#n;mfib`Dz`AR@sXfRSx9XV$r#BOU8!<=2xzlYvXK0c+~(m9B(t!?-yZK6 zL}+)?*hF%x&;hA(OZ+EeZJ0LO&N6YiJsbZN?mGNaiBRjqvyGm3w$T%pTTZ)L;6_XP z#mQ_L@>p@2K}Z|>wkej1n&~+5P|#u)@-kzlv~}yzM}xb1kv`^jDz$VYrAMC4d&ydL z>;6C8zTDZ|}T!G{^GvGn)>b znY+*zn_K(l5C48)WaZSql-%QvZ#wDC4^F;w{;a(AcjWTVUTrHLJ?W?!r~UE0KR2GS z&UfEEP13?ulMi2R_pW;*^yS)yt|R~Yy9Y)eefp8veXs3xV$SAQ4!`W>{sSyk7dLNu z<9H>a`JQvzHXZopUoO7wz)xR#_%{36J#LrtH-GiO^16KwIkxJj`8PH9Zo2ZAF^4O7 zE6r~dgoEdYcgWhhmCDK5f$!xO6c(NZVdj*AAXds?W{LbzEzdTcs(3f}F9=eQqms;In-Y3J+P4CHyCjj<-9wHeaA%vy%AJ6_Dr5j6$}#%f(>6JnH1`@bDnvdhxPZu z4{?lz_R@xhC64g*Jbozzx<<06xoyv{;_u3@HZ01yY||Y4QZf#nKj9kwwBhYKousOH z$a0?Qwmz&J7S@rG+pdF?=F;XN79YZwlJJQyUEtzjy?^4z<27FJs7==x=1ZHd(JZW$ zJHNS8iZ4xhQO(abRpFOp>xl>MdXa~c9QwC73A3%9%0OcJ)8KH*$gP`oJQYK|_QVuAj z7m(M2GLlgWVzhvUV_=dZ4>=0s4}Utx!gHRxrvBCnKIF?J6|`e_p14TG@0oCEG;(FuEQ;vtg+bpDlt9`Qoxs#{ZaaJ!i65k|{lD-Wp_x2F!dUf2xEN z`2rstyp-2!ZzlK2xU)@^n|j~nzPI!Q0!to2W4;(A4hrQrrxXObR>ZMQiLTvoXPX{l z&&EF&fQKxHyL)B15z{-eEAHxHgOgsY51?(bRci0aYCX_qvn{sS>a7P!RZ1^_sB#05 z1RI$SE27iEb%c7b!>8L+nsaqH;pwS?d`Gy+qPTdwqJ5EIb3D`#TE$%)7!ineD(;SG z1_wK)jJXGH`7}harJtWkSyff2*w0q$5}VUnFOtA4X{*Mq+9@}*B6U@=jI&EI_P~41 zl*m>cU5rU+9PC!Pu-LKKzS!kza9FGI>@{(#RHb85(vl3STDYlmNb@A9wNdlPei&if$G&|k~5lSnmzn`qL?)^+xfR!V&;|*zR(Igx2RIAjVviD zD3T5+Dx7Q9Tt#Jb3rkAomK9cLhkkDOUG|t(C-4~p8^MOQaXN9;qVSHS?_Xwl+Bs=l>pNsa7O%=19QZCgY)|n zFwY8HCVms(@K0bqd*7HJwSW73z%j~iy7ZdCuM{}nhsOL$;Cv!5cMIGIyr<(wK7bGtz)|M=4B%+bik)?;y7yA(#Z?)Gk=4yzcuDJ0sLH>G1e{2u}u6TV6$|KBt3+i zE=otb`1!zZ6EH3b5fHd^@gsh}0p>joE*(EJ`0bvRB~^|v=0~>d3SjOKI6|l6mj{RS zz-+`o8eN&n!wk1cBRPg}bfx2G2BaLgmQjQAJ4s+TxAgobgUz+Tt)qu?)Hc}xTSF9Kr}zvW=_FW?r?#15`Z`A7Vs0>gm#Ntb_A-_8Q= zgPn}|ksZ3n&KzUJkBYwtxUzA^{76-G0@Fy-Qn<)oP8Ywc;XExjOL}CNBraY4(OAR< zyJkselfuL`0e3onH2QGR#4PC>(b=JJ)A5@Q`eVCgNuT1TD^vMW7Mmb6JMYeMs4i*w z?E(56U}^=9(COkw{FVT-Y|7yLegn*T0+)#&REu;4Fc<7GIKMl9c~;;u@p}vo{{-f$ zJvqNj@<-`?0hrGPE)&1I;P5>#x9n}qkIG{sFr&>Jm#I9)qX6~-reNQ}`7H2}%2Xa?A3Q2B42Yj}{HS?;6}U%c8S_JDTG}iyM*Jwf(=ldmnPbckrl}MW7$bhm z!RBh#`dbah8O3iwU6wS##c`S9N8>!#1M~aE9G5A6|3LayyR)Rl^&Ced zX6e%VB%D72=1z|>KWfiUZsZs|vMU`w(g&9Vw{{7~W~y)d19zXmaBk`2hb)mc0yoFY z`DN07iO^+-89pjNgKm zEGd6!I(~eHgZxu^Wnj(~xJ>=6=YhKqn6pSR;L?{zlHVM-Jp{~W0+%WOh+p=BS<*|m z>C*G#vpqzg2In0Q%93Uu%yA??>EvZO0vgqpC3POcahc@#S@^HSaPH{k9G6L+zlQVm zz+BcoIKSRNmShVW^Lro8ZvpdohcQ1J;&*Xpmh>8Ky687udTIRNU0_UMj?0vPWDk`B z;}N(_{338T5SWJ#HRiV`_sP!up&#!BgVKg#jhW3Eds-U_({hPLnYEP zz}?zy%#YIh4qpD{l-m~;YjtH2RDU3#f{-v`XZRh(ZYeL4gF4+iEq zfy=~i1nTc;z?{|3`DKz9;`b0R9|@chzfHh=_nX1_%|0Sa^5Ui|6F;iI%YbnnH8{Uj zz+5hHM*OY=<}4~0T$$4QBHSJV=E7q*E|b10ME+GCnu@c=5v9|)P7We&4^R8 zr1_^A^E(jEJ-|GAI>%)iU;7vV{qYRs^VuAiDgPEBek;~xNw?#sD^vf-3g>?Sv+KDW zmnpr(&k4*K0+)#&rT34(ymOv0Khl4@ou4HYm(a9pPH?Ls)~ftm69BraY2s0lm>m`DDQ z#HEYhNH}i>=BH~pE|Wa}8O|H8%aYEyf#WjCGs#QGjU0nVcBP9SnXtzI_rf1JHdA_u z->5$g&aV!TX}}$NlQF-?!0!@Zf|MX!nablaIDZe!gST*8rt}^O9_QSeCFS16aXENT zm)eGG>mf%$+02bWR)?eTb)REV3dO#G;Qvj8*t zZ^ry+yly@)A%TPVq>Y~&Z2EzD_{qWfeG82FDUQp;&kE;KU=mLo^E&|X`Mtp4kzMKX zZ#me!09+X*99O3NBYvF%!+`in$FCJ^&I9h#XN~#MS~Bxd(9b zOwsEcm#Kcxc%2iN`ZtaFodbSH1GDQ}9G9v6r~tnJFc-f)IKQWW@ozNdHx>MD2Ii@E zjrnyVep`X*c#q@gH=R6F{`CTL@B7C5Xg%epz|?=hahdY(HQ@ZfEcnovAGNxFv%fLsNA-7^z%YjRNta%-4^9Pc z^|!|S-T>};U{2o5ak&}zU5)gXe24MBA2=?Py>>hNU$-SoI^;)=qy9s>_{{;osXt|5 zn+YCpWwO^Oey0P|oyBpP;&&>XcQcu!t7u>Xmr?xsb}&h^Msi%H_>ug*56os#G`KRw zZz>)NPl;a{FsBM!CVmd^yB?TN#~SmS27cz9Oj0#& zx~NprmB)BExPfWg*_hvTz?}}vT*@F^Q#0_Jfrxu@P133f9G9s)Cd0pLBF7Lvy3)lj z58?WOJ7JP>{Am97PGJ5eaGBCeV)7m^A59*d-=4dhBs*@pGVvp|Tn|jy9>)Ck29HjG zVGQw;F1=&H??m9vriKJpCV4psZX1BvYfp~LBrj{gZ$2>h?!|GL|>G+!A%$arb{nWh7<#)XJ3xXlwRU@1u%~YTqb^Rg5Rsa+_RrC zKkEN}49uwM90zY{<0ru(7nt1rjrq~pFpAZqj9-({Y&C^ zU%5&8)?&=B6#RBtXp(GpV}5lAXO9|_6u?av{iZ9A4M^`QVCL0vTqb!TeSZuvnx2!H9)n+JN`Vv`iXO;@J!AbD8{Ost;cGRX_^yBe6s1TGW5H{tLc zFt>>1>Y4cM1AZHU*`d)me#e8~IAGQ-F^(U}^TWV=BygGHN6pYCV1D!t&hG%9NovMT zS0;XBZ^*zbZZYOZ^C?FP3}c9&bn-&x&H2EsZ5^E7eF9^|kGecB0e2I9d;nLb@}U0t zTfmGy*f_nUMkfGMxNLBK?ZB)RxJ>y+73W-F&XtY%%|iSh1?CHZ%fyf3_X9AywGYnE z1x#GvGV!DM9SO{lL1TVo|J)=ncw|?)^7SF02Z5W^F*v_EfidDo{h5P-`$MNOzx~1F z6~c6J9Q~$?AN6M@0Q0%PWs(=NL#Bmczu=}TQ~uF-oeh|>Lpd&!{-g5!4KUXTTqb@~ z;cyc$e_O%%Wr|-5`27fsH^OoBn=ZYSf1SYG+HK5__Po6V%=jLT%M?Evf0+WzhXSX@ zPqPOLkd!^6M8P=Uc2R8zYhcCF zo83Dgp9iGZ3+$)?IO~A)()`3h18^v}G~pgL5H}!PvhVu_;s%6Ea(~(Y+`#x94BXr4 zaB1SV@UX%2h1N$@55x_KAIX(G1RRYo1%`-QF$5gVuf~Ufn+Dv~L%>mb9~lCU^v2sm zz!d_wb8J9956Hj$fLk~O9NDLV0XWD3m2X}QuKfBF{%!#7z&H<^^oTW$9-{gd5E$+= zy&j@{uQlTb>SwZxTmA##Qv8lc7p`XiE5)Dc`5NF( z5?IPbs{}o%+09BgGbXMtN#Tb>G$gaxd_axO<#yH7yS()_pS{j9O-2~9*XM9~WS7?? zFLgPbvbWJ`ch$I@P2L5C)654roHe#)x6kdWwoJqEwt?R6L@<>OM|-``k%IQP9Syd6 zrx#?W!{xIzIP9JVpR1wSX{I!Pf&1U+l*v*S4Y6&X^8w|Q^X;SUhvE>t`MFuBMWe74 zd%Sdh7(?^of6%Ry(i1rgaR3P!d+(A+Pu|>I>0Ia?_?afWtJ?#OP z#wMrT=5s1e4W0(nM*9Fao7?SKDmOKw`qVp#SCb8~Q|dAK<_LZKWVf@$=}rTy_uAza zXOqsQzS`~uBfF=*(d8yL$Qw(PjsgTir)s?*CD$F;6}?z)fd=saWNUG$&r9oD)MtmY zMXqjkxhY3$n!rYG^tc+3tFi~F@wz+>+C0Z+z(tw?mz}M^HQ3xTzC%wh3krgf2pmvw zwcup8HF_7c*xW6Yn~hDLMNT^uThoF;>wzvI%7;oQ!1UoPz!7^ZLvZ(cnw#v-q6HA# z+8W&5kfM4YRu=oi^gahek@_Z$Gy6HkxjL$Shj_GBHHi-*34L?;^mGPM^U0hRJ{={xeWKY?S_+xrrsI5wl^ z<#vT4y`h+vIucX}E0*f!<>GjGX*cp&=a0)ahg*)X^7rDy)CnA#2D36R7vGhZqrGtk zPQ;2}TIJ<7i6pWQEDKxDeKegbJt}u!EKoM#Y_aY18D$*v*8r{Wa>zJL#Mz2(bdO?R z0>&gCYpkhBQS44BAC6>gj#yJtQexG`(qgf>yl9bY&?=%4a=L8?YT!>j>COnZwF>y& z_#R_|Oj&lxE{MC#zxE+Rs|C8Sm1b1#VoE+bOhJoX$!x+U#sivvf>uau;8=C7I-L?j&7qw_q?xh$n#O4l{)9sLJ z+#Z_`3j#RRB&c3r6AVU`oGr*Luv0uuIEaX&M+owgX4r*I4G>>^ADTPuAe_ixs&zK0 zbVP{-TkY|;LTjy!=;p`*MB}Y*0b+#s(9bu?^c2rzEZckH5F{(ZHF;=0w zZC-DqFX>??;oz)8=g#d^1KwGoJ6v`jzAVn!j1$yGkJsg+YAI5_t8gDL+{wm87ma($ zRf+b+Y7%x4#Ci|vDH)?!urVaX^8c~-C4f~G*WVL}7$0a7jJRu1R8&;LCPcu5BrHlG zY@!tnA$gEMHj@_?>k>s&jMTLi|7xpssdXuC1+*?majko6U20pjv_-LsiWQa0_xsJ6 znRnlP3-5)X^(z-%?z!jA%$+-DnKNh3%+=CU(HJRb`YY&K1f$tKKYtuPJXs#{i-G^z z&n>pG_cS$ytvF7PhFu%wm^;`@Xv$>Q)O#81$SLEB*hY>vJ^5)UwUh06Vk)pgrJBcHs+)=k?(tO*e9PHJ*-`S_6|CzVV_mw~~SCe~4y zu)^#}S;^FLuzv|8iSo#O-Qgc2R>p#mqa=H`MEtfbzRJa;_rjwQ-YV(@T^mMnlShs% z992H)mdHIdagt8qzA%J(&ij?V4vAg-qg?# zDzAs)z-CnPw1D(h<&*fiu5x&#u%&8wJw6lK7;0)(7b4ZA>;ohE_bH*;i6bWCgOQ?w zhFawn!9RY%Fdh1+riPZrKDw3A6B->Rmkt}*gHvPCHc5wRwsq^|$uOrzju{6VN(;dU zob^_dPMZYR1bJ_0&xVT%hf_@{!|CDQ}oL z6Q7*oSM%`U2x>}6bPX0hg%dS4;fsK}J8QsnZiYf%jP7v!n4*&M5rvaV)KSQ{-%#ou zAAJkU%Eq2Xa~A#&QRCR!Jr+Z2CW&ovU4;xC)NrV9|zCbNc4j>Nxh7%r!n^;O63JC)TRXx^Mn#IIc7uq zi?-LcNhVb`)ilZjVrr4!pwuLWL{|7Cq-t(MO;v91attzRnk%7La_z(Id)jMTnWK*E z%{)g&cQc0NUGb(ReAm%tPPgnn+IXjW@a*7-FD`V;zE=D7eRm?ZF@%*7Re;&yaAL+*FMFkZyA184M;X3Z8f>!2+{61=(9+A>L&m?2Vk+vIbC2pU!m@`u zoO8J_i^sxVMn^iXL|fSh0*md&3MY?-e+9D-072*(k9F{3Dj|tw}+bR^c7ofTi55SjO_jUA@&wB0_zf=1RvTSi_Q69td35$55)($ zGO~MqhZTSdf!S1nuYs3`R3j?$_q^?H4J)kMwqMmbc;bd{^NA7fI|ol+w*61HmPkTt zNzKEE%lY) z$^mH^*<;M}WGt1`C@N){>|@Qdh}N*o9M2kyCFw;c2N#UR4&YMacc4~shpR%g+JK#{ z7OYEtK$B}m*+qyupgQb?Cj6>zQtHsj49CgsvFLql_TORvsXfpJDzUIzvHAbC4I&g2 zmFW|fC*XwMPF;cTUS(uI-*M$(3}JK+zRs4BeU&Xau@2g9$|Y(A%h}o**ny^?`Wi2M z-T%-FNAM*(PR?GXR2w~rh*Erw2Mhb$RaGa8qOh=W_QQ{m`a2!eA1(H1bfAP&_{>NIT4}bv%MK(i3 z7wqItdw}~e`hqUz%Bo;xE!@Z6w7D{Aet4f)$RiV}X>SJqAklvfCHw^H-1GZY=g3As z5ihU~V^eGIM!dgYQF$GdrVqtOGcvM2-i`u1#@#+B>QNNMp1vyBT*>JP%-5jPe+Clr zfO&{dH#n~7pg~G%UUR2lzO`zkqMW|9N+mZ(19|xa2zk>^LNeIwdrinlB|+m3yeq?OHFuv*uhtY&&`JB#Bpm9}pdGS;x=e~{H8)#2_?eJz-$Yk^6EVAcI` zc?;Ig7wJgn5j7!vK$5C(=#W9fF_)T=osW%0#!PBNa7slje59coT0Q#CYq`jVuQP^% zV-N$@G_#^III;4SZRys2Gcg>na*Y(zi0H=Imf`u&Sjp*fg}?z~O2?Bzld?8*1BAVZ6_9 z#kYHn1xyUiES-#Ch>Ywm2o>s8&Z>kT)TisR<^2YzzDV~o7AfUT9_lOG z*(ws>0bAh!1OBv5BoJv{bJ82da=Cz!&NDAjmSa^VYNY1 zs2oib#A$9tIilPF)HEYFE`;x4&I~pM>nnppF}wg8(RmfM!ScoiGyuL>nR}FsFNAtG zU^crFtEd?5fMS~PflH8rUE<{KsC?0a%G#ig;nR%Jip>!wP9BTpc8D}C!jiE`2(o54 zEgct6q57s~s8VfBv#wFNHeS7It1uV&mh-ha+3OD=?f|EK9D7)`;<-!I|EGxlnZ#gB;SenxmnY(n4)JKz6&~ z8C*CalAO&alBmTqW{s>1l{U{(KSv*PfoX;vJTm!?rcXM~!to6!cl`T&t3A=T{&q>* zLCe6SwL5tcySu)T!T74g`K>TnqBa5qwb5N7QTt`8NCunn`ZB0^+;mVY_PVR1}Ewn`}G~J z?m@kK8zs^qc81rO>F7a-T8`TG|Gw1LXVXl=>XwPYAgq~+`pO0PM0yS8Kbx>RFC#k- z2K1Oo!KS&vrYZGv>Ko?OYjb=6Y?AWwy1aga5gRCD4}4esY)+TbWLbkz1ULA=I@xM7 zN_aE^g=i9cpGG{=9E5CNA&_&78;?wA2{tV#LMZo)ipn`yN}G{=4px|qajRFD;}V#{ zlpPjUUr`tI%(|(;xW6F&{rr4p8i!1>GEc+|bfg87#DGlhqI;e>dsm`S}fSW7m-!K{XIr|C&Npy26odII{gY zR<@`W(pb!rS6)#YV#aWdM|j7A zLCYz)tuB8+f7ea4uouQSm)@B+K1}=~+w?vN9WP1r3jN^S%0aRBv#Xh;mpG1;*w@{F zy%1SLb^0Yw*KQK{SmsP>3?s8iV~lMD|X2uuci0Y#Ja1|20;*omO1x}ts-d~q`y zw3;{tJHmze01gOvljg#WH#Zn|R*5@HcbHG{MfJuy^c)<9@|S>AMY^lw>+{`1lfzlz zbP!g#4m(GNpHtWpYA9=IniZ5dy`zR>Njj(ptHFp%DK^lUubcLDFmKg7xDT5ez$~@8 zG4qkQmV{$>x~*Wp$n}S+7~*YclvWUjUddlZ>Z+1@ zQB|A>cpm*FEnO*LQV7~Y@BM~Ncrg(G(MqI&<9MSH7mv&%dxd4%Inz<8sIgVd-BZ-b zC}NODv{Ns_BjF4R`N~irYOrV<(Hs62cTkHk?TqZpBlMq9d)_D>J(iS3e;@(JJdacJ zg_Yh^peAF~?V+vHAmT@hViBYIV(XFNHvFX$1^2|1OGg(R5gJE3U58gHCX zd-u!J(>Jp)M6@Hsk=T|=#&(>l;*jeY%WhiO5_X^L;kdB{EQEOzgCQ)~M;Yu#{;>s1kAHy`GN3$ve}Ro>*(b#dd}^ka2Gog6F$<-dR0%ewyPSkho~{2^f;P}jYm!@ zu4xJ_fYmZ*qTWZ&m_lULAF_!_)WWJN5S9w$|A;d79q*J@G|j;+(so4H1%RHdCbU3f z_kr-wz-(W63wCnDE?CkyJ^WaRD0Z&{tFX|b>L3hiat7E%&A>#Res(4;dOOapg#lkV z2LmJB0K4E#^i~1ffMTfL@<437-+|8h#*B)pa!!URT2EhFY&mAt>dTu#p&GNngucCh zL}|4R^|NxT8d_k~iT$4)aogTu>&&uu__Uz42zBM}v9}zW`&ek-$w<7e^fK{YLFe4bOsKee1y4XW( zCf$O%$?98bYf;B?*m^yX@o%=#SRW3%YpQfTJExffU3%S!mxKRxF;s!&a2a6(3aucA z>s<5fZK+0ML$fv(v%@2(61q6Fh5b($yJj1U@_99(YR-<<%&OP5dIU@{Mo+U*(Tog+ zuxA*>FO8$4xL(>p1K1<7+j|%4MpkH(@tcPlD}1;*7B}CZ6%2J8Q#O4TC`YrGBy$Q`R^#0a%=$A306Gev1DH7zFT+}VK)o@g9^(x9E33#S zbT}${2_8s5VXJ(-3u|>$X;H-JDm*Nb@ZazYC+axB2yE!96E$={#08LBhJpWs9OdDK zs1-M8S*-{u_VFtt+t_bBur{6+f}Ry_=YBm&?RuaZ@Q}xM@IxYuioNl`5J;#68hdX# z&SYf8M(nBsV_K90Q~F1$Q^4Yy3wn|ZYU=5AA@^TTyQ`|E86F$$iJ|ac7KwvDub$rF zD&2Fv1aT2r8L>c*^7K&oF)&vpS1k7LSKh2iIE9*qvckyVQNeny?+#XJhjBwK`%RMY z4nB!dGN=u;@a~jdP=Z6|lKM*Sdqnhp>|V?83fSnjPVWh$ZAQL|&~Xe@ul6kTfd2H; z+A^%MUlR{FMg9FHR`?IJqt>A(^3CGv(Ek0X&DgY`U{rzHHr34UKYsw~R}S2Zkuu_| zTI3A7*I-VZklF(eWmDa1OmAUl`o=VUK7(wOm(D=cODHIqeW+-lAsHwW(h9OGUwUi> z92G8#NcROb6h`YZG;YFi=mfQjzBiY~k_2>^$p&L8F;Z$EnqWc;{TcNLkt(c3_XIZL zo%N)&@fN}y9ZR3& z4jIyp&Eg0Yx+rp^?E6&_;!7)be7Y-QbV|s{*_ST{L`#9zzy5e5Jq|OTHUDafxYLwu;Z{qLqJ}1jwxvt6X8dVnn6N(8 zt#=GPb963iznr=VWjvgCd>6CAJ~>Ejg4O?q>Ppn&WL6e*6AL=-#vAP!UMCmu5uxNq zqeh)$=rGNAsqE6DC8PxJCUg)hj^q~a;|(B3STF|+)*kK?s5=n6SJ6@%!Vb$+wi6*$ z4Rt63HnC1~3CvxNHne}(%|+-d9R=K*#stv_d#5>12jI4Nr%Wv1~ne% z&ub(`JQp8QwNkMT8c>6pvhqhG1KxzrWsZ9}20DjzM1NUBNyV5+RG+q6jzsG6veII8 zFw(JypNc`j$Oi5_q$e_)T~E(mXbMb_2^_%^U*DmMN z`=aa=HNUrp{_Z4Rhv`qJE+H+xqlZWIHXJDJ8o~N{Q=5o^QMe!1`?Pr)EUHiPC8fH6 zWkV7D0t{o~V8#VQ^BS7wPzP$;ZXr#?!unb8T$%9%wcKAUyNmAAy;*1Y>B!PW6_wQ{ z>IBM_O073Kt}(HCEGo5+p>-1aKJx}^9k80L=5)YN)ZS}=^U}N!#Sx-s90YpkL3ih) zv@466Lg*YhO%N210g!P;yI(&UZD@-$(qka@D2Kv#B`hINdZ-vakI8(4;p$El@iP{Y zBBQq_5`DWigj5fqrni3|Y8oLz45NCDhKU*6NS_;aHum>ub+~2CBGn`Gk_@u2T~6MjpCLjtJS+LB3jQE1JgCHMZ1Z zO&|HHG+|y0b=fnGPLv4cvseEOj0P~5%X+JHYoxl}gRR@8HhOSecXZ3X{Q4${af7iVkHMHT{$Ot{J9U|plTN1by3 zM?n5CR}B93>_uG)J*~G(vC$3eNS_4P827GLa?gaX^Ygvi7c&;*)i^iv^Wlfn&YNRs zARaRV?q*Rs??mO`2FlnCnZ>;w=Vt8U7#X2$JFUawT6T;mJe~|iRg}s|R5$5}_T=FKsx*N)Ll)FRQ0ukn+c@B@T;(3^T%i~(K5c+y=MX`y^}O(c4G7@1I{ zpmwM8`76m zC$20b)mC`J;i#rDT8xs_^EF!S&UNO7;FWE@W|K}8%el=qva8&vnOqhrfl%^QJ0l-O728p4PRI=;wgt#^WeBIX~ zeB?c*aaz`GJ?Mx-^JGVN*&VmAD2}1IX zypPI}(@gRA)<|x%#ORI9)pK}(AAgTuz+*Pj6r0XhiRYio!!l&L89vySo1tGn6-2tS zj%=5hotU1QK7EHj#?wd~Km{>m7=x|B;NcEx=gtry4@WIhFqiG{=NM#NtJ~ARF@pAs zL~K<6HzP+&wDgK5;ybf2s`}vio+Psm&=z_hPUMeC;7X-&7dA)5SUvOtT0M>YJvyGibrF)(I4Z}kF+kz6}b{+^BW8QTUwy2)n(}Mg3^J3H&*CDUDawL7_{#2MW z2?q7;Gh*K6&hV-?o;@Mv?XW9fM?>j=^-XMx1nZ6BM7vw1PUplLjJ`)UwKRwDy|R#A z4t{Z@u^2I+br%vr=HEcl-G;g_4wu8jhL#7Ja8ZZ1lyGiw#Q3ivd$K;*O!EJajcNfh$ z9Hh|Q2UM`$ijOi-*COU*Bl8It*aMPv@2;_|U%43~l4 zj(NZDW6dL}!>OK3&V$la)ut@tD)r1k5hGOeY<79|R$Bs`$ZNndQ|Xg%g8kwIEs_SvkbG0%^lROJF)8`5mfBaMxC82Q5;v z5QYY})CcD`;^UYI^{+OufwZ&V=JVqX=K5jYiyd+ay+-2VEv&3WR|zAXqYQ>_)SAc* zUNd5^+*}X9^`giC8f!`z<0jGwmzZz1`2@6iWpj((E)Fj+4ydWDCFe9tLkbW49GtvEt66Il%j)`thl!!ATd^vtMtrY9h3_mmObSlUt->ZUA>J~SVw>i^N zUehq6Wu^}7;`AZRkVefq6s!bezIk)!VO|Iq{+NfBpHfTMys*f7f1mD@djBBd&b< z%6_j7KIeuz{&ipFhY$8w_*6F2-@Vsyo7bIq*fsCI{dJEMF8uOorQXo^f-@_EJwF(A z(7K<0bHh19y8i~>pTh&P(z5#hV%VViE|qWo_Tl&MxO>GtN}Zwc?`Qtyf#CB)=Kd!A z@a1#T-+o)E>ovZ5{pzdAPdaM%{^O6{bmEl$zf$TsjsNN0&)xCO$LD7JdrYV5`=%G% zuhdr>|MD))ndf(Y;_Zne9ZkNtS_rG(*)pPE+^W(RxrvDf=&<`~J zm@{i``sDF9fA+!)FYo^Hnk&ncx>e(Q75!=7cb;1Gw~T-9zU<=z$BtF%bB*tO#*aQd zuk7$$_n2Gu!JhMSZU%pJX8Ge++&S*ATkjq7@m)Vz8o2wgo0R&g#^((==Kj*kJ>T5t zs5j2KtIMaLP5^%9thB?WvxBylzPIS} zqnCc7)B=rv{F15_2OZJpt%tt&*@Cx@xpBEtcWeA1gP#cPzv!(;EBE_!@%pD{|3s<3 zX?)>c!Lf%Qd_nbFtGiwJ;=$7^l{#P-KKH1CdzTFFKl9I5JazNwfv)$Vjtv?=c=jQ8 zSB<-VY3?(tk9+BiUxRs9YWxS+etyq0L(cx~qgVedt?wWAUZ>Qj8vpq9n}4$M`nT_V z>D0T=UUBY#J(TJL9?DAV_1E2RuG{OM*UYW_Tj;IKH=#*qYW&M{{`Fz*M?b78`02j8 z^#16XSCzV1ROGzdgJC_-#2^pi2PMWCmxXhue-sA8h`TY@lC(Gb-~($2Y&qS zjpv;F2+H1#<*)n6fV`;-4u9*BeY^ef$;?ZNlsZS_%QJuQvjP7e@@1zRX54+{DW`*< zmudWgtM{9J{vlJoK6}uWHP6-@vrMVaG(O|dZyrAX)@gej`a(%d*7HMdQRle{IayOMks_YH?q@<+@iQ;`$NjT+f9=%iV@5rAe<H1I5o_A|}ziak6Z@{naf3Wee zH`~?>{ueCo^%}qbeS3EPdimLBo$~o3>3^(kdQPdH&?#AIKYFWd&vDnCz5cR>JqI6i z*CSBEi#7hx7cPD5z-uS0eyRMzqAu^&mn!wD#;+NB-jI(@$RGFb2YVj0Dm!o|+98|e zTzJuMUbPC$(`N>b- zdH3Smo*I1o3%~5L$7ASB{;2WyjH?{7v}WCL`#w~9amnDZwMy-Y(Lz?*6E`;=vh>Z9 zFWUX#zF%$Kcgq7xP1E?}&nw*Y_CLNHe&@aqef;tvKf`nH(D7@vrMOBcEA1z%4qCr%)&5sbKk%A?g9mTe40%Dn^8_M8Rb~FP#-@f@aERv4M8IHk zZtwYn2OT+W9#%~?%xlh_gD{tAd3~qV)K}KFR0RPZ+xOVKzWoN^Jgo)sR?{jQu%Qn& zlC2BYRW>dtZ$7qKRpn2cRTDa<39Esdr%7P;F^#n?&HPPkZmOInaaq$sh-vOS4H>Iu z%xb7d#_g_*jwwl@2D4zjYfGae9&TG=9%9~W8d9hQrd$yeTu}>Wt89>*LSDV9FNO4# z*cvHVn?eTLJjoIjFW($O`P)rPge>b;-0p%LT{^r(U0^xhcxKJ4j(BBPQ~C|!7g$$Q z+0@Y7Ff)`px273E{JC%vqOGR&>zg+O@>o~bf_;V-Oq*LdErd0i&C}|d0p<-jHgC|e z{f_V3ufLP#kdCa;3#*eB+8ND_R1~Rj5X3xh8eIRCbDH7Itg9NBLS_!WvFbmC95vjj zh+uF&|Ao;$@ zRt4S|Ogo|`anw+U$s#sw7X}J%`;g50`{^vQ5~s4M_v-Uf?8vm})rZ$Dr0@!es6}I^ zk^$a3aaW~~$;U5t8kJ&2(-sO(%A zv+R4ZGc%Skr;t$?3R+D*;)0xU-ZOcoXkLJEA{K@vQwyK6@f%?%3WAbML7twp?=*}^ zJK{y0K`%Ny`nn2^6jFXHmH~yhq&;(_+vOC2`>eKbez4^M_S?3YnZnPx*0@(~Zn3n`nM*xAf{j@Qx_Ry-%Dfbr=)Y zG&IkgSGE0bZpGaVnR-p`o7*cmqcL|FPBo3WydIEybnclN0Xz|M(JU8(ad%j5Zm)jG zh-N1!yY#TMfzTENWZ~hlss@q zf7=M#|AOAvF)!$;f_Xt(gYAFZ5LOzrU=MQ`cJWlew5NUHj%d%Q=S4KJVHnrMnE!(d zAMStEMUBnwgpiiMV4kWBbDCY%dj<-qO3V#3Y1}LW1=NdxnlDE@7v7|U{Yul7=3qMHv;1|UUZBvUonU=*Qow^rQ$w9b?QYYbgIl2Y?tvvvDQ7hNl<(M7w zw)U&Ix4_rh%)_@j2EP}>tzFd6xS)tr9ZfBjp{Na(CmO#}@?qAwSO86Ov3dpg;T?SB z>Tbw&S}!zxsdmb060(VZj9Ox14cBL8W9AdbE~*pK3Gt$+$9KBfN4+(>2=$)EneX}x z&Mf+5)I_L9NT^3BpuRMByQ=>fD4=o>S0d^5F;GA`*_fSP{b!_XE6FG`bnIpbxEIj( zXab_-C?Po%xB~omkB47K?g1|3BOCLOY|skor7+pBds0VJtN>5oj|Uq}4hmQ-ijg9I zVPakVLd&ILarLCLiaToRBm*p@3S4w-+2$iQrt5 zL&GHKbD{JTs*`(hf4;9_nTP6x0{%j{Vd1>M1|tnk^RRn-2X+DlcnW_!B2`MJ=>#r9 zJC_$W%~Ek1ne{D$2JVb=FBXI2ur8wE5679M9%0VxFGZygl13&JP~>L8Z8DHiDeRvY zmu{&BR<)IG(c0WzEPV0+ece{F#Sme4q#A_+yI_+Y^htnnun^1QAfxJ8)H8OM-5+<0 z@v{fJ>~8pnLbQSO8qPQQh{Zg7!9Mt16egBW#kloT$#>FNOJ)m6KGQb3by9T8)~#Dd z^+G3BUDIqR>hB}?PK})+2|7JZ2w9Hvk+@%Bt_PxVgrJ0kpoFA*796{0!D*=(Ed*uP zyrgucreB#QtRv*=bP!3YgHcqDwmt(I!k?%vn-;`q{CJPYOFpvw1GpP~WMdwZtrvcm zhRL=)-9`KJYO3)K3h>Lok2RBnUAv{)0jR8|+MY%*_X7ga0L?S87knI2@;z7jNI6mo zDNAtfiTk6>HHAe;Nk~XZD1eO?M3lO!J_a(fnF=ZYs^yNx`U`O-a9gDO19D%MfRvYS zgOrK8pO_R(lqE^RWgWFG!ucgI6|zyE3E2n<*$9aQ3XT#eI4yx=tpsj)1`SFpc?$+S zi$|wxAY<|93@eWd&&^PoOMZ$p)pwwbYNnpuX)ARrMoQiEwf$|EkPIWzcMRfrazaRcL(m zU8wHEtmbgRq2XccfdY73ypG}Hy} zFQxPVL|;u8b&!Ml1A1Ji!;L6STZFq~fzQB?$1tCtTjMX{+3}CpYJ=@qfFIk2KXZ8W{pCj(wLxbIn>>VHJ$4qP}Z8qQdV0HDOtMCoq6FDH&Lc z3amIJ{Q^n3yENt*^aEmSF3l45P(!lOq3ELzO6E1)Fg*I2>t?xB{mk`+=DNSRzQ%XG z%v=vJ_g^yC1I;zNB_4&Sp0-V?MyoYS{*d>2gD2sh)Se(>Z!?C=&vB;Q--X(qHUqS)(8d3@Fj|K{; z|2SM4>Luy=8>p)~-r+$LM z-lHR)nq;SOY~P)o2DGwLNp~7D;qYyD8}C8#rQ0AR-3Fn6S_RD_xHSd}s0|MHvBUL* zlt{Y63=~j#4mZ%@3LUP*;U+lT6o;#DxS+$GzRuSv-+J79B6XE#4~D2M=k2Vk=q@-q zBV0xI0ukXVqNzL`KYNg83&6{CJX1D!+-FQ&n!uPV)+R8@(I#*n&NPAZasCy~a4M-~ zIMe38ALr>fKY%mkfUY~yb%aFM5eleHc%tAo8z|E0`)%k5>QK=UZ)k`*LLj!odX1xw z_*_HO1E1s93qO0X?TYc^Jsy4?aUR}nKmr|cW%4?r9hO9F)sVQLc58&h#de$`XvcHD zhwY$kK5|w8e&jAnlN?^haIa&1(tbD)5z;O;&UBj@=N&2U^zVwi6B2nR1ltCZAhW2Pp)JOdiHJ;s<)z+ZBsHP>W+QknyhC^=)_VhVF0O`XU*NG(*vC2HX#6tpDVc^3LC2PfeU z=Cj}G?lI9x(V1D8Z)rXo-GIw&L7#K4GNm>F=Rj0|kva zX~>b5;5&b4bVO^#^V25B@E3yo+IF;&Eml2YCAOZ6WR*hr)ncz)?dRouFpqJ_Nr9j^ zzzyLJzQ?m*X|%nwo9c~i*ogDdz@KHVIY}WzBP2v4Bmn|~+l2Ij%Rs4u>t>)Rk(miX z&fK<|Is|2sKBOHFKYhLd?l(UAFb^AJU;OUJyUUUGoz5+Iw*m9QNou>1poJ!WH#6tZ z6E9U0N6qp5>0U?EJ2h8m)LdUQq|lL&(2-C;6(G6biVd`*Xhs=)AOX!DXg|#o>%ipf zTrYXNaFV2&W<7neNEM|h6Vd8ZCv${^R)hj-FeoIrp$3YgRf6Cr>c(RH?BSQG8*yWn zk3P&pnWFJ>g^xb|IKE_vV4b>2HtH(_4F6j_M&rpItQ$KU{6}$eJYe|!A#)z>_@0oo zB_T1W1h*Dh1*bb56GTzX0;?%Zvj@`%Ue9aHYhUy$oNwX9!c}QyI#qHr@R51!RJqK; zpW&Hw*R$|rJ&4eu`YCbpXD)ws(Q`5rzjy2;dNzK9%*K1dvKRu?MaS~o0_MuWhLvbD zjq4BSA`NlyE%WF_fG*Xz(ST$geH@?%khhCE&D}i{kd!hDkd#sfNM_W}0VFf(O907? z`t^XMWX_68-d_Ncy!QfarPYyM#?w$N4ubJ*V);uw1 zb! z4tX>r(fESf=x|$HI(Fugm%|fDm*sE=I9#s7F}_mL^>sL!UV_@6`Vm6H7leEUab&}0A!Ao0irt)S>|*@v;crf`WK_I4 z^RPPT=2R%$oZAz$c3%54C)t`Va#{Lw)}Kr!%}Gd_lh8Js^F__4NEu~)ZL2v~Ay1o+ zJH5@>vW@0UJlu%giiz?h*?2B`n2pD#qohjH5t61Ow9TgLgH~%FC!Pw0a;PsN$J=zj z@ipCd7uYFe_^zIxfTYS}db`L@+iCR$S?$4grB?+Mb;j*W#yj>h&XoLD%ymytR9JzK zumT}0hz7+3ccX!}$sQl!iS1*Lk$6OQ0`_>Q{p^uQfb7_Q+W}iCb45oyHc4i15nG}h zKLvT)%MO171%(|52|Ex9s7pa1!Ch{k*zDkmsWG+zyRdz<;vi#^rDF5Qwrqo&!P0Yl zli*(4;JQd2*%<|rAPR)0kNZ$V?616fJp;{f6eL{Z>Jy;YGv!H^Xy<>Vknc(ncoO5w=BIjt?wR@Qs#YaR!*EOz2;fgqhxg9y5r zit)3De@u28Zj}255zIrw{1E)ccgG)nB%Y@|uLCD)>6OhjPaO|Yj-|?2NB3GNjG$?AB)t#>#tS*$m*8h4}SH#|nh*LXq>JWMjw z?t;Zf2w%~-SahO^l!#8(;r83W{HMGY6RK&1ey!4I!Zop@4c5r3mgF1DS5dY!zghI#y%S z|5JdU^*{PIJ^3N-_473*^X!HnU-&0s|6@aAu!$ef&Be~AT6q-UK7TyIjYH34mYHI1 z!JTrwq%GSx8#|+t`uxT;6#TKReBQmT!3ar% z5eg`z(09A4RR%H*=2kUtSvXj=?Dk9v`go-_>;E1Z{aNQdqwyQ~Q0n)Kay+ zwqzdGmFv)!g&8xZUnX(CWBbkgd`pO)nhLB@0e+-#Bo%DP@Ci2jMpSrIo3oCb{Pec@ z)25A|!I^b`)?BZ3ZB9tqoRBCB!L3Jn!TIJiGFM<#Kt|?@PA5E@pzT+ut5}>&?=Rn# z_jveQpJ9XkFb?Knn{f5tZNAq3uIyKDJV2P1!-geE%+W_1Xa4R+#%=(4YRm>(R6n`+ z*@N%z5925{l*~gzin<{rlq4i!9D-vQhv2?VO8y(Q_6K)(DY>@&luRsQ$=Q(GNx(DF zC+IjFOTb}3SOP``cO;_VXHFIg2?YsBaEIVH!yvf$6b!}JgF8qTZ*4yXy?u46qu;2H zk;W!v&u>i@ON=b`bFxTCC`m|UQE-$+!F`*Q+?FiZkEd@6@StKMB zBqXvZILe~nGzHCKxy%*VEyr5Y3s<(dZs=aAx=|iF#{SjD6%9*uAPCrBUU#w99eymk&W5i7u#fWY5cVDcpKLmK35g8hi z(tQz<1}7xZq=MUo{DMom!CwZ=+SlNB;9-?M>(ATZZ9YlyH+W)kNV%PRSfejSJ4f|0 zu^M{3Y3S!1XA_c!CKS+HNeJ#kyu09ZLx(q^SvWuAo6JQF#;VSTg;@EcJO-;k}hfhAc>&K2P6?RCGIY0Z}Lt7v>ep# zqN)H%+zdx`4{6*5fTTP|)yUJX0wmEgcRAdBfF9I2UUxV~cu1}O4(K1cRv!S8T5SX* zwffrK-39tnp26?hO0D(-B(*vkkkpEMcu0ALfF#E#KvJve4mT5!)Cv!eau;2OyJLap zJs$oYacEaB^T|8&Q0-lS^AkP=``wKF6{lmjX6VdABVFM2*$)(#~W`?=8(L~L@>nqH)jVAh)xwhNO z{K;I~=Y3?Z?eiEH$iqf2?PIR(^B51v!(Nw|Yx_LL>+tYKFBNEv{2`x^e|EtoC6UMA zPU6*oa%z17*AVwsxbM_ZoXJna%>5(4kkauH5`9c4pavn8;J71`;3^z0=y0tLcag(g z>2TLN+|3Smo5S7ba1S}$Du-L+aG1t6b@_wCt#!C{4!6qXROe8HWT|v%F1@F7NOs?}=)4h~L)7iW zox>quFj0&!6O0<}2T0WB@qk1P4+A7>n64MOI}woNJr$6s;aPx04bKN8YWN~RlH*5! zB*(RYL=7|0Qg9Cfim!&>z+FBY9Ig+)+h+;b#;=B%hnnpr{2uk0UH>&|m@id;Uj}}$ z)$meu+%Z<{_;o9-c^t9SFm-Ehx$Si83Fg}Bx>L-x)pbF0ZFSpR-}Tkz+UmOd&9&8a zxTGC#RXFdG9#nUvVILxJ6dH8~#%*1VYlvnm>4lw4TG<@Ekyz9mAyIRLM9m3~YEE!d z4AfOI+*)u{c#^Kh;iymrx4_{RIox80`?14a?{K#}+%FyO*ADlv!%_9gGpPEcE<4R) zqbWU_Z>L%O|D#!aFy#D>1ZFWm03t`qt0@zYkdt-ZrfdznD6XB>ux$Rgz1Fbq9||lR z;JiKN@cS56Nw?*-#FYe4);5Ud&A-WUY~#a6YETzJFG5N0`7LIMqf- zR2v~tZGxj}6CBqK39iiHsN@7U-Qj8-uF>Jnaky58V>Gekz0%=sbhw)x?jDD`&*A6? zkh}~`A`}^afxX8&83*e>q5rGd7bLgxx!R@oSdz((p`-IgjG?1$>oK(6d)#h9h;MSG zU+P?}9C^tYwih6AW^#P}ibO<1U2`3H0F~Pjjr~UrNI~9Fskd-)pfH z$jF-c!H)TINuPdw`XWZtXQXXgOLQIR(-I-nwI*U!BVCp~@WT;rtbB;vc4K7}st-F> zE;HA5tXyuc?O3_dcYV3Jwqs?xAlf%p&Naz+Vq0^p3^IU%a)2@Qn0N$;CbkYCQ3!+r zsymVku7`oJW2nOobT~T1C0&WbO>np=4oA14q~j=Bo^h7LwKyCdlah|3Xi0aK!~NLd zs3asEm4u|zwuIX;)PCiKeEB(kz0AAwM5+~guKjbJ=iuHb-A#Otu z5D>8IT(VI58ayXQ9SZ1H4aE|ULAXo0@*WRAT`vc2s*kSB!-hKszaNI_8e`5sKYx02 zWkqd8Q*KqTHW-y`gE-C8Y{gq#D-x1cBot78HFvwJzZoc^WxHiAE6M6y zf)BcY<6<>)NygE-fu+5-(aa@yM51P1j{75g&CEP(=ArmCM>lhr#ddfrpXq7k<53$P z#EIr$Gc!_Mn3a$;GogUqTtsm1nRKR^8J9f)yLO-tK=@r|c6zVKD?~J#FL4M1|8@^t zGj$h8l!dsoq5?eAMSqrt+XTe6=qStu_}RlB;!Rs}oEqu+K&E3J%jRFWJ89Fa7SvbZ zd+50}_~=LtzTSFvuqhWGrprA7{NJyyHA10wOE|_ z%%ylA=tXDQTw|2%qppn!NgERisE3eRa4QYuZR5Zed@HGpJCZ7zK~Ms3k~BSvje zxAmy)XxU??ZFI)s(oM6|>`S2Qupf<0N6_7-3HFA?LLqL7=z>oG@8l@*jz9>%Rzo$e z5YT+hSz`dn=x+j`mo)AaKr;H921rJKv)o;BljNNTNJf7b1Cr6-b%12_cPk(%kK;SZ z@gN`>{k`CDuK|+L-$p3gc=$tJUc~)( ze43njx*_epINuc3LHQxAhlzEnoOZkDhw&PEl2t4fg^CG!) zaVS6bUEgo6?fCN*bL|^{mKiipq~~BTz^;Ic4gR;C#T169wZ047(>Q;CGfcMDO*rHG zbFCbAK8G{;;CYH~vry5A~5pe;oN7Hw^sUpgGaP2{-@H<4#(eQ6gE8GWfWQRYQjC!ULx zspv$Pz8yL-I&XwdjJmCL;wYmNl`%SKbRLTa&(R&2xRy8~5LGr1&RRM`&!i7LAUkd${7Ajv^RC#vi|hg%LPemKahxH}p@d-&Z~ z3qZnO`cxG2kR6}L@9{_#B_BW^>Q>y#Bx1*}yN|K*U_?c8Q0p7MP62)y_=WXN%y>M1 z=m%pwal}(6?5lWKbuwHoU0B^|=Gv+g&Aq@`ch&-P-(FkwV$}(4Gaf#5!ZDOR*!KR= zk8?VSdH|QUK85@Eh(arAbH2eJ4XzV|n~ z`_+cmx#-)C1Exo^Q41+(3m32OU#=}UKHOea@h|Y9s0u=&DhSCoo`T~xo`M@}pss4D z!;N;hu@1*50aKpCRXbd*!_9ZNa~$qchr8V2mO9*x4o5$@JcEI>Qa`Vwa3!#6(W+3U z2Ij0%olCZC*k?nJ+47l;InS!jrCTPfMGr^h->_9mo{3Jc= zs+Vshx-Yn<2HC?B(brZ3XV$L~!xU&p=G4cQG-=NN;7peL#$5BorFjWS^Af_YN6e>j z>kQ;+UVc_QbebrwXZe+%%*WFM3pW>@lf%)Pn)50@>XZ3+x2%O<{@}dck7(R#xSN2> zNn7|;#W@E?r#d@S!xJgM#w=($U#VadxE2HPjK5%SeeM!K81B79^v2E->a~CgtHx0 zz1+UQ72{_Qzlzx%#lGn?P?(1*raOMmMY72E#G8Nz zn4LqJ(K2U_-WsP1bny6Wp&u+Fcd!DqpuDpc{Z01{(ra}MM|La3Ssjma0nYF_w2r_z zA7{S*2{^OzTb!s868aJnb3kxwO}c=}z*7asF`T6Hs(8Dthy9NA!c{grD_!k_Qn)-f zHa&aeZZUpHpbx)XUxVkB`BXpi@Ezz7K6|I>kfd9UbAKh6rVA$BFStErBi91OwC+ih z0-q^?6@i-9UdNfV`lGq#J};tM2np{I3Mj526x^EzitHw~#b;c9xMTQiX;^RU+_Jd2 zW>$Sd6E!tHb4F@A`Rr}OS6Er3`RpBYy}RQxLc(W+gwF&=J`-Fj`i$#{+Q(<}@w|Zv z^w~d>=d=G6Q#Lhba$ERDGn3!6O+{zDULqvCBslVt;50AUNDO>eyfov4(TH2qQ5gS+9=94j zYqF7PE`2+qFrxEDL}5hT)=?NI>nM!ymT%4p-4m6b4_(|v?_zvE-d@%aE!Q}X0VD`x zC?E;K7zIe~PH=gr5~uUd1oSHn%>yJs7z=qTjbmlfx{tvwHDhD2dh3(G-H0>kdXvF3>QLmGkjOQmfMPg?;24e}xK@YbGFHJ| z>2TLN+|3Smo5OKFRmywF;Z`{u9dc6MD-K7?T5udeO5Sx2x7p#gIGk7S=p~F7YnAf_ zUN{w%#6*I>Gu%tWGF5_iaR1qwo51 zb8U6P-R9crgs5U$2;5!4mZl-PIkDd z4tKi4&2qRo4mZ!?e&}$QI9!{g*N%>XGPIA7Ym=Fpm_I-l8)yJhi_C@x3!0`z8FHp;_Y>USj7 zhu@9764*0*Y{Wcdqu%%}j%1_K)YgZNtf{Zkx|3BXz>mf9Cx_RXay#2v5;EptPH+L< zP&~)4g9248b#)6ET&F2UQ>MTa#S`nzSz#}^erUATIXI(0buP~AE6>B3?{~hr|2wpx zkc*Izi%>vqMk>K=F;FDAtVZw#jSugVn(g4yx5IXb&KqGnMBVlVjn8Zwoi!6Imbs!u zcrJ6rsuMPbYTy>vT>i?U*Ft+nB$$agj}3#UB{Nre7vF?iCQhDC8#-;c zXr_N{&RWgPhoQ000oQiX%UQ*sVL$k|#?eZaaZ>@HaPYd^rOhmPPY0AZcwKVPYL*<= z0SX7N3vM}ZGH!Yu&>Omb?*rnvHAnp$(7PH6K%RfEp`L)`?ooi`?r=bV(03_}pX1jH zKYN^pyOa{%BaAl0W2?0`So8xC|Nmur6ZK zK}YD2{Q{g{!M#G9*Wz4+a~kp$B`I% zQ&vud64fZEN!N+fW;_xCpQAq{bd-ju+4^dTn!v9mP6BQ;e!R!SKY02paCiB-bLJrx z3VAP5OMHh5Wk%LCHA~zE-=_e-4E$J6IlQ)k+cMS7$mQB(IP?AdgBAGDH0K?Hh7!&r zB%DVmpmM=mg6m}<)2$m1WPU?Wb%z`hyrN zpHd;H+x;s%|DTKZvqvI|u0sn7MF|N-3CZwNa2$RLPRpv@jmAV`i1_`M7WBTLMC{=g zy>`X6J~;cQ>u&|F-bW7RAp_ISZ1s`DZ#Vm6GU7x`>P8(?-_TSQY}!VMstt0A2%L-> z*|U!R$VnJKT39mB8q&0cq-hDsSHJ{E9VR%h8pIAK#+2L)%W$(Bu4Jy*$P5a4@Ptpa z)fm19t8w#&S7H6xc$i!y%*Nw#^uVKshB!tR94@0|W&&{39`^8S!=>PZDL$Ktc}OJk z*bR|HN@O!7Nw1g-e`3egC0U}~V#l*q`a4+I$SI{LUS!i3;Fp14SaEyJs)z}1#tHRA z(i%mn=itptJJO{9eJn;!djAld)S7f*%%^ZBsh-9eaX{)BoJZpPEY76kb2zgC6lY;z zLc+j=@U2B~g5cgUkkR(?t;IwEd5pU$z>f^b!@q?@1#rjtGy(JMh94{SayI_xBW+}D zLq%vrO{iImasiP1@d!5``#n3MunY#mOyzM-(9vKIKBEysUFbeHkoX9a%;$b=BzmJc zFGC_}7(&u8gaYa|q!!$r1~LsZ8JnFTUhx)SRaG0UM%9*cfxbN9LSCIWu$rg!{IhUP z`oduZwzeFsvEEx5-i!4A{sMJ%#pl;;JzolnDh5tI4HKDeBBvIMqBAU6WXS1nh161wC9{vgRwl!Sc@6j za_6d&kGlbgPE`50E_f z=PunZ0LgQg0g~r({4LLY9MBy)?;1ez+}}CeD}dyE-*UKj0X?8|`~%SK8rlFzp8J_g zM>mf=SEbo@VGQ6?x(zt`kvh|E6kKmWQr-YS*gXO5JQ>gsJR?V41c<)F*yaV@)06SU z4E%WfXfNu3Zd%EFg6n+T|A9}bFc0;_k8nOW+;jQ+k=W6lqk^I0n#$0~h9-VlUh5w| zzW_g)D`EZPRo^bmlS5!ub={%RIg=JNhp-6-LqD1AW8!q7TqMI7&zV_zkxWrTePysQ zgz~#)Zv=X(&Wz~k|Lrd z^wd0UQe&`U4veI*MLFG+%@f;>^MO>3d~Y6;jB>lwJ7g7dF%2IseK#rag6_e7r4 za6SU(AK=VMjA=NN1~YJG1AGa}i*h9-%9T(+9fVYru&#QEJ0aP>k(|^O(NV%v0mU&i zIjO5&<3=c;&H+x!Yc-Hj%+;cp?Rau_Cku&=Ds?(*;klc)hO$MWSmaVFoTaEV6wXpO z{(O0;zjU6BP(pF?eCW%we&M<6b)NO{^Q>ztS%_44J3I1)FLrwA`~21^D&GFG;!o@=(fnu(_o+ zgn(|5`{IM)4zuM_7(a{_eWKR`9m1oUWuYBcK@v@kKs5H=qn5B}8%*9T;%w3D!e!gF zcPzxCZ6f5K#^rqc?7?=V`15sZ4RWRt-&r{40EcGLJ4DXGnH?w6wNAvj9%qQUYQXto zoX^7fCpb6Z{0Po?iPpd2JQruu3D4DP;VW>Ps0Biz76=8@rAQ^X%MD~iyG%se2LG-{ zsftrTn<2!DOYU1zdLRAp3!gkd-^pC@%Hk=`Z9k-BQ_HR^nPWqD>z%hL+sxiDtL5{P z>6&kkLsHIbSAZY&1D`4fjcYqj9@on( zBC*zXPo$~Qx9viO=Gul3a)*~V%<*(De1bjrZgddtigU3+Vl7}RpA17l^A+|TX&r*= zi*e@Q1+&(zr8t8dTG=Lxac25KXjI`FLc%wM0*Y=8!O;j2T;wP`JWs6+&CEsY&u+m_ zVP#4gYnfyKU1XlfS*bJRQae0b()+IpjrAZxhw7)q$uH(_+6&0EckCp3cB((5T?}hk zJ43baW}xOg>($Y0zF}-k|60O1n&|+5`uRPAj!KFkmThXO5R@pl1ZiCxVvlIUG^$6z4R`i zG}JFgeFTW&m7~4{Kw8I^MD{s+10>Lg-vu%l_x*+>^N`d2gWvqPl4u2yLRVJN6vEb# z4fXl?F=UO;FTgJYzp$)%4N29@Cu@2^JNkjn*~p_0a_XT1#+yayFSlJ-45f&N4U6IM zgoh1_VfVtrhQ%zBOLu*{xwc_3&zfr+7Qva2$?E zx&ntQb~sMVNL~(BB;9m}t8%#c4o6c|(nYvaOEPA9IuLSQ(qNKb^`}DVPU@pf5Q>zTSBJyi0PE|&tPCo zt{JEo8c!IAkT4LTfFhX%Mb9P}+0x zvj-V59#Q_`q?(Wrg-}4zDImB$1~RstnO0f}tXj0nY%aJ77u9@VlApryD0>Sa=|?XB zBstmu{ZW^E6(H$7?{c{N07;*TBvFcontU{VyvM`eD>69Qzb6v&Q1Lv0-z%~By2E2k zM>RFf(<3rgwE({i{8$A!yvAzMk)``e-gsT;VWw=mccAUwY!^xsh==V$XUL`NGMjzZ zSD0(tg|ZjtVY^U(ez{^h`{fGEr-o#Aj54p--JXF1%t4tIgWEpfQ39PUnsyT{=oZSyT{jTxO=_#N`~Y@ri2 zo;S2Q2Rh?nUTKsk;MAA+=#8h?d^YeDQ*PJ>xpQeo8=NC2xniBLk`ao~bP`)2k*P3N zOk^re;>Ymt97Q8a(oF!wX3EinKZ#6j1a73p;ZKy9oeSJ({CJOtU(9Gs{MpxiFb{b= zgx~X#V)ng>QKjHYWfO?6*Zz$gpX#-MIoH_}KO9Mit;z~|iWrA1_Fx;+C6$5mScA;& zEF#t&XFdh2r-!3^;Y^j>1Lrev-UsJeocG04Q~jS>T(U*`J2rE3srC$2#e1nsbHiIt$A~YH?)afugNvb<8te{um=~UlQHl=izlOIJeu@ zOw8H;C@sxZXP2l~Xe;R^xFt)fzuCIg?pfHa?OD-f`ep3n@lA>ky&3)!BSYI>eEo&1 zcbOQGwcEmTKU6IXq@=LVq1uB8o#-ulOA2LsEFkNTFmLK=-hWl*q7U$b@JAe7vibUl z*<*h3<>Hd{Z6)iUT$=?q`33K?xw<|{)myry|BL$l+x~vW>I?`6ZtOzqs28BiAujR# z5?AWG@%$2UmqIS3Q~aZLR{ndB_!`smzOLic_aN2Qt}#iH|&@A%;nwU?xuq~ z#H+$-vTJo+vH^)#Wp6;@RpHj-a+i}R@(hkur3QllN$pDji8Xi%Ah8B#0Fu1307>3P zK$3SZAh8QCb9b+CcdrK|7UFVu_X&6R89-9|-ve5zYyVe3D|DyGZNyh<=wm?gMhr%j zH%jkhb8tg($*~_G$-xjrsp(OGq^5lV$y=TXNZzsxki6w|KvDyS8%lX|0ZDn>^;^oj z7?6~AIUsrSo84V}iptzw21wrgeL&;!Zn1qw*b+xkA7_B3Jci{!?W1!>20g2BJMR0} z1~3mzi?uk<3wPgMXHj#0zW37OJJLgFZiPtaEtcW)$zh%{5-wp5Jy(1l2d|oH1j&q#tWv;E&Pfr35 zYxNhIYwI|pqlkyS4w-9f^>cQW2d#cS?LcP@HL=fPq>cNBYBYei>(sZd=LU zy>TW#eFMf6(}$3lK7=IXP;m6k3yzH^xKR#Q?{G~H$5Di&<0wM%-sEt%INZGscfZ3u z=5S9s+=~wPs>A)+;ofz)e>vPI4)-62OT&9hU3NE6R~=|AxC0%IT264sI2;451xJDs z>Z%GIuGHZeXf5f^aJUMGt8=)s9PV6)yTIX=INVhZcay{2;&Asm-2D#sn8Q8ka4$OC zs}8r`;XZUYJ*s2anC|Cgy!Bgl^gYt!DOy@K1^C&+A3}CDZuo;qnTOE|d*F9rSkZ3J z_M2nmLr-BxW&z6Pk4ISZ((e$CqR7>Ey^VO;HX1RpLo(&Ii}HIUYCO)qO5+id#v>F^FW{{N z_lki$jkj{^RyfsRcK-d0-?pd8UPqDlCup)ed` zqTmHb1urlevIhRC8lM|9AClpW| zO$aW_Kpu|w>s(SKwsFgc7vN_Pzs_BN!u_$~%wu)#^^uLgGd4WoK4>X&3fh^>($^9P zXH743vfu$Xhj?Zu31=?Hnf>5&oY_yYrxoTQB+NqyU)Kdy1-HsT37Cgm);{Jr6NTsd z78ZD!=bGf1ryY_Sdp$wog4(@|AaSwDX%em;NSQ;nhe2pX2!jw31|bwsH-mD5ql;2- zTA`aoLR!IK6|{>qgx|;c)ENaY8i&J(zHxQWk+@ro9}?)pKkxlMun+kZKl6~cbMgB{ zB>Q}atMn|@%tvwcc%5%nfFIwEHI~CWTji#|JxdpIZ9<&+uKtc;tm%snN3lXWLP9!1 z0mTVb!O?vrxRgjI@=nry8dvhSMY^@feRl%V-P?ZBb%dmaN?#L5IV?Quvkn#s)JpL6;c z_(yyMVjgm8Z~Qj2pFm!(7M)yiq7jqRiJ(+-$$U_$zM{5vf!>OwA{3O}GWdQ4_+{W1 zmN4&xQly0WRVCk-@&!6X^rb9|eJR_)_NB)-c_SnQBot7TGQrV5B)D&Zfd4?{{DTrN z0sr290(OvuZ3o>VI;V*}iK&ZLK6e+KDHHd(rX(ayNeJeGx!VoCFqTyBvmw7W;va(2`I<6{9r; zH`+koCM`FkZg(W0<-gib%Z^fODU#6Xve+a{5L%are*bi`NJ!{MD4-bSD7c{pibcOI zClsbPCy>PSn36aE)S)DTQS{-LL~0kmBr*>2nn$W$zm_T z<$_p(^GaC6B0=o0;?_rDSs?G7@Ja&VTP+I#v%nTPswe2vT|@X2WuuM-E>X|86t(mF z(V2%mV-bFCmja((AkV0c zemIj}{mu2BU3gr1GLwE$R2AZ8&R5$s_QlV%ci?dX%pO z?xA6cN=)y!YQxDkm-t>?YMr8mDUS4|kOCq$7-F(c_oW%{Q5GJSi5g1;H2sA+ijg;Y z8e+`N9vYegh&D)$UWy^O5ODvGy(*O__mdEV!J zma{zPyk~pQ;iY37AevFI-}9Y|r;)g%Grq7MMG6^Dbs`=r9kX!l_@{J~;8drmyc@NP z^f#(17+OmxM`jd!$_FY9W#Oj?{G?L6E&B-kn!rtlUkCo9@VmjE3O^YBH26c|Plr#u zGvGf4ec*+0U2J(;(LL+p)`GtHxn;S zG@Q#z(**`mY1+piDoxZLMAG4u7+EMmXRZ9`B#2 z#P(1C$k%FP4>#z0+5P+DHL1#<~tlu z<8gt2IpeMfTYyb43;_`jRS;~GB@CN#SIo1;_4<$$TX0pvMFP3gJNh*A$WG0q6|5e3 zE>9JwWwLVL4Y5p?Hc6oMumvDvOKHgK2@aU;WvO^ z0e)-vSUEkB#Th;Ym%iTT*-a47Zh|~bSH)9Q)5sT&vuSRGUF~_HVkOgsik01bSfc>D zk@1E_BYYc0&w||y54SzKjYhj2%{$RnGHaon@0-OT%2ea{Z6a{a-u@YQ-rkVm#6uD8 zkL!BjxHtct$Ul^(g>Lkc(=)YnHIb<@gZv;@I?_c8%Mled?%YI-c{hbmVQ41qH-m_0 z06{zh2ts)S700a=knI~v_C#a@udvA$Lp{oE)oELBwtqt*1#JjUt+i&7nPnWhG1x2D zqw{VjnezcZXp=YCIw3#}5kW6gFF=(UWG|y`^r4!)PK^Gc+Vv7jIgVE%o3QT)57Z%7_J*2QIRG?sPL&Z8h7mWNFlTtwZ@j&9>6;LxrdqQHx;V zIICsi;5Wvzp76uq_kte#EqUH-pS!O>f~^oUh7D^Ei`Ft z?8n|Y|3;(d?J6>Q8VBb_zn?(}bCKHVMn*p#5i>4g(vAMd;v4<{SZk^zmaUppMJ*e7 zW_+dIPUHRxmcfmiAa2|Qd78E%=Q(bNfJBWh7C}klW|gvP{NPQ)P7t-<_^FSlp}5Er z$r;x?EeFoHJezo^KA^$~B*q8UTE z;*Co>3a4@1JHD1?Rfroj@Kh#qhNU;q zC|~GZhEk~-Xtl+=sSbR~uY1KkwQjhf5yTCRApWl6IC@ucT(J%9Tj;(yLmLZa?VT9f z#^M{=|H}KLq}Js0<#8*Q2X$n^CEAW$Gty0RihL zQ^ywl(PV5vbChg_<;yU(8K`6utar9iPl!F%=YRQ=p=} z+9&Z<3xgs>vrPiRF)$#T2(taFS_#yp<>Te}oKl>r)DjT?*qT;;m`l-T@SOqi537R! z@eiw`)ziL!#vuvaX}4YR>GViI{L|@ifcU4=(*SXKvjK6A=K#G0TXx4XLW$c5XdT0S z0jMz~+pqJ!!_!DyAYjfop5GjK6KkmRh=(lb0IqK}GwqX~@z2ZE`O7suYb4(bpVHid z%LAAF7wcs+D zv*KQUnf#WxmtQ7R9o<3T$Rk^!YJ}`dhUFRYf=5}L_!02);FB#qC-8Ma%Wh z6^^zu;CgA8kjrD$Uo_w7_C>_f!QldNY4q$g{b+{^bYzIsm(;V=mmrvvrM^Uo%7*k( zUvdX%BLOGeX*F$rHRF)f^sx1`HTHUvJfqM0>3ufMkjv0NaC5lzz9*~7>VqeqWla-6 z97k0i--^Dy!jZA@sxb_ZJLAQ&MS-I+4vy=iaDx;sRY6n@aveE<_?GolA#%xc0Qn*; zUZ%x>xI9XiOSpV+Nk@hnjfC@sl^*wooLlCcU2=X-19s^`kWlgll070InbAUMAZvrw759=lG|4kc* z&tl%aZJaY`?c7`&r!veYz)2hDeDRC^|4hG5mG4NDBMUAMT=vVi4_*!beGM5z=XSJZ zj>0N=)j|-jS_twqZARt6aqkJp(?qQrj-!oCI2~=x#BsEd3CI0Q;b#A_nzTxtyeZzJ9ziP`|M-6X0Mu_8V+cF$SZ5dt#h5`DM z@lsoce)Ry^)Rb$ka;T%v@;2 z5#(vw2Z+;sDInYS3icALxY1+s`!0nmYT23B71RS9>8j3m#St7h-!*KLo$tjx*pW1R zqPh*tmVY@O0m$)}YpO_(8A#kX*QA4paHU&n*u@H6bRy9vvM4L&B}55P@Kx$+mr2ls+O{ye|1jT z?)aIvdmO%VUif#c{q z2aaP|ZExaD4O~`38rOoU*l#q~$J0<;AYjfo>$VoyOhXP44;dv*Z$50up_`oEq;$T? z<6v#a&E(1oZ-h-c3hyRE!I~`!RvAQ`7c7E!Y7^vX`VCwhcTqs1J{5yJa-{e)sbOn_ zL?3W3*wYAE%yDi-F9)MbFwR|+*Jhl%$YVCn9juLW7lyvTlfh>;QFQR31+8c2Pi@ws zhub{EVYePOh@vOs778L_b~3KV*}gVRcyQ4M!I!zUz#+O9xdy$fU0^<2)rOkb&u%4R z8>6SiEncRkhz=h=_XosB>uIIQW;}H_QFD)v)>CtjkJeKok3XeRQ_edS&;}GjcRDUh zjMh&C#7FCA0^%GrZpt|p0^+0f)Fk7$cL4Fx`u%`-_`UnA!G)0a}0L0hzrvRdF7rfX>dz@~zdWr`{nwcx`G#Yq%M$R~7MkmSl zHuRf`hpK=j@E6)v0sqVms1~R3L@#QA8f!XAc?&K|O}d2B4)k&`^-il>X(?+xaO5QA zV%W@PXIGju@ZrK7O&a(KU2;3q5OFUj4el5Ba?&7E+{;OW35NUm;$BV~ye;nKqycWJ zdAvlR$s;?W;XImMn=A02y74v-DzAyVf!hcFDE!aiQ-!o2z8mD)~ zY5E0J9Cuzop0p5H;AotQ(@}4n)74Wr>Wy<;YlWlUIL8GkT#Ul?RJb7um!xo+3ip7* zO;b49P??8CZz#~q(AoZqHSstUmvqKP!3TIS%g`tw9!fRJ$e+Gy|A5gg`2{27p#RUT9jJZIydYqwNCLYR#dvR^G&4qvJWvBHrw)3Vcw0LXm z98}4LQx>vnrHrFIp*jxD2U#PVs+qY}RfkV`RYTm*aOX5D@ zsCuf7t8z)d3Zf17X_I|AJGXenl!}|(FN0(+QBPb78%^gUjZ`sp5yjFBpTg`a?p+XR zp11_@#3jhnbOcl!cT7OG#Z+~wHsD*Gf)4Z{Ne5GYBlt7$DGBw}O*70h$}_*xj50HV zz5d>ZhdT*@Bc!kHv_Or_neCMT(gtQ;Y_pbJK65^x>1E$(-4ATGWjceu0dv`ktPdL|~Ag&}mT+zrtn*Bwz&#VnrV*e}JGngONZ z%d~3d$}8;V@M{C#5`F{tt>IhX`@@fd-v&OVQ#<&SX3dca+)@bQmO_xHiB1yXxY`2Z zgLxcBgL$0JrfAA8`E9cv+C}a5S-Z{>mE%7F(R#A~D8yhub zRH3+}GgePa@L;6jwM0Dhf~F!c$<}OQZgLW%7tWCwWyP38F`K7#e6-OBYU_LBl8(Y> zoV0jcj75}2BJgA-h$kySo~C2q;<%Fn63x#PzA|-I*ixr^)>NEA>tfN)thh0!k{JE} zxbyGgSl_3iBMowkJF}taZ(?SnD6h@TMv=#CW+MdSp*-+jMFKy&xPj-#FQzGaE$}#c zu~?rU6y>!Ee38etfsd^6=q{1sbBY^ie#l~)qSpeA0~U)F=%TzffiCix1-b`P{0uFh zoE3IXx2&_Z2r(;W2~9i8R!8cLN~zQPoSPN4NGAo=Ii6b^@U3yhDKlYU25Fe#IgKfw z(}iOPvvOI(2%a7eM-+-zFgW z=Ch^Fv`6%qScplT9#m;o*g`$%sWa%9+SKXY`L<7-$SYtQ2dXID)La*{gKLVLqbJj- zq@^i(Ek{olGe?W^+T>`F$1F!95M@#8QnkqUmudj0HA3!X>I8_-D#Zcf^IH7?@tL(m zKp%k4-IM~TKZ8a9dJ~ntyQx4ueHakueH0L%S)=j))r@W#AU?B3U%GI4?*QT)?*rm9 zYlju?7$82gb{P;4UpZJM=kNl=!&e8;M=VtJ0P*nA@r^uu{_1HLK%6%i5D#BZKs--1%P;3y#y!|Pu)$+0r9k=T;XZ;wtBi95a-$TsAf13r0baTo6rFPTBU+l*4F_QSc$s*p1rh*%J{2|Q z*jM8Jbda2OkZc=TDM&X9E+1T!p2BIvKdO^t{HlsZY~buokQzzdQQ`!tvja63f##h; zQfCKhQtg$B5(7s|hUh@e9?h`Dq3t~GV|cutQ_)HnI`*?3P_z*u9g=N(oF{3Y1v7@D zIGqHs@r=$s>?yi~7=EQQE!kTJI63J%Sv;4MzO%)>ob-LkaKBaD%Sm6FsU;`R%%ouo za#CMIaWC~*#J$uPC+?-bp@#c$;$G@oAnv6;IsjMKcUas@eV4?&)aS<2R-FNgnHlD! zeww8vC-udPd#Uevp4=*atHiz3w^Q6peFwz7lutXJkdybWs13+TeN-!xE1X29p2Eir z$A73Eu^?15K)pra9~YhZC*k`8hvxD`8rnt6b0T%P(3qP@bI5bylMT*;PgeFk{GIUU z!~X{ULioSKe*wNbLb?b(ooBlkegpVR;dg}p68z5aUxsgi|0?`w_$%RC;je=K0Q}eC zkA;t>$3&|4*21SUOM_6nM?(cATdZ*O*&U~&gHt*02MYI@!hNA|M-}e4!u_If=N0a{!qK~t>!={0vZg8u zS6AWcD;&K!d06}vuA9OID_pF?^-{R|6>gZqWhq>)!qHoo>v%-ro=~{i3b#n%mMYw8 zg?m%s-cz^_6z(&H`$FN4D%^2}`$gf-E8KO3Gs7-K`Uwc>r*QPf=JBAC!|7;qXpW;+ z499g-xL}2gRk&UXcfZ07Q@AXJ%T>5(3O7^X*nq}AJ@45_5cZn6(Spc-dfwHj{+_&} zoJ~LNpPu*sWY3%LMcV)daRGH7?|JhNi0KK=jH^KOPzG4AH1_q-1lzvunGGG$cK?zNgWGWMD8w(fNjX7vB*UQ-i8 zbvOU%UbEyV>|XzW>|N8;JMUc+#Cz8Sd75ZTaE@CqAWzdb3iqADx#Ru9>97GdgFH<% zGQx3f6|SGc4N|x%3P)n(uOu_1d+%dQLD+~H!$+kH_F|y$D zz-525J+qBi)}S{BFt9DjX&75>%P)tqAlhuRH~K7x47M-Wy;Ah$SffPg&N7jqmpQQ?@C_2;W6c7|Pn zOw-viFs;ek$jZcV3l(Qg23|jM0UICESBW(+Lwzyc_QA(Err|Wn0S!)O$nR8yW(F*I z)r>x?ruSJpdHh;ae#H?kGh)^ zg{Cj6R9Fr{||#AV;+es5sM=9U(c+a3ima-^XZ zmP&l$qn&8O?EUl9!TF63~iR$S8VJ7xIIfEJ5643Gy_3CZ3ixeIX!E(-nogs&GCC5$C0qp`6#S zwo0zZzzT)wK{Z81h#4Uhb(iehfDfJ`?8+GzSv?M2#skxchvGz^xGXEQfslW;kkmIO zvGHAHb@Y+L4vUJD{`6RXulDTE3R$*4AnPhTlD#+aZ7)SkF>3o#kZ~holbm-4M_Fl z)mq}4wI5nk!R?12Za)O^4hP3khlAq`_QT$DtYRvst^Vu`^RsU}^=kW*pfln2I!F;*C{ z+6e1xCsN*A5%(34@w_%7h}#cA{NpH&qmQFF?)KWxaLDy{Vn4qY-+umQ>Yd^niK=nz zHhxQDBXl+_w-JK4jS$2?dg3@*gU4~YjTqioG38RHdx++d2R8TNTg}^V1UJD`s(ff9 zf}FAPp?%Mdy>sHB%EuemN5wauTPe!_Pb!}TYkoUHdYYH=W zR?V%1#=eGkB=N{1wzK$F_D?m}2?p4!q%HT7)pJG*q`Wd#a}SGZZ6f@7cs@zo*HP6R zLEHif;?*3-Q8mYLC9^=s_1ujt@F{5Q?8E|pD!v8&57l!eHnS2{bhlzaKhAfGPsxi9u+Zxdw+=Yjo>7A5sjmXV@ zFd==cvkiIl;UcvmPho4v7x9vg;z~R4;2)D8+~Gs0i4^xa!f&ODKS4ZW2=X*FM|NZa!mfqO=$37H(j^ z7A+Eyz7FPzNDxm%f;>%2K}Bg(*7S;iFnR-s(|s%;QDsoV&It30A7PpiQ>o{SKIM90 zdpv2RUZN(UD(W@Jwr`r$VzA(0L$PXr>rs{3E{UV^vUnP^IbjQ) z(nZcTZL6SL=>hBmP?{KAkeX`EHPsMZ%^rogkn95Nc}c_+xO93Do}HVSl#c<)vXyCT z6k2YT7?e9aIz2C+KO>+O)!JMp#WO%i1MJcBG#E@XDox()f-P0!d$HTeJL*iwRu1E@ zn#SWC*G*W)@%LGGR4miO3Xi?pUKf0n*IuR;fL1UFu`E(b`T`e;i;{sHt@qMP$(O+S z8}f~KDBtJ{jVbo>Es<{yLvk&+JaFCSoTJ>NAm2y18BK-L%5swy&)DQ95ne?KH6cRu zb_z0h4pXV?fJ-`x6Xh?ZQFDPz7x_B^etY1u;8UElMLtt$;Q34t&u4;gJ|oI6$JG>& z_Hw>ZabTFoI`0bzrNxy%V@n#C@u;rIeH7|S$02g%?w#a zJd|ZVxRMLAEH!CZUg`~2UeIUTl!F#riTxcE50byHlx^{N8eJIDIU7FdodciDfEIJ| zWFv?t8$q6?CE{sW)5`+#G&RgKnfBr?rPJWy>G>^ktvT6wgY&Wra+9qsaxx0?=o*}t zn>;wDU|2?a@?ezfw2bs&gGX7DQOWwJv`jMv<>gti=qfwQJ3J{p!iO2(tfY*V$vHW8qL-grU}f8y7EP5LT8?Rlh2g!sb@k3nlq=Zsyc;$0=J+l) z=w{xriM_%S;^Sfy!V=?ydi9R#9R=7Fm?}jPf)(mSV_9V{h z>`e^|Z|mq}t2HGLH&$=|wr$}j<$EV5WqA*?dgml1kHmy7BAD$BOnO#|b#zO#gpqVb zBO|joy@{z`TDB=9J1g0mlW$5W7&ZcyVTZw2&MY-a_wM3dc$b;Tn*0tmL{Tt&p{6KB zW}-UR+TO!n7`XTD+SNNMYgAH3dI}e0Uru;>ZXWi9wOWfwk8Q)lM8Xn>pPj(@dN)F` zK~#g2@~pm1yqkEB8|N*M$ZKDTZ|2Qjpp2pklA61gfkAx(eQ1pvUrJ($XZLbEi7W}I zK4dQziKLr6izUK{5Q4NF)Ne(ak6&vazaR@a7Sw#ylh~=JnAL|WnVD>*vEAAut02?6 zOIPoNsDWX2(ltx=5~;-4OZd#hLXvu2y~FzV4(k;g6rC7?a?(37xKDU^Sg*vGpk6(~ zdf5^0TLAkH@E1nPVMr94#G`ES=1x(2s~45m%bJuDmz6OF^`3Nv`N)&s(kIYIEnMUi zm6krj=lP9|<1A6}!J!e9lk~5p@~ujBWH3cF6^);79(v}9`7B`^WKFs^(%Vql{{H)6 z+NVjmckm{1XYbZ64EpGEpRX-}>l%OXNZH+?BcE#=Sn+`b&&gl9b)Va6^V(V6!>dLN zeC67X)h~E0O`hF;*Yv=u)vtHC_H5#~@_XL$_1aNwQC`NBl>w{L-`h9;;K3vN+r0Yg zj!V&h)Y!64-d`D;_s5~v-4>jgzOhSFpJ6{t>2SJz53jZ@zPV@qPp>5XtIE|id!IVo zqT`pZow{$=8*V$6FL|%O*Z74VDf0f$TCJ;wBzHP_W##bF85wgjYQM5!$B1kD7RmdD zq4&j9X@98Ghk@P;w@20=RNcGs!O5kEO_BFWb6RiRuzjTUk>wMXooF@I<%hWH*IJB@ z`D;tYLm~TLIqbG~-I286z7ss;{iWXqHvDtl_xXDw4tJjSec-|Ep$`vU{BZfEDFH(u)^f>owB#^VO5CPd1m@)5Z1KkG>rK^UJNP{#j#CR6U;s z3wyfm+tD?y{0ooD`%gCShq}K!>W$wQPn7qgU(58{SZ{+*i>>AR{jfc$ zV~+vB<$pf;;%a$6ID7Aq>X(lHec+K?|H<_^oPP+}9>gzV_$h zb2Tb#I6L`dh`Gspd0#7|^rUNFOn)r5=cY9qFGP3re75CRiKE9A9KKL}_JZSH2j6k& zc;vGm-5!_EM-DH2z0#gp2jufro6naUkr$p{ZrSDuFSHC!AKqo%sJ#!*4U+lcH}&j* z{=Wt6>9ouA!Mf4iF02dN`s9(F{*T6=Xi;zarY297`S8dOUe&7ieQxa2p_|XR?Y%x~ z(@#(S9rj~VNXJQ0_g8wR?D3vy9vcdFo~UqNwnwMW_D&l#e(|Fx7v)48`|J2u?j7q) z>wm6v|AFsrY-WDw{_EX*cRyY4&yU(#TMziA-p9`z^L?iF!@&z??rEImFYiCQukPtq zo8~QfDJS~cr+?0A`mdDwbJiXm6d?1n40E&ly6Pp@oPVO(@6 zmzQ__YAy9vrwx@p-(yKmmh?Naf?|^&_buB!a(45kZ*FSoSGm^8=C7nrm-m;G@9pzi zBe$gi-9jHvO!l7B;)%Ext>*Z=eQ3pxb3NbvvWoweDNptY95VM*|62adYi0KSrJ?VY zt))z_%lm_^gDY2g{`&*+{=k6YpIfUub&tGXH?Kv%dwy6DUwZF~!Q!Q?c~P}_-6ng!Gj4pt0iWy{6wv(aiRMktY<#O<|9RGQ1*2jZ?99y$StKgIt&0@O@`S96@KmC_fl=p+?J@Ck;pI(WT z@ek;hKj+9itJ}K2w)+2lD9zj&4%N_l8YJWp06Hvidr-A|4DYr*>!p6zwH@7MDFXx+ViD{UN{Ch1d3zqTg0 zT>fM7e%rGvYp;8}>%h+!xINP%ta0AAs}iRF*!cNF^1gnlWle_kPc+rP^y>0&-Yj+L z^%-wo_+jmvjpTh+8*{=3)sCi3@SXMgk89(fOpo{>#Ai?aA3Jq2wcGw~yQrGw+Q0w8 z!-xIleN5!V-OV?xjtl=bx@VI=!j>#t->Gi$E|1UU{i^P7$JN<5?$pzd?Hby@;*#%| zZ{G0rsd7(v$@^cwTvoBm>u()d_}0J7zrOHuMvv3&-e2}WmF68&AOGU@!N2}>CAiT8 zBdnD-$@|8So!s`oYo~fFk9+Fy!%u8}GJQq;YVE%M>|)KaLqihgd}n=S)}c37oJ$Go z_UxZee(T-N_e|4>^lepEHP>m0&yP*s{I1z7dH>BbKmV&>RL7P}`@9`>^6Xc;9_&4P`DbotD-;YH(rQY?)yaFW zy!HM0sV6F~-f*wiQMauH5!(jNeIsJp8}fO@jyt#asJY}%`Fup_aWC)qc~54;u}_`< zv8&mA`-pkvgU9yyOx{28?h9|$uj;-*hHqKFcjx;IKl1k5S8GlcEZW#JCOC2U!Gc=dR-Kw1J0xY<{zsP;^zXjM^Q+)bPK~UZwAyn)&hDXm zs>%D6=l>eAX3ew@*9@FjB|5X;a}U<^Xndu|hck0)Y_9s&i@`(JjIXw$;HTPw^8VGu zA2&~XG5gVbCmkG8rM1hEsLDS)KWF;RvGTrS#|b&t8m?=`(*Fi%l6b7 z{Gh!5VD8rL6WgzRBWTXFG99MuI+poI=Y021mgdX*sMANPeCm~XpuynI_rDm^@#%l|rBmYXP2BO(5iie&pBV32aHQ_VHoulD zKQcN+HsD%y3S7|V(sxs`+LT@R_qwsqNqmdAX9iyyaO|B0>j(Vu^@r<2X4HNwvBi}O zTVHIw;n8pE|uN^kq_eZEgTbau(&R*~n+?EN8Q{}!K=Nmn<{*}OjZ zLUjLM-)j{=uyNldD;Kr%sL|SvUm# zzUPxM_aEH+=^KCdIJ+&@ebl?2FSQ%G+~v)vIuH4d8u0pS1)Uown)}v$WO)G~nbR^oWnOwIm%sm}5g<#dH7UQPpWo9irimQWG9?#%?on3a z!FU)>7?~;Ao%k(NtiuY1`y>#F8JDa1z;zM71d(&&P|S*b{9gX*y6Ce{ zS92TuQVe6)to@5aBYSQnaVDt2q=&Nf0@Arfb>p?}GTf{MB{QAfBta0e&eD zj$hyKJJ;1{_y{RRu<5#J1kcr62P`sP9t`@qPpvtETykk?=*hUGuGNiclYWZf=Leqp z%D|=Na#_Zu>+)o}_B5>fq=8G*MPrJE@ha36*{@5WflJdxb8fC?8mN`=D#xIlr|#Wj z;L>!_Fj7|)26g)D^s73Ltu8OdRa94-^6@lRr8!*}O^eya%Zusy{ow*% zjRl|{FUmpjz0H{9b^j~t-nXcdl7L-rj>AGm{ z!Je)yUD{Z59#uyr5SBE+4mDjhnXZHbr@I)qG&`iFx~}F7{8GxF_&j_$kC*3;fHVV_ zX7jZfS8wQ&`BjTSo!0%HYv9s!(ZruUU6rTyG+M8wi#~6G&1<^qFkLl<!lcTDY(4YQVT?3Q6WyeFpW+ z@SI`b((;SmT&`xCuwpgtQ>UhJs8f$a=>{$>zZx>G4$vhlG9RX^lK(zT;ph>nV<274L$!D{V!CQaZW}J?xv%S@Vs1~@!ft+KHk#9Q zH38nXj`C%?HrGES3%B6ZbuLt1tJzJ9S5u~I z?xY_6lAimzuI7yE41TGOD?2{p9Jl_Ez~}mMYWb_{qWaU-{4#VA7rEw4SHi4U4)S~X ztLthBq^tQ){8B9(a4su_$7{pD`D84b({;51-qpNN)76scx_pH;Jl37A%a3u9g^=in zHspYopcj(Py#Y^ix~|s1yP9cpJyadc`7vEDZC~}iKnPFQMak=Gruq$xrm{6!APq>@ z=;vAo!PA_sD*$*~UH(j0o6Q@IA=JtjwbtzE8u|9*FEm8}bzN;4*A@B|L~WQZ|G!(- z7YO0$@oGo(cH&iQQtv1OmsXak?7N!j6CGJ^v|~{CgS*!lxU_h6aG+~Q=@V4JYEF+= zN8nw}n>1Y=n66f-`J*%zfO@>>#o=m}w$Z`T2vt7im;27K#@4bHug;9C5)x3xs}qCH z99ltDisp1(^cuCNE7|izzQzJjk5^a5bp(Nuy1FnZvGWs`3|v|oc4J&r=TK}CJDf$h z2&%g07kXK1PS-`vRNfXXEhxG%UGXk4mo*lEdb}*ScQvz82I!CHuRbeU_JKVb0HHZu z7ZnFrvxk;n7N%=fz`JB@n$vX!17Fzg{q@inpYnJux%AM_8Vf*OR|w-mb*9oVm_fBC zZu!Z;rKMpgBo@Ib9bDp&?$~nXY@zdXYfQ>AIqUcQqH) zl{Ud@Z0TubIfilReTQhKYy5l{Dh`^{b;SbjYHo;M7_ez^#hR#bseGO6oV)^_=Ja^Q z0q<(Aq}hBd(>3Mj5PD^6PS+I=yggm_=6tqaV*#k^>dCnD@)gf?B_Dran1M^P`Cg2R zc9)^1%oi44q&LND`MXz9(sZZmO27kG^KuYUijeEYbVUSCAj8(29l%K@pQALy=k9q^TWP77G(^Wb3XD4>pmvI%1m+LV)L3UpcK`yzpc-_yq@X}(gc`N^GJYL`Q`R!hT6rP@jiNLv!UZdwA>yKS3+DWiE%OIbBy0@UG?^^eZTaGF|Q;zd)6P=JYfi z27F;1HQo1@wOrSW>t`T_y3=(fGp^t8TS|}&V^B)JhHvUTwskL>)X)_s2>Lf@=f`zD z{v>@iqdQ%f6%Sm^x~>$at6=M4YGP@Q$15eBP^q|F&6I|2xa!Z{dxGoQ=l7G7@->`s zeTiQguT%!LAN=KmKx$6cl?J@4xjB9*mj-q5TE?LrCn6u#SODtrqF}n3bzNyp*Z7R} z#u{6*jS-BiKGKWq{tvJE7rCyg_g^RrgywWzBZ0?z8NrjqX#~?XIjp9q#sW~cjSR;1 zIeshQI`}Say-6`NkE!|)Jk9C4GJ(f%e9Ju0lKaN#-+Cb@|mtiDIZcH(wweq6!5NQ8JLcv;~wR@LXMqSq_F_h zbx|S0Yz2O0yhbsoTw0?V1}-hXMl-IWX_!-C0vWdEbX^oSSMyc;N?oHFG}Y?oq>dWP zxM~TRS1M0Lwv){--j-l&eQ9<`#ev(r)HRmrdiX@k-D~i(k_4%eU9R;_=Ej+i^Y+n$vYn1|H*4NC25%k1)vnoxv|^EC6*~Qy5oKUA6yu zqOyTYvyDd?m#%9H)3vzH-^SWTOT(!Sbd4O+<~_%{9%EcoAIf-5WzfD|fvXH$nyzUM zbcOsihAMN->1j9}cvrKoYZ}v)T;*&PjRl~dhL1C@1NfzPO80WFt>pRjFYBjNEo)BK zH3N9`=#gKt(tMohYEX49@>_Shu9=MML;O;E{`}@@NK~@U6<>o4A58r>bjo9J=Z1k>j|c-*SNV( z%GXnjt2KTpHen$2{*`Nczc*XmB!HJ5QwM}}Ik^+vn?&UKwV9QL-( zW1EK0FfNN0uenT@HSS{{1D9s=&oZu}x<+`pMH;xYc+F#6dKx~3WWF z6@7o5@!IG_*Yk`^A2WZB>pHQ9vR-p~8d9a_YVJwDxcs(;!Xn5vmfpW=B0SCMwy^+s z%-w)c+TnZ#m79@TQ)2srXTstSU_Ip5P$&r#vloUV%uz_#7Hkm(v#;aGW%1)#2r z8WpZ)I#RVcpdXk1*o4>kjh2VCG;nG8wU}`o0asZ;w20|i-{p^M1}-hXmN2fW;G%lt zd#?~wkhn1&T`@l$p62v;y$HOknG##3;SvVrdpEjQV*#kgYboPO!!L1-9F%y7=U1P` z?y_M3JULz0OSrdfA1-D5%?31G&WP2Iu8W!nu4X#QlFG8%D_73(c*WPAI8ZS#K-aa5 zajgZHtPfvix;C!sC|}fqS=WW?54ytpv?Kp>(~;pv`?(en+&0PS>>_Xs(N%hrRgthdf@_9$P|* zsySWPTfp1Cm)A30W9H5JMq>e}>!Rj?JzW>id^*X%rPYTU85ix4AZ>mFgWl-bHqOAM z<<};q%QnAKVx9FXDJwC~rs>+mbe(=9Ajz?=%?@;x@k-xr;L_st4&$OWn~c|H22HB; zWT1gdi`N#$g%=64KKCWo=Q;F7y9Ub)T$-+T8CSHXYYWr$Mb5UI% zO?jA%Q**j)Yz5xctha664xQ1%+ z+QxKsz5j##LX_}yT~zd3%|&%(w6MrmuH@3vkh0Qt?&brg>%m4X76@|5rRCQS#zh&5 zK$>=M-E@G*>+fzpjRm>z^fW{vgsy$~mA0{iL0g7Qo@wCHbbZ9Q+6jV(`#+h)b)6Yr z!ATnKWLzm)8h*rdjSgH!4KvN@X-IDqK2}Ktg}OZ4rZ>}A0P6ADg?rmH{Fv!#V}61L zJv685+6_EkS4jl@(k3?N@j5-^^$r>fKwZ}-xOX+{@!HLF_1t-Yf}uHG*B;>Q>B>5l zPEBIX>AF4z-qk!bgE-T+$A^wBMG^<8|zqG&}r)bK#dtaCY6#V>tBK z0q^MsE-hYEVELSswD~WXuE{e$B!QaK)9_2+UCndxOYM!^$10+kNLtgT9ikVa=Jfpf z3V6J~Kqz&6$)H*-lw%>3XfLicX z#P6e>)XzoRvEao^7SL*I)~pnGq{&D3VDimRVz zc~n}Y%QQ4>B6)>Q*F}NH3>^q%!T5>k8g*?%mqHGLbX}AVuI8fgdZqllB}7~3bX`9K zjqfbJDgs&$x=}x}0jtaIEVB;|kSu zooBihWxLKXaB1kr1Y0$gKkj>`u{+bzNp$zDRay^M5d1hn}cX+rXviqGIl9t|wRps|HJss=%lW{e|FQsAIHeHYgFfY@Hcjjz|r#amY{{r52KIKoQ>t7?E zHohIScwJ>&MRjdET78M82%xTuUL3ab4p*73msZ5CF>qv_+?XUL+CR*Xs?l16|#gy|cl-No=Bc?a`!8c{qorY4#uX1mQ9`sQ)0KUx-iMBLk=?qQi|QIWZxc1}HK)g`JmYGk z=_i86$vca#xHYcH0IFPQFV40xU_gxWL!J&D{a04kC$g{GBeHT zx~Q(^?@D)2l)W|%Jt3e>t*+f$Mq>e}$Ez~q8i!v=REg>8d^BgBflITEDvZkq1f=1c zQks>ZmE;aBSN zV!G01uW?fMR%cxGAQph>@8vx}OYu7WQ-?{8b=6>8Q}8QwRcE^DA9gd2ifHkw$+##( z0hn?_>v!k6PR_Nqb*$?i#zpHYrLLMxmrILkdktKgu38Rs-FxVV1Ou0rhP4^jIs8gp zwV1Bp!~`e(lsb${z6hQ;a$y9ISEX6~pLVS4UdDA%(^ZG*n$rCZC-3FD4s=bu?;|Jg z<@*@dK}}a(rt4bx=MNh~sHLGd<7xr|0H)s_@f^V8wWmuNY6NOdFJJW-m)N8#WRa4(_tc%)0uI8p70AL!u_L&?Wubz`9 z&o*#rw$YGr>GASmy59Qq;{XGfmWGWS=-PhihxrCBO;=;arN^rg)8+OuZDX!GJq>*s zS5@(NfnNs<;ZRu~_iT)@2GDdhVO;vymoL+GaM$&|x+dHFYU)7OJJ!{LaUB7Hw2kIWSI75WplV!m zdK$K5T+}KDVEXHaKe};Ut-CJnsIdUlZN3%bqJD>bf3;+~x@5Y4VBpf?<;S?B9p>)Y zlFW5oZC5kVz@?>OYsN)&j*OQd(>1GJzybr8rpupkQHD~=xi7lXjzb+k`H4C{n$zPI zz_|4M@@Kk6d*r>Lu>jQ5unpsC1}p&6jDR(rxh|iPb)B@a+cGZd^2>O&VY=eWnmz~8 z;AAlvX7Xk+;-||JQHsK}Q9P0+xCn-Nq}&lrBJKAn5ljxlq;gan7b!<}Sz9X1<2GD$ z^OC^$yGSmXWPS{jhz;~`bfch>H1CT0U=<4*2bYfW&Sd&Y+%8l!)Mp^KLt&^5Asy$U z`b#>F=~x7lPy~}#1T(V;X0^c7HOW})6qvyZ^PRx7RG3Qwb68<${DNE>Fw|q>yT6m4 zsxU!<#z%2w2uwGH!9J?O$?&WYnC31Lv%LsSIj$0%k|wMOCcg+~b`i{lBA6s$tV5OL z$pYi0Fe?NmUSW0#%$o}Hi@-dkFcn2nsiQC}1*VI_G^NHd+*F0xEils*M(%G>*G0zt zoT$jgDVl82SGcM$7X{{|!i*D5>RL)pDNoXkH8YClX@NPQFg40@n#~HcL||qsOxJRp zrkslm;SPauSD1+MoTk3Q>=&3u3Ny3mq3bS8et}9H%+FW}Tg^3cFScQ37V2&xwhXONNVXg?w zT7_v%Lz8eGE;0wx1m-zKvs7R%D$EgqsiiRM?`2|4ofKwJU5t7y{dahg9BrdoZDIj%4t3QSEUXH)}D^M#^m>ccTd6y~VFe5o)q8*-XW z3e&X_$9THP5S|klH-(u;%}==biYv;OWByQ>zXZnHMao%2ohLXS7l}z}$`E*mON=iy zl;BP)%sGMaR+v`JIZbtik>hji6y~g;nX52^T5zu46lR~myrM9nEji6c3bRFEwkS+H z(Q50ZFb4&ux5A9|<8pQ@%yEHPuP{-qIZcMb{46jg7nvHd{+wo;qS+=epD9e^08Znp zxaJ5dG+#73OP!xuP(^=nav3O<`UUn3)RW7079-yGZT31?H5ZIVUhp6{doP zb9pMv1c9lbFx7)Njl06UAut{a(>0jWxGBtFfhngjFAGdz?rc>U6M6wHhvnsQDVYCt zp|JuFdCPpW&7FR;U&tXY$jMDf%1`3Y+cP<`Y1nP`T;!T#IpsqNxoqWhU~=%IImdDu z3OU4O8!u}6WA*EIOeBfXu;Ss>&Pm#v&GOimpUo?TDH_H!oZD?g&JZDoxNPNwGdY8VoL6TL-{nlsLLrB^Y||%#$&u+Z zwbIF-oXI&TP!{ZNFI@V&!$4mB48*7 z3Nay3e4f4#a|jr38=48-`6)1*MlXX=EX*?QXAeJgUWNt&ia4(x97SBVaqrILQ0+;s zQPkmv&g3)|a)`@TP7fP7tKG(5cP1xP$RRFUInhjxY>K6=cR{PevCZEvf4wosnVexl4sqGa>CfbdhPx@!&$EFuIdYc{;g#%mRSvnHRiLxg7iXUN4R-BraPygP5G5Le70}T}1!IvHgq`a)`?| zUW1t&Bnor$KUuz!%Ml2Jw@b(&F38c^>O+_uS+8<7$MsLycuqlFwsP)ga%4S!BRN}y z9OAN#S0aX7@PpGDZIP)s4~rq4 z9k-d7D30O8zT=tMSvV|GoE4c^cy1)lAJpy;K7Ry+f{lv>B|S4IF)=bMgeZQhU2JxKdg_?)f~;gj*e@h>*zoYo{FuDq7E8~dAPWv`8b~=6Z1W&E4EX+p z_v6QS`G*pDm?cKUnH`g7(Vhi|CB`y_#KbThd*`2+otr*9J&RJMzYRW}A8JkY^Y)4|^HX_P&b(oz`CG9@w62|1^TQe>G zmY`spm{K&MAU>O&CRkDxePp6SaB;N-CPp|4G72s;3%?=QBYB; z;IN?Jo^)avVx=GdWhp|M5EMaaOF3NhA#ySTiuADb3hs?V`J9}P);FYwbqt*Xh@`MN z=k6vBTH~dJa!Sf95`Gr8)*O8Y!bWK)&K(rV_n!|$P>_@J>h5^>$P}H2k4}ZWLx~6b zrW|A^2;Q+EL{SjplX7t==p73~1gk2dt*QATY3UiVD)>*^GO~k(qgVRyw7Vi8;!IWk z%DXd_47ERaJYwr%_R!|sg zo5mO94!7RfAS77x?{KXWg~Z_13c_-yYnH;mM5kws%)2vr6UE-i+OfAREQ$I2&{>%8 zoeW!07}_&V!iJun!^WV!)^U3$jp%HO_Md$A} zh~jN{9GNXF>ZZ>&M&*V+U=%uxNjOa&Hqn~(y<%}%*uOzEn)d#!EtH_>d+Bf4TM0k9 zEVdCK`55*{86A|0c-@9*;Eilohd9<;B;IXMWG^cMWqS ztC{5HIw^1?>L zinB1{HinH^CFNUXr{Ly=%j&l9T=rW|EGd%N1_CLMqQ6za^q!_v4fNBh!do>xRQaqW zAK2kG3Z)c4W#q@J(ZG)XHqjVCv*u%vl}3I=^8SY#-YQeXcu!1HjwK4?dl7t`i079a z=%cYUbgJ{y*>J0l#W**;eHnRc{lN{%@sbKnPtF&kgEph5&Uk}@Xdp~#A_*8I>|<~6 zFT&CIp``bhFH4e=hk&SoM=AbB@y7Io7?$IM+~Mh?QM5Ty%5WY;Nky8FmOf;9us|6S zw6YNk+g^~);w+_Dnd74|#bt@4d_=~GQ8+#nY|YEb&dReoPYX6qE`~Q*+ao+TJCmYL zqKcilm|`hO?y@GI7*;5z4qn39C~R;+@5m3TWDd4aC_Q;J5*&c=;Rq{5Rl2 z6~wGPJRPm}sI2T2>+Cn{0=Y#$Z znOU#w#uEV!`Ts-lqS~t169#uUu=Xbw90!WB;J+hojwU6X$E|o16^>>62TD%KCN%DF zP)juNaficN;t7(wBD^IT?z}4kjILn`=6>#QkZmVs^x>9i8g?cE)L zF6KPj9Sy8;$o?kh3h!tfZgNi1VVG(7&^XF*Qxk#?HJ~3XMm29`lCT)!>GjHnAmrFX ziDs21LsEDJhx%tUX=kh72vJY^p6QDQHbgPr1HxQ3XxY!e=&O}iS zs5gL1HoxgiGOxkeDDUl?P`!~t%3juI%Ik$sPU5mM)TsGwuGzVo+cNQbgE*;qzgwM* zy@4Kjt@H8mTb-c2ks>~&bK53uOQsGpYbBV-bu9beKb)yD-e$trVTdUI$n@DYsv(oHKulOkb(U0v&KA$YUm3d;Dk3nw7th0|_ z5X~0RoFmN~7Jn92W`oEjHYKYq-MPD?8h zyE(`~VUa#QJ#Qt0*c4h;UO}!kBq=8;IXz##z3=X5_h)6uI0Jr{hncL4){BW?^3`2; zahU0CXsoMvWA*mcrl?DAxq`9nVcpiS-FiJATfjfbEwZ5THilEwTx44|qbj#ig*1gQ zdv(RX!6;+_FVb?n%gYOuarzjQz7nUr2(_lh<>XnSES3cI5iKwZlk!0_~ABRm+_BA-VsdnT$=0TVPeNwY?A56-y!;djz%9O$SfOjpm-Hcl zvUA3u(J2z+7MfimX>LJ+h?iXYT9`$*AoJEk#TFv@1ZAWT&qC)I-@eBOVUGdYjsYK{ zhw_i93xjIUGT4e%5fI1E2bwI{8N!-efY1BKBqpa>lSd{dXJ?O0w_4g@uK<1X32RPv za+)bHF)oJ|!{#O6%MNVSU_qZGFwx1@6BbKHOPj z^DGkY7ZMvE8yplFVgYKDzDGhpUtT}ZE(^ipS-RXO!SFCKF*+(XEHSZf64t@_1)@+E z@>0Kyc4)A)>8?T(8f}S)jf)5gLh_~r1_b&KPtOnRn2WgP1^VY@7vv^e13Ttq6y(tb zOs)!VaEv7+DkeBMDmLE2cc4J31h(b7N9uyTE92Og7pV7}E zcd;0rn1gDVt(`~0YnwLY;%n!`tn3u*s}aygf534pdhNCC9NGmd^`Sj1-D6{-gTrH@ zN*H5shIWsRiHr`4EH-D+{LuSN4*QtA3$15Vc&H^JJ~TcqG&Z)_%DKS>M_Pj8BVyx2 z!ouvQH)>=nlE)a-|IljQ01KL9dQ7oZLU(leW8y<%?1wjp_55YI36HSE1Vx6&hsQfG zCq^FFHqa+D4p(eo+swpX1m8cuHVfE7mkyv+SgmVW^{cd0e=3+9vw3mXMI{QNb~h5%#06m8*17utxTajAIqi ze_(BW01aQLK^U( z=~~}aA!JFH&?mTiSjgRc!y}@@q9ag)<>guNwT|tJnBKqzS$SwmSyQOONN1H{ zj8YmBV(Aeb9U2rF9ByBLzJUV?Q=GxEmave>nBb5eq4qg56IH)K1~(+y5*phhBserK z$`KDO5oTeG~I;1H6+{;)jcjUGPZl9BUW^5 z#fWWT!z?Vy5*ic}6%&s)ufz0ZuZW1e++?1%fo<7PD8;##AEtPbYS<9!F7D=8I>`J% zD<>vA2!$IhjuN&A<1A5;;c?ON!49$}s~}S(4|@+ML=6lp%$#6LXhcLzXt)C-&XOM` zG6~{MuDCH-A*fSGt1cYeq!S0sekg(w39u5M{N)Pt43h>v;4$JPsau5<^ z3672mi4N)Rpag+6xbTBb5=p{X@HP7=*`z7!;P53bJoj!|lEY54E}i-=A)%JA;2!Z2 z4s(fOmX|)(nwU@V6BSKh+XTckFEIgo^Q324F$Rq;Q!!U<@krkCB$=L8mK*HcU}@7Q zz=GC6VVmV{4lBKk`5Pr9!V($OJq!gm*nU05vLhr|)u~At=_zExH0{HghI`YNiRl^ET<^ZtT-qJeyLHEwt=qNqZ|@h-x@BuqtJZDWd26n9TRaG8-`1~# zh6LE!&#zrOP_}OE*P(+yJsav7?eebaWbX4rs*ZFqZ58{NwoJ*zyz3~d+=_H2fQ53S zY>D)&WOFtlp?AE5v(&J$^11gpQ3ZGwQ>9>W)?aUqHJS1OjQ&90ai7s?CkYak_QE~~ zx;ooA4Yo-&c~^=bs-GQ5Ps-szBhdKo;B=+oSt>!VK_2b>I~p_#1f3&!r$M(2G_yYB z@=7_7*Bbb(f`(Jt58p{V{0($pe#EI9$*YIQ?mML|?RGBD7mt^L=2JoEDE->t!PlTEyT`daI<}}QXi^28qwrk>-B{3M zeahvz!n2pZDZtMZG@R0YeBBVf-#~ZqGfw3wKd{lXsnK4OX$UTIj>1Rho;(1W75g}y zBm48g<6i|0r?ekFvX`o#n@pE+k#iKj`gqpl3r3=T?B(w6An9@>lDE%sduKH2f^mm-D96WpBqxxkLXign-E{~2^ zs`CpeuMp1tr<`Mn1;_fkQDa}?h{@hlEB zQ9m#;lNUUD@)kl~pyZj94KM8eyI-p!>2io{Iw^Kg7pmO#+>0)j>3lnFia~! zb3)KLif^>Y(E>k67wLFXuZUQjd^G*A4>#Ie(k?a8Av9KHn2c|qqWe3WHZ zL38pqF3(YZRK?@!R4HiAUjC9jHv!$f=Q*Jxd5!Qm4m1UV&QW}ifo?iz(l0odN8wu_ zXgH<){Ge=I4Z8UhP&h~7^TD${f`$>|$6kDo0skB5_TfYla*pKf!ZY(9CetUl$dR4e zlQ$O`Rrxa75?2_R!~CVQAkKm&j0!TGqxAb2&jx^|-d~K2)kF5|h0ZGq1kDtB;lMen z@2Nes4K$(GIh~{UHU`}&(7fD+&`LPx3$xBIR%=l?X{1shHeQ}Xeh2Hb;L!Ee(i;is=W}Q2Pl66+VOO3H#9RkWed-9qIm(amc-9*+0#8LwV&XK$}cs5bcFhcw|3g3FrO`(Go;T*|J z#Ip^csTRTM9Ods3&@}-~De4%)Ig&?bkF^&xj1WKe!bjyd2XqVR&_Xyz@~D3L3^Zp2 z9Z}npXTpO^pt;oDxx5hYH}2tL8i9+PqxywjYtulpB%0GXvcG1KaSAk*W1P#Q^3e)3 z39+2cQGDYe?@`cvCFmTzk4WA%(A10P@*IVa>e=Cf1|W0x(ytuEj04@Y|6}h<0Hdm| z{$C)*5I~4V#C^bsAd4gf2*YARGJ!}olCY@JAiNRL$(!w8G-f#a^@5oE5YJV=nTS^% z8!x7QMHBOUg@q{<<1pNqJehueNUXDK>Q0msc(Fd5D`2@xF-3?_wj3 zQ$nNE+b}N}nOMus?G1HmZ~Md=Y-{J+fUR2%A${X9HvxwmLOs~7(h+D--+8pc)F$-s zq^_p3z?ZYK(?-#5cnD1hdeHRMmuo6&%k`Hmhe`LAhMT+&eA)zuzusH}rG zuRt%*=TB*93U)Tk?+Qnj7EWtGjtwOhlLD&)Msr7tF|pY*v3!qcluvA?60^IfsXdrd zo)WVm5)6bUr=GKlpO;E}C+T%*4xne^Y2}`Yon83IW|wE;k^;O-Jri4kjmtZMtYCB4 z+uYuWkAb2&l{KD;)h&3}O!Q1FU0hRwzqQ4s{(4`9uhLgvd#b;*ysmg|g|8F={`tjq z{_=WXZE<~dt-sVachS6gLvc#Md&q^KITx-(p`yoM@GG zCH}>}T1N{A8~bojM&oz&gZgnFWJ_2@LKS_-D*O;hgF z8R%j7T`+aJb_HHAwNU?_q1^*CAD?|K$a z%Cjok(~+!Zj^^2uh0*T3I*6k_D@RTQ6U zi~hp%6$zskFV)efA@>DrodJ}2z5JpwbiH<*PQ|g|#?FYdUHNmoUW^|-0b>HvjpNk5 z*Nzmn9WP=z8(0`OcKQ6q&X)Fo4+?N(jpxL;DJLOiI;WV4>emGIa>8V*US|BXr1A5t z_+@cx=HLXc7Y8VD;Kc;St>+QQXC_QB8Ae&{qPqG;mHw(lI6P8Z<*Ng`9+>^zv9y?A zI#N;UFRQ37u7`a{paV3tuD%uunFSuG!Hb~>RM#4Z>)7cUyl@fpuG%VaiZMb59iW4# zkj(SdT5wcJ6+5@Oy24jnWmV@u4X>MDU0ZLA)VXA8XvzHI+Ts$FVdXQ(45_ZDuAP#P z{v{0*{LiqX~xU0N;GfnJRo%!3UY}((;me;~1UIFb%D#t}Cx+56~??M28R8 z;nX291(LF}Envw4s|g2dU}ZJB1eHDG3Pew#53BCo*zM$bsyrUm9l)Zlj_vhI?{~x9 zzuo=8MD`)NrqIQz)FjiwQH~D5x#vao7OD@`(6U8UCB%_Mn-Mx-F($;dt>5R#YBG!pm z{~Tbz*s#P8_V=MDu|J-~RZ)S;Tnqgu#epOlzwL>yJSh556rEBu(Dwu)5nj^6) z{dlW%XP^{p6)+vqVuv4R?~E&_k1>X3&pM1X=i?7{bo>4G^Z)bXW?Z5!;tI6XMM5}v zP=g`I>&1!fHh(Y@=!+)um<0Xyvc#z*qeIu=?Pnfgk7C{N0gI z*tiI>F5?*J7;D`Mh$*}r{NwHzTEoF9x1R0^qMTSVOzSEp)H#AvVo^^>hZeMZcYQrH zm$LFIs4J=yyfcp2tUI+1Q-AVW9d;c_{DkASMJwtI(eayOB?)_h(c0eCh~scg!A2^4 z0v#sMylDzbMiR})*m}Xdj>gq02?HZx<2(fJAEcQdOY0ZDC|w0#Pkr~O3zcr=FRNPY z?`mzuy*&P=#&9rfP*O^ytJ93MXr%5CEP`q{>pGDJQ;fwJ4y(&ceEzw`bv|_Bq1kV8 zACY=oG+yqntuxq-J~)=auFzUvT@9=>wBJZe~+p&l9lcjdaU`mZK>#4^fN3Q$ojBb8%9^A-kQ2K9Zg;B z^^HyK0k5|tIs~elTig_O|8{G>3C33pW{zT_rNG)4U%VWe_T@6PiyqE7p=ZnlSGf68 z4Yi4bkxgSq*mL53BP@r?F<34#pkG%&@fJbP>EqFWrWrNG_48p7!7@R$zn=OYNA?>r zI~{CPRxkF|pIYPdmtY24U8!`%3$WdnmX9*59%!3Iaowp^C4S^C)3BSlA=9X*F+U}R<=nUB4$iET-#sB*5maZ(=>jXqRh z)c;}yAQG%k)*IcZ%>U%=Gd3K(EvZUioQo2-f0-pZ+Pea!-?i_ho0>)PrmjL^KmC#l zbF{Jw1+Ph7u%l~QlL4(5xqcg`A-@auUw)3d9*n#ogKgt#b}8u#@v|{I>Aorm@pDh05##_7BmRR3*C0O)eER2;9D_Uuv^^O>jEzWl zmor_WMF6V{?I-1cI)Y~(1m#nx`cMBYtM2I7JJE~_bTj(Vv6If$QtHz&Iqa|Q9FuW^ zo_qj$@>%~ETkh1)?*#))bD|;1&^3XZQ)oDEZV5EE!zgZ#tM?R)nGg>+E}59NCve+a z-M=v{dlYpZ_3u?@C(=(w1Kz|8-PHOW?Kj6G(@Y*`h0`cU2Ji1f1~wIUB(i!4SyA6< z351)u=z>)!Ox?Dihuo_Ramj}NU1@9ym@lmw{Si)ITBTA`BGF%d4MKkRKZN8izJF^% zI)%tkP&JqWRUN{`V$P&9k@y`fc}9DU+2q-#%;ZM^9rgb~huWU&Ho|dYTRj3>CmM0? zrqc)2H-t@Hnb}pi%A{modskCqJ3f38=H1&ya6o3ZCj~t2je*WV>SW{G{#(6@&&vOL zmEY^`^RL&Gl)LOou-f4Nu$orzY+Fsf*naYVkkwoxCq!QlmiT*MOTf18Bk}Y5I9y+% zK9M&!7{T`jC<P^)pw6oJsFMdtiwgqrGb{7=0Ipx{?s|f5s36Mg*U{ut-@%}9AhZMm_coz zwXz<&fikl*u<0(>&#FWV%Jm0UM?#Hr*F*wge|`aOVb09Hky%Q9^|M@gyEF%=mBWyN zdzj?&4A}6@sy~;k>UmS<7?p@LcQ|l>BQT+eAC1SCH~cFb{WzTgPcV${Q$=tkcWWRN zz}JOmVXg^qdl$B81^nGzXd*7h_M9k_O`*>X*s#%z6Mfv!gKW5?70BkGSC6{^N=nu= zw_`mD$C4GPdvR{Rw!Q*KKd~#n1jiTaa3FzO&uPVa3f0#&LzUWtVO67OZR|bMtinp9 zdw|X6{s;GF`@Ip*?vXLRsmka@xsQGMMbwqH6G|HGq^Iqn%F zwT36D6It3o9OVc)KoIes!Ua$%E!(&#tCnC=K7pnbnYVFjDY+t3sI-v6WTQ;}M;U{gzwW`@)_;XiW)r{x>x?ufSR9%tqYARD) z3bm3t9W(1}>8(y@8cLl3%_Z zTWlT;H)bIE>nTU~db{LvG68?Un2Mx->PJ$p03g{MB>O|WWHATSadbM*-`E~u!f1`l zkp9)ZPw(~Wda&icNimj6 z_T1Bt1Xf8WAmLBqCG6;G!7L_P0;}}H6e3zVPeFnKqtPKTtJP;0XIXyAkYIB_P1^G& z$ix>zni>jzfKn39rSl4923d?bVM)CrOkH=dvvx^E7sNs?%Jjtx@p>6v-r3rv1<-es z7BUB?mt_*;HX>ADf?3%ZUV&^lUHu$aq1x=RMhRd;IVXn{k_pi)_Z0(b(kVOB+(EPk z00}fYT%W9d1#^@!_$rcv0yAnOQ1j)lbGlUw{y-OtPNgBjsUrmTG$0pDv4nUJ$4JcR zXldwUVPXN;<2+mFcxkdGvgKY2NKv1VXd|f6Rp9cYY5t2qaR3lGU1_4+TR@8L| z0xkSbxtd}A1G2of5hvM{Y2^mk%FAketD6IAEwnTkWAJgA_TcMV3bnrh^R}#lDJ;|lW@%T*^dfRQ38zgX$+RTb#towsX;?q?p>;AJNbF zNw-d%Cwrs3XxVAUp; z&1iZ*2S%rGH+yfqWLjj?uJ$9R4Dxk~2%@q2IgEqUFC~Y%2&90zNza&xKrgyXGRd02 zo{GZ`NL-d1?W>l-7nO>c(ahac5Hm$Hk!Ws`iCZ6` zFNm3ktiI-uYg(L%Wle@pC7a}ACi(~E#v_zyQDL?OpnA-8ZM3x{h**MRSOlU26Q0KS za%7I~ltwc$9))Fr{hhI6ryuo;+c_vy;B%9adYs3XHQ)_0WYT_1o>InJ4yAXw;W$qj zT{cmJfAyXQ|GXJ$RQ@%Kl{w&=c|DDx7M1#Gv^e=(J`eW^WM(hN#LS$RmEpE4nNe{$ zh1&B(lid^%lMagB$kJt%VswrnwaJlYw~js0 zuhxa`j}Dz>ShA4e(=K|#N?+>6MXXveQnOc{2rsKE4Td6XppC5HU96#qR&mIxUm=P~ z)Z&&F5S9Yu+XQL7jUkndp%n-sZRbWO-Wb_%SCxW}MCWh9ij=VgZ=-F^-_ ztAM7)7C)DB3~EK6nNUC0g*yGANF=DQ6H&oOI&y38!dFyVx^O#cK=k@-N3a<}>?}7! zSX#i;^i<{VG=nTKZ!J+4i&-&23Vf~!W@a!dbT#9sF;0#+!2F=BzcaAP4{O5mNSosA zUzssFaSdOz}3P#$vz875HscN+eOi`{DipUdXfk<V9dQ^(3@2PAlLfhQr?L5I1s+o{S%! zrM2rh#v}y3LhTmfIBwt6V%U_ooTXlx)VK-T6HBG}DH3g_BH2b3BvVDNS6t2_&|65d z_GoO_fZ7|EhgH)B|5)=Hs1XaI5Oly`S<(H|)@sGMfbr zE7L=fHDr{*D`e0Z*5Vz?jYXZ9KhR3pLO!9H&*1F;-Xs(@g|Gb@Ahk)h#4&4%PIuHy z$u{~Y8#urSMD$h35S@>eZF0+O@PB}_H#CS+al7iPjS)4*Z*bz+tvrx@Z5V=_6>jJ4 zOetMWVRWIyN50@f97@GuC@=yNst%2tOfAmj-hdBqhZ2-&5e|&$o`Eg`iz_Y|MJ@<- z(wai<{}%PGmS7l`7-eB$=fB(ugPpFEHrW<6a{U6`Mf%FzHENcproaz_xte(lbxOWJ ztVpPfsf$u zT7xFw+Tad#agWj&*%YB;IYh6r7>t1Ybko{oSaVX4Tv1fw?~n1es6aX@8G15XmQaRH z$)_|UYCpuR0<{eVS5H}8fcp6Xd%@X9TvcO_@i5h|L z!3Ld}O+m%#6ZGsj^TAbSgUme^s$LhOUP^4JO)tt|S?T~`h$1)2EpLqxHrn9ucS_RX zFMsMZ(vAZ96Og36CAbpwpsL)lr=3JoXDHe(1ASU#P(n&};9e77C0!wOJQHhS#g+{u zXH?p$woRlxj3!-W4KprA9vhR-zSR85y#dF?&iz|-bRRx3u0$;su(H6a9xB~k`-`uI zLj=!9jRwY%Fp4eubJ3CFUmw~gbPyej8ll+yZU8x=-KL;W84G8!XO{+A8++O#xJ{a( zuogVu)qy;qv8p(iLK)>;Kv`w26#(^1?W5z&>JuknT{PRH$wcwX5LmNh5Xf&)m$_zU z|1;X5%OD(Nvc(C|xTu<@ZT*~rq35VQfrU!+%pjT3w(4$ChCMKT(w1JJ;0Y8i?9Jnx z^(1#%Z2=a$!n+iF6noPOf~YCyZ{v{w5|buf&Pq8$IhS?BXclBY!i+`)lhP{2A-2D! zveY;h@i_i2fy!Ri#S4Aa=Q+aGI82%UdyJ0ivMa%k>Yv{NQPeschgdZ)JAqY}GAKv| zSM0cL-2G@RoSM^G$UDjdkCSlmmLOF7S~*&B!l+Er3KS-Yb6|o)YBymoc&v)UX*77ru?iAL7BmAhnd+k zs9rGJ}@~cBZOczCEqQZ4H z8%sfh*3QE3H^3OF7OISPR_CI!u?Fl~qMA%agE&&d&s|`6KRTVvhoNjjvt-9oT)c2k zqgwuSrNAHPAiBCi$Dy!CM=*8Cn{AMYk;bm5T3aG>{vD{&yCSLrkyTxx73}>==U7YC zrMPoBEGk;hW&i%8NoeWyN{$bN{fNXYX>4xOdl2+EJQgCmJf5s(cYYuJEvZc|uTXLS z<3zH>{j*SeyJE$V?W%giM{EFGc{RDLH4d zq9<{Rc6-ts@<=nkVXDN;8>)yerR4K_YY3S*m=-+ z$*}0ws7?f`+%(!1h66MJ>DWz0|DZK&23Sd5vq_b$C7#Mg!>ih@(BtR;YG;qTZrq-8 zgIz(yvP63z5|DX&1(5Kwi0+pq;Sx8y512!cEU8Pf*B)?CcDXJHlx{_tV z=nw;j?vrNMi*EhX$mr1`Oj+rbP+MsY<^~rFc)Pq$v;ruSuz*H<{Qgo+7rykiMwP}p z$)T|M#jMPBeM%%*Rv$}TsHW)wn6sT{p&&Rkb44-U^UtL)ZuvnaDZ;j)goGn7ES%S1 z)4-n@$C6>zErJ$tIQW0j1EMG!?rygqOZ`%}gzu9o05i?^L6sN&LlqciF_^{`$or8q zQa$qF+*`uox|4$}7H_-jdYa6skm`s}o90nvtx>XpVnlyqhK7l52#*Ly6=N)D{gK`j zk?gRO%YxD`t5^Kqm12&2-E&gRKUMr2Q-P^J{0CER{lop+eei?q#<3h?9NPAy_;tA! zEir1&-t;OLm7Qw_iBJ8fcJE>Ao#V!{XuvoBjT>N7`lyO6V^b2@ee!U8l9Tv%_B4sl z&o=^ySF=Cy5_b?&3zDaQ;l8u%N%9h-Gv!~t4`(yVr6wrl7F{Cm8}$YQebv$ zy-V=vT}%tOAzdvPj+_-!W@RH(1W=lGhB(x*VN?@{hZ4GD+iun!n-!N-Lv^QWGMa9T4WHV4-dkdcpQ$HcO;E1K79+mowy$37p+KQU>{ z8r223(tuxB+)@R8j-G4=YUYbcY_5;+h6wIpU6Q20czczYZ=9XAoShvK4=wm2v*uN0 z8sqh~e(U~PerF1snyr-!bFrIy#Q5rW&G@az z`*)^w!a)LAe8wggl)x>0WwckjW5Hw}2&mvQ;s*07cw;P5FN_-;Ekx~5#wG!zUovd9n)UxhwLtL-<4c5fsT1wL98&cOQ2wNTN=p++LUnblS}*E=y1D_s3N?S& zW=A$Qg}8FDiVJ6I^5aa9%2x=SDUufv^YvVi=_%Cwh=0eLJBdXb`YwxX4EYEBj0z@KgWL6DFn@E4j$i*S!0$_(Yx3s!phqmH{w13{ ziSvcPd2_f&-C=|VQ~|VvwS=Hfu+gPIl1P2<x28|OrVXnn!vo{w^4p!3$P)!cuStKC+HYTMX=3$IlbfuUS>%Ad2Q^ZZzZ9wdJcr&@`;m4CHMZ+5N$;rk+-{SA^?67+bm(>#$=*xE%l# z=H3x>Aaha3Qk|`pA$B`{3rjJ!%}RV#(kja$>oKfEyqlX8XCKOr>zv4-B0KPI&fq7# z3>;7U;dQOG_ox5$4-elwX7{(Rx$I^TOTp(}`Sg|fFBP79!>xb4yZPPwrWp7ZGUMNI z=t(=@Jo)&mU;o`_BW7Oo>C=Ysih>uN*%%o0&b(vZ{K4lpoIB&-pW(Y;C}4Qn@G1W_ zds=5k^Q%v6eEZfr9=y{q&QS2ThyC&1z;iQJ{w#gW11r*h_dCP*mV&o!d;A;zQ%)Q@ zrF#61lNU|-iD5je;NQFB*;_w<|Gdn~T(#ul z0pD6^7$**3xfuh;Pq}UGRV!}2?fu`iEc+&gw$l`R;+etke)!0%H$MOTFNgl}$t!CN z<7NfVE&1=mfB)1aZ)E;$=w0t0T~T2epD6giGp_jP{F*Tb9<;LNokLdT+yo98$o#7x zyshd_yMJ8%{_WRZpLNIa-!+WyDR|zDiT6}CAM)zR6JI&|_Kc4}pDY*|ho>EX#sdRx zDt@);UeB(o?~d{O!!Twk_;r8Z`SN}9KR#x6<)1J4Wc>9X8paw0f8^4Z2ah>n!fW^c z{l+z~P5jOShH;02k1l*Pa^xkiJ=A=}N9(pdeb%*x@rHsI9~!6_bL@p}uRT8Gq8E-` z)@&F@9l&zmT5+DtO^pqwi>``quTHEsvk{i!*)-_PtBN z-?`?KJGaa@=ZS}|x-o6?Zx4IZFy2=1N4~Z5+6~|O-EF^EddE2ro>y>?VH^h@8lIN> zr=d4>9QxMPE1Tblyf*Ar$kH@9+c0zPIHi!?;etOAlK!_vIJ9 zckm@Ye)8vk{!<(9uuZ{-6uwj6vN^Bfcb%(mf9}$a5DKFXWd7|VX5N0)Z=M->)sO3Y zUmEoMd&oz@n|^ukIiH^Ly)DbmJbd~yOFw3x8`EeF}cn z2Rnay_gRn6^=>XX`6%yS??9hX@CA=ohkkzZnytr9egF0EoV#F?VH`M!`M-H>LEe%z zV_w^I_>kW|Htf<8Xi^I9A9mV}1%I3I>3|!W?znRC>EP#E75wPOk63oW=tZBMGwsUY zGr@^>8OA#bo_XBo8!x!I;h^K5_w@{aZpQbqQ6!7`A3X1+5e3g4{r8Pq4jOg&h!*g9 zhk|2!%_%2V-1+W_-wSSCc;A_*|E&tX!*fK1anaY`df?fw)|`C8z{d?^tAhW1v+U+|-zZ@u~7pB5fHb=7ev;}(>)3VucNSzF#N+?7#YYrc`<}W`Vn07k)%V!F{b8YYJft6=Xx&4I;ulV|b z1JUoM4`KdST~fDm)8Svca`FTI?+;!v`(?wpP{GsBd}Y_iBdeEe>bd!?u~)QhH;fMz z{FBYA`uf^8eq(XP)`#An`TiQim@t(2yj=d-^*{Y!N$IeRKVH85$c5mC76mVQ@1isA zYJcz_qux9Hz9DaR|Hd$0Q}EWy|8mb+LtkFHtbE>m_e3&JHH?G7yTj9#j{o|==MKHP zbHLWGkK6Ie+Es>8q2RaddavWjdmcRhiGmBZzj4QGpJ80D;2l@57)_DvANy$XKZ^Orq*^fe0~ z|Aqgel8o0oD-Gir1%I;Q{2A}f^j7`tzEQ_)&d$0Gc*tfx7hU|bUtGBRhYxgo{OW_( zoHZCcex`yCIPvz-b1ls?PkAhO)P4W8W1V4Kt>C_Eul@b&U%ln2!s*ZdDC3}qF_^rd z;CEIv&$vGL=1GU&U-?yEVMROS9_9xNKefX|>G0rLY^z(~% z{O&KG&bjUI```cN=o?Y)cNP5U%*NG&j(Bq6eSPWvmDkOv#pfV_i{WY4Za!w)o12fk za@o;WPc1CmzSA&1#<&w0fj`aOhVD?;a#+JWt=Nkd_KaO!IBi_RDjbyPS{3%Jzz&6m zyvYs0&gS->mH@nyCQr(noL>O9p$A)88k)OsHwSJ%>C$$+Z-iGDD$ixs1 z0EQc6x97y}_MR}`hH$94LAJa!M6gkEasv{!G%fGyM8bWpjM`Apj~Xn8{;qV5{ZY7y ziB;I^7wqasEwJ8(oraC=u(Zj&o&89w4)XLPelu=43AFbkfr*|}iK;d_BL97+CH6ro zEbeng7G3sxjw(YxTHG33zCW65)s&Wl#2I!3n?qgUuGWZWWiX7L!5-LtfUAc5$$2x- zA3HjFaM*86!^-A{2rOFRhK?}2c?Fa5rcKJ9J~@Ai)te(~TZKAHnR2IX3U^ab^oN7c z&GQ;y_ibJghK;JDWokbXbNY>gzWqoMgV{SdR%98CwM=afIW~vc7GDUY$tZAek5}7i@9{hZbgkH0pj)> zl~;G*v>n$N`cdVuK5WsCBqsM_4CqFS!?5UCjGXHDEn=`0XI?1H*acEe>B4cyAI9}n z&21PSxg^++jD)Mvel>jcBjIxOnTVD6OoYD)T!NHeG+`|}amrYd#^JW^X5RMQkH#tW zd=0K(=xOJ^q8!)|E|uC zMotj=T`Uf6M0h+lF$(ruw`>-++jpK}KTTZUe(;{^2Kyr?Zno#=9r}U(sA%s;B1@w8 zyEsW{O~{%eSCvhOW7ySp`I%B`R5$qh7hduGE4 zc6<1{z%$-+rUC#?fcyx{k3xjb_IPshkq}|i^F0$)1VE+;WLgwbpdf{lHN@EW;%u2q zaaQK2fG)0JzZEy7z|6~P-jsqucl)MHHIcCI4YW5$H_%oE-9WPj`(E5MGb^ioc7jTA z(@mW3dvSS_ZHGu{;a_7D?B1th zjc~B>i1uX}xv*h#opG?i-7@rL85iUj#xez4t9@BUH;zd!P_T&hWf_;lw@JaS(7r6= z9{4I0?5En7Wjqhx&lK!M?aMN-1ZZ>`haURXrUkk6yM~`~=j34{|1#?8J}jjerQU{l zFlF;DyKqCDy0~Cs4b0ell_@*E9#R@;>RE1Cf|QZMujl!bx?7rz4;S^lyY}7Ey2VTS ze3><84cLaFjI~c@uJb+ASNTxiq9Lt)16tRm_4yw1pLu%U|D5pzmLZHcux6X1YWoR( z^ox1i1{1vmKgJZ>FC2WgYaT;#b^gE(>RwZVt3M;5 z9$X-3ZJ*G44vsPo9?pV_@G^6vNFL8c2V-;J;A~c56oR@dmHh}S`h&9>>)_+Cs26I+ z?=!QpHiPE?>?1Xd0Y-JU@ew?%kNMDl6IMH$Cvd)jfWyZ5X%>#|4 z+Beu}(7r6=2@AHxg8kltZM9&E7Db@NSp(Ys04PbK2{J^Z|4@McoDltJnuQT~!Aef_ zuLKNt6*$n(G;GdMc)OzL$CVL@F<*qZeEIAd^9r*usAais)IP6K`yyP{=VguBITmW^ z6V%d|g-vW|k%B#>eOZQ`rTZ#}^bMbxeSQ{j*_XMl@}cdSVCudBi4F5$$-GgZHH zqm4bujkY1+5u*4*yuZO4aiNWASUpH%q1c8VmFegqw?(&xAA~ z#dx^roJOAh?XgHhpOA*WEMp{kyTFdpJ{yNC(hRBTtIS;3SGh~c3X-ab=r(K+i)O?z zbIVaodXn-nvYU=xz)JDj+22k_ZVS58MMtI~a>$Z3PC71DR&19Px7~t~jB-45MH=s0 z9x2j)AjFcQ{~WEXc=q>e!nnGba;dspPZcd4r@G7U*I8gC!Q6M52V^>TyW z-D;|gwj(uh5AJxqsm4r^YK34O)ypV3SBy6C9rQ1(PTthXR}GOS;P@H1RkXBt-E47@X<9m9on z+u0)Xw3gQ!2bdx*N7!*`#0)~L(`1Z5_CcuH5J6N0_cVl?ztb%$&?i)&FU$BfVhQY3 z?Q>H`4?-N%jJ^SV*tG?Bc;BGDxw*Sv1ja3S#JxV8aAja$vFS^P&&~GJ0V4qtNv3BI zcBYE}OhW=ts#ZnWKFNi85J#9Fs0+yA+_smR&TtV(t+?5ocC>=`y2Iy`VRwS1#8G2t z$KgTDJ7#3Fd-AD5N_GK`9`Ph!`D*L+xq;ov|Zz>@V)lY3dO z&j1u`(kIxYFUxpRhYmK#c>;6Ddf%>AqHY}pk>>XJcpHuMrFhfv@^Ry>7ce*8n1=Pk z4s)Yvf8%Ya#@i@lj?2$Yj`ZNC`LKL9&c_&rx4$%$_8a^~YTpQl`t zl5-H?a|s8gA*tTMJ1Ze;Rm#bHuUC7NXkbxAcr)=b3;ozcLmG4{Yf2$w{$*w~xGbBj zbr4*#J)fh&I-}tNBfWWWp-A@@!S%p}N=&P8@0oBBr?&&{ad4S77j7TijA5Ck&ZeEp{uEVGSqt2BO?4dTMLkGi^Kny{ z9mP%IUcg9U9N97EC+w_Fita0g%`ssa$~2!|cu3JfaO*YjN1z~??lw)?+u@QE?|@qf z_fEJA;rxvKB(1MJ_KSad3Z^L?@lGZAshTXs3cfUw*F&Am@-RpgK3s?%% z;5*m*?i6r_J(Jtk`)(7k)JMm@Wxekf0cS~#X$Ki@=+K+i`)-m@sksJ!XT9$`0zSk{ zWaCKMXhhP8528@na&nXrSYW3CHc-Vo+wxsz`EIm)4_LkzEZ=s^Hvl{!xlm5Ihoj*L zC4$Z8;zP;3(Pamg=jL#xAr}mS>rKevrtt=xj(d8%UgvKm!&q<;-dw!QP#&&BntE$4 z)^7glqezt>60EnpY#BMJ+I?AWuTsbD4wt; zBSSQc#2=d2WhW!^9FC;gcM^Ov6f7OSPw*0p=5sPUrFa>}$1S)n2JB?l(8M%s8Yedu ziOGtS5+Ek8+DUBWu}?i-L!BMN&?^8W8irU0_b~KNpqvBo=WwUM-K|M59jzA<&?h9I zPb>}sdj|0ZX4eXmlE5@^UOs=6sl<*_gUhJiX9uW3ia)m$jYQTQgtinx9a28sz2i}f zba2z?EWk)3^KsLNEbXQd(~w5Zcu)BPXk-o~HOSw5SSD$5AY8M)uV|Y57A^-6bd_EX zs;|MVfcrbRi{bt^++}c~4ybN3&7v87LNoegDlf1Nh%YcjGjp=x+l5J>FB3CBVx9gW zv|guUXi%MJ*aMp{**xqL3|Yqa@fvG452$IQ=d1y{4^@CChp6A`j|swljhzbMOk)NQ zS$p12qvs6ysY>WcpRzepVFN^tOO}4v1J7LYY$WY@Bswg95t&m^>*-iQMXR*+D^qRh z_y{=9F=n9ZHNa2?Zpp?#u6z_|Zy_|psD*E-f-Qj$>tcYN0pB(i%8E&72YiytO86uf zYUJ;#czy7_seIpo?;Yj44L(WxWB4TP1Mo@Ohv3_;;=O2vg7!M}Pw>61LgVrMKM*<} zZzf(o?io-nQWm;o6Vs6IKg9cKHvXt5O;$GZOTAvxmt@joA6K%#5lScx(H6WSWVjSX z$TB5=ora1i<;5h5$a3_3v}!r;)FJ zuhYM$=-=OV{obU17wGUm=-*TE+w7;hN-Bgnx*iB8&L`-&ztsH>RO-d7%fQgq`ySkv zHT*;1T4X4F(jV!|GG0I|fgz3ZWf|{Uun#QQE(>NLous9OT+(ug78uvy1?I6}6D-(d z3pUGw6x5)#8}{2ht&g}7I@eslx*cfsL+x=p(TAX9t!Lkq!*YA zS8EH6$kD)AANE5iY3W>w%Gv#*9^H;Y4zdcBYx&4=?$M2$nGD0^?j9G0nT8n7!+UCU zbW3fYir0I7Y7tW;gteiCeVN)8AC9@~d$DUHtULFtfEgjR<(Z->Gs>b2eL@-fvW!0? zqQL&5eOU&3l)#vo#B)$9YB=4-a%{7TqmgNj+785I@ok&OAxSdAuu4C65r%0<7!rS> zlQ8?XxkM9f-!e&&pwVs%U6kt*5V5eGSvMNARp)+Q4{ zx$4^%>hdhq(dR_d_fdP?M59GfT3=RQ&Dh;9YorZDn1~=sD)E7EF(L@&#H8rE1>t@d zr!x(!IT~+uRLCb;>n6_j-%2=zjR$4(;T9otpto}>>-Y?~%g(70Eoyq;vhFMO@4q3Q za4LPmsr1SEjKE$*e1W~GeS-~37J<1$kGXKBX#ritAo=1mFvhZ^6gUsz^Ia5R8d89~ z>x(k5X+F?9aLn~DVt+4}!h|Q)5IYuSnGeg~3Jjr9O5PC;RjrqGf}*V4Yy=8c=@YEd zCkwX%dlK;lX2+mLTRe6pDogR2k9$6dO2Clk+&IfLtQgWfsq{rW=9+Z=i0}#nM4nOF)T>gmxtWqGb2rG z$?)5Q@FEv}nTEJM7H?%jW+YF75%k|(XJn;$;z3VCpB zSFuv@dlAPj3pWD9`ut4y zRvY=#yn6fo(=QfjO8Dit+y1+|!E^X1Xw#3m7p%25zy9I=0O{CN^g$ z>8i}Z<&4b(-$fQcI}htu&b?`n~n&ree-e70EU0Hatx$jzA)>u8XiJe zyLqsf)Ab5%Wu`e4!GzQ2+bMyvt7D6A2b-{cP@iwd+RbU}d^_No>Dzf8rZ_tg(MoDh zwEbmk&iHt`L6opbIck5|Odux*pEH25S^2u*J52d5g6~M>!y<~2qkIp-cewJU!{?qE zJquU`UWW0x6>{5da(@yq_n^o$WRT5x%M!{Vb0qY7o!r9GitsWAzWTA***_TVGSZs+ zLue79u_J;s%?^vmbU?l;IWf`>9Vv)@nxXpYM+m%9BB;M?17#ZL&lhX>6`IMu4wu6h z;`efraTQz+%2&gsUGW;Y3*dee?h?4y!41Ow7Ti^EVLRz%Wp03b6Ws5@MfW$p2lrvP zfc0*M`+c~?05|UlQ`09*O<$Hl+m*oH&^{b5W35%ZOzm@OtDHAiX7**PoqzN#OkY<+ zZdN-V(t2M{14~~%H#7J1tj92pT~>@P!LS$KMiBnL___}Nr!#!>+XE!R=GSR?W)7dZ zV+=H74Ae3H?v9ae#$YdF9`Czj9AL&cK*#u#J4S{XBSXh{)E(nMGsb~B#s#(*Yc~&) zo~Cz;#P(*(_L*)J0>{$xPO*IP`q60!Ed`Aj#>cHMfu~|N=`aoHzYy-c!;~Pug5UoW{(OM)ddilb#%WBFb@#eQ(M4gvw5|vqC zF@5vfE~3uMHHkWJ<8ZX353>EdT_68YmAK4V;xYwnaROTuu-yr4SHOr97*W7(C$L+0 zw1sW!YT8Wy>UA}%;TL5Pg1ZV86LG!S^8Lp0y<_>XjHKi7FoL8YW!>W1hfq?UVSLCy$G}~Xu-nLN%PE>Gkg5nTQ}fl2O~XmJ3~kqNf=C=y zWn_0OvZ5wK_BJ2ZlU<2j=1vWS-q6dEx56d-b-3(Ge}Q`f+_&IPfeZHQt%M6f)Y}Ai zJKPqye}x-@i`ALl3*o*G7upP0yn4|cSqIg{cECk9A-;R5q5KW*K-2}@talh(@OAHz za6g4hJYrQy)oTVQC0&X>=~DD%DN~QY-bH=_b54FTxfe_J-m2b1h26RL9CG&vBu+zy z@h9JGdMRGA3Lm!=?E}os4opLoo{0DIgYic_@fTd2?7)(W@Uk@KAdh{dww77Usb>Zz zu3Zs+*+>o4B)LbYqrx!tryvrsnxo5sSOZ0R+SJZty<@nHS0rSgVlO<3D>Kwb%@OM z>GQ4em&`vJt8fK68Hhu!|^} z+rEKT^{1~}@%N&y$EJ1k^_XDQ*B5Ynw;hzQM)y&uz8|&EP@}ty>3M*CO~IzYCu907 z_+(6^gAusz3|C4Gny8O_4xh! zw+Kzvze!v7RSitTafsSNt+Rjc+h&Em81HwFPO0x7iK^mBG~RO(!p9u%z4Frm}Za7L2`KU|tKxUN5jyEEs#ez-TU{Z?M5$FR-&L zSf>R$$AX=2!LG4j*IO_p6SxTHJlx{^1tW`^CW7_l=CFhC`(D%{1Nx!q8v`G2M$6zK zDYdaKKJT+f7U4A?_j+Ck0aZpBCO^@KX$Ik?hWK|YByCyCn$AYt-00y2F8J03uJs9d zaM`Hmgq4Bjd|ZWryO)A3C!CMHmzf{iwRbv-I3AJ z4of$+W+SXYkGAd+V3QofWBKwd-%R+#uC@?98Ll{emBFzQzAF`raj28Qu^m1c969Jo z=!Nh}+DqY+!SP!7WN`d1_+)Ur4?ao3buCHp1bi|${@#N989o^t*{6h0K@XPHf=&evGL-#8eDV0c4DrbK=HoW>dfQj)KW{JJSwcxh$vX3 zPq0Xz903&A^GGMKFB4;De4!Y#*fM2|L82&((F7wHqfanKpI}U2#F)Sw7;|p<$P@A^+ZrhpP-h$ zEaOe264*BF(<`Pm=)USm-LR7mK!~w&7=9@q&ei!cw;yT#9Cnf~bLCL;mkLzr=;ONS zW802hyEUzq?_*nsZQKp(eCu&o9~%5js}c{0aMncBp6sBMo++&*r!PqY{_{G+Bi*{{a zf#QappSx!~Y%f;Z=7xcy$AY3+8-+S{iYg*Lwryyl!dk6`=O-w_e*#X-P`ew&#}&N? z6s*wlQAE3y({{wE0i0oc{&pzmRMFGvv;n$r#bz4Ly8>`8J(#KZn5%}kIjO4?-UJwx*buMBhLD0)DKV)tuKh?#~d5OKR4LPCOcVGnJv^?T8zF9?sWXV5pF5mo8WQ_*3EE< zlUv~~hkF~`4!C!~rA_5dxR=7c3oa3IFWhg#y$>$@#{FSk4!GzQy?=wd5$-Oy zkHH-Td^`^K7`RWt^}yW%mzQ5Z1Gf?G&*73^o`*})a~)fxDSaYM=@V%xFiKN_4MRx+ zJ4E}kj3Nuh_DZ}x3~1v}z}^jLm!T@|OB(D0T7z>yOGQ^L;is)qRG}OSfm<(SJ*Yu} zBaK|Vd>S;G@hS9P4!AI`DYWy`<$`wl1nu;Reju>t5no^qbYlNYQM#T2#FHe4BUve4 z^KmPow;-U)r4uj>xq(6?d>vqz4>kK zYE{`su+NXhZGM~ESOqj>%O!UrHREs3iuw`p<6);2rLTQA^CNXl+bef+~k!%%H0CLvT}u z+5yy}e3JqDE0{6^=kxK6aQJc*gSM&A9|JZ|`JRQ3BVh)wqA)&C@jUn|@g~40@#ewT zt>P_(PvUjM7f~>-=Dm+M$M}}z+YH}o75X%MQkT!+J6FN7@Ku-lqX0VM3Gn^2MgDkJ8N4sK5@|;3O30Un`IRtZ4O*YOZ`Cg$}+s_(*Pr&t?)vh zonYUzae6Il1OV&-5yZ!rH9HzttFI~IGM~ZOVeWSn(^2vBo;sL zAa^jBR+48S_h>bFQlcB?Z%!Kdn7^xCzsVkExSE5Bex+DaLJZ<+E3)N&H=0KHpx9pG z4=X0UXdw4H^-hPI4|f(^tZwwKfD4$qeF$1_?`8OnHMri_;m(Bn0o>Ve*}@{Yez6+!x?h!hIQT4cz~MTMKsr>RShQ65Pdbi{UPX zyA&?^Q15AQ8{m@m*z=byxXV{y$6K&G z3pUk)6QrbZm zo7S=B5EK0Gy25@ua2j9c{1%9wkC!rrkK3494VsBQ^vEGmY|P8Ha(20y|RsvWycf*mw)ZnV!Uh;ZLWXXTcU&uq77k zbPKlJf~~M%t1KAir#inYE!Z^{OvwZD9Dp_$uJfsj0oUU@FG`5x3tca5jUE_OFvmI{ z=N37J2aTSkd>Dp|@ybW$b{i;)0fX?h7~g%CkE?YJF2-jXGCqm7#L4)n%*=e9;hs>S zq_MlPIT%@^c$_sT!pmIw%41(ju&mtXG8u>6&Yli+@|NQ=?F*gJZ}PaAi*+6gED#41 z@bba-2gO`na0!E8?q!?K*6@jlFU&=sFc*DU#ty_17}-o|p{*_GYoKOTD2XCVKjsANat&pDVg z&muE#xNIZk4K2p(Bz$~&VG{J~&BgC|aH+A+hfCHd*Wo-=BCJ85um*i{e~Q4yf+7M_ ztRY9&Gm}j5IYTePOCIIp-lWk8*hwxzG0h;nMB6WEsZ>vzGU&}U4TD7h^5ql7FT0mH zV%!C$Yc*^NBO7f#ETbD(vQN?9GsGbGK3rxAIz>T`cYmYa&24_QHm1tb{uQ?rONKBif*dGz6FtBGD&AqEGG-5ZGqK z7g!9DV zfJ-8E!6lKpbvUQqLL~ZxNc0Jj1hyIR1?D1>>M)`u4D>-^;JG~ovqqWWNGb+f%DKb} z0%n3qM~@#N+`ahCH00{BcsrsfPxU+rzqywL{ryr4l$ub|6RNTcH%fBzVO`yd0dzRk zPcU;;s|`W8YzuZyD)$CJkiO6H1qMANYV|H zL-dBp`@zs{C^uE(g%y7`Yx1E0pOt2c2Ka0TA8=a|gn#rSp{8w~H+X0%k*QXUxy3@} zjpCzV6d#Ox|I+(IsmgK5C&$PFH;+`lW8ss%rJUfug*U@E34d=wXogV$Uy1TzFO=TN z>a#*=?2)uI-@S`B!)U?ZHo}uHRqRzs+sAKheLf zZMn+8Z69sO1Mbo0UOj3+II4ZQ5G%cpBHl*0&%)gV_Z7H5gZly8hv1Tj9)?Rg9RXgG z(S|-5ZRpEVpEM9y4&n=pMl^w)Y{5>mU_6*2@t|Jmcs!UQuyZUJ52gt0atn5a1^c!I z` z%dKymAB10=ZpRlZCnK~Juc^FoUx9sx(lUg(zjn?vG&)d^ekmJ&)RR^oF5}4>5eLk( z2ru)EiUaEIrpE7F%`+=N&H zyG8qK`v$SEkLymxC7UDT*PfSYoIAoCKA{er2W+a)==SW&4eKiJ-+q*eicpGlh3mWF z8hwlIUbpD}%YFA-YWJ~#Cf*K1HK7KtiF57>vtOWg1H#;A^qGcu^z(I!@>Gnj<>B&{ z)r)z)Nh!rFy$J7cyiV$vA1<->#F*rwu;$%pxCDyy^58We){S#0A|*!yr)m0(23+Vv zpU{Us*_JJ^twHcZi&Oz}@tRKoJoC*TaNSdqPQYfk z21}+PE+*nV)`?;B1EuBRC<>W<5#CI^@lm*GBr47?%8LodjWw1x9GI|U4X|EjMthcE zjXuE|eOdg1kqRAb+^>C_tE20Pv6r35M;yjrj>xdN>Dc(1p1Td{DM>`ZOoCu86tg4c zaQRpJ;vt=^nGEUe2%qjkI@7Sh9I-x+iV~T>@w*89L-~Q|Nfyf8VufX0kBZyvnAl99 z5Pl+D)?vK<{gFig`h)=VWvTme1V&N_%+9t-MC5Q@t`1Dc$`XrnACLc$SQ>+fMxvOH zn|C(?=2rBWhG?9Ox6R4B`#PQ01Ss!p39L>sp|)FPc8}Inh$A~>KLYD%KCC+x6gye| zsn_>Dhs(IT^=~To(l6)}vd||7h6KhAB`|B?ly5yMhJR_B2x;|MH43fx!{X5>wA8F2 zT=#anuLE|PiPg0nUe^qi0G;w`5JX&Bp^bX4BQRfi?1;96v?Z49h-H1) zLOWuYYW_YIF6()k{>{Nk5KEsRmcA_GMZ^-=ueDDL9NX!cgx_3HpQ=@OM~B#g^ccM4 zOmGgoa=7Uz%ZJ@3#tA4iK1oUtnv5jZBiy}-lxc`MT5nqWPm-FR(DFU0GvW}H#ddX49Tt3Rcx?Es!YSC=i+T~ zl4)PXSAR%oO;FjL+$3WiDW>csdm&v&_6xXV=wHGmJHH5*ZFxzD^RpI0GWvvM^vT9m zfw7ke%ub#*P6*o&WLl@q#*Fp`Z!@9B~vVaK$;Azwy4XE#>?W-9s+X5Sq>Y!XK5o*#W)TA$q zUnf#aDT9sQXrC+zNW2d$n4Q8FnOFt49t(9QDf(|lxcdtbOha7pZQL95V;#LI5ON;& z+OetulPtZ)CbQ*!N(+EtVG^zt*QDj{ucY3eg zhTF4uuGZIL$|9IGiQfK44ogMEyg4qhmST?M8uA>J7k@OGk5Inmzf^(hdG z&HWa`kzB0V@w(Y4gp$L}$1UaVK!982W*SzWv!g}(o0#E1q_k;yd1q@^iek_)bSWZD zM!n33b#<%Q&l!UJpTlJvp4Y!QvI{Zj6JpRO#1I&XAuzin?r2+U423_I(-M5x2{XGFg+6Kcv>qyrYX~sVfrfwcTdrohL}Dc@5R(5)Du0A2<*!F z!Ni|awGY^L0TXJ9ZVuQ*$S>F_1GF2fESqNm?O2_qu{awp>oiCI=3pX>OP^qsKG`rK zu+4}sFz0xYi7k4Y7IJ2-ckBVH=58blwH&mTA;S#S=V|ZFQHK<1VULgQDM X)?BZ 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 @s7B-sqWkM*|w>oEg64^+u?P% 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

nXtmYFO*n-LwjGqyxIe!*94FZPYbR+;HH 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�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∨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ÐSaokg+n%#B3~xp`Hv=IXg#OC8E7+ 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 literal 0 HcmV?d00001 diff --git a/src/public/datamap.h b/src/public/datamap.h index 5cc879173..be484292c 100644 --- a/src/public/datamap.h +++ b/src/public/datamap.h @@ -315,6 +315,12 @@ struct datamap_t template friend void DataMapAccess(T *, datamap_t **p); \ template friend datamap_t *DataMapInit(T *); +#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \ + static datamap_t m_DataMap; \ + static datamap_t *GetBaseMap(); \ + template friend void ::DataMapAccess(T *, datamap_t **p); \ + template friend datamap_t *::DataMapInit(T *); + #define DECLARE_DATADESC() \ DECLARE_SIMPLE_DATADESC() \ virtual datamap_t *GetDataDescMap( void ); @@ -415,6 +421,8 @@ inline void DataMapAccess(T *ignored, datamap_t **p) *p = &T::m_DataMap; } +template datamap_t* DataMapInit(T*); + //----------------------------------------------------------------------------- class CDatadescGeneratedNameHolder diff --git a/src/public/responserules/response_host_interface.h b/src/public/responserules/response_host_interface.h new file mode 100644 index 000000000..86eedc896 --- /dev/null +++ b/src/public/responserules/response_host_interface.h @@ -0,0 +1,61 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_HOST_INTERFACE_H +#define RESPONSE_HOST_INTERFACE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "filesystem.h" +class IUniformRandomStream; +class ICommandLine; + +namespace ResponseRules +{ + // FUNCTIONS YOU MUST IMPLEMENT IN THE HOST EXECUTABLE: + // These are functions that are mentioned in the header, but need their bodies implemented + // in the .dll that links against this lib. + // This is to wrap functions that previously came from the engine interface + // back when the response rules were inside the server.dll . Now that the rules + // are included into a standalone editor, we don't necessarily have an engine around, + // so there needs to be some other implementation. + abstract_class IEngineEmulator + { + public: + /// Given an input text buffer data pointer, parses a single token into the variable token and returns the new + /// reading position + virtual const char *ParseFile( const char *data, char *token, int maxlen ) = 0; + + /// Return a pointer to an IFileSystem we can use to read and process scripts. + virtual IFileSystem *GetFilesystem() = 0; + + /// Return a pointer to an instance of an IUniformRandomStream + virtual IUniformRandomStream *GetRandomStream() = 0 ; + + /// Return a pointer to a tier0 ICommandLine + virtual ICommandLine *GetCommandLine() = 0; + + /// Emulates the server's UTIL_LoadFileForMe + virtual byte *LoadFileForMe( const char *filename, int *pLength ) = 0; + + /// Emulates the server's UTIL_FreeFile + virtual void FreeFile( byte *buffer ) = 0; + + + /// Somewhere in the host executable you should define this symbol and + /// point it at a singleton instance. + static IEngineEmulator *s_pSingleton; + + // this is just a function that returns the pointer above -- just in + // case we need to define it differently. And I get asserts this way. + static IEngineEmulator *Get(); + }; +}; + + +#endif \ No newline at end of file diff --git a/src/public/responserules/response_types.h b/src/public/responserules/response_types.h new file mode 100644 index 000000000..7e60208bb --- /dev/null +++ b/src/public/responserules/response_types.h @@ -0,0 +1,437 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_TYPES_H +#define RESPONSE_TYPES_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/interval.h" +#include "mathlib/compressed_vector.h" +#include "datamap.h" +#include "soundflags.h" +#include "tier1/utlsymbol.h" + +namespace ResponseRules +{ + /// Custom symbol table for the response rules. + extern CUtlSymbolTable g_RS; +}; + +#ifdef _MANAGED +// forward declare some editor types just so we can friend them. +namespace ResponseRulesCLI +{ + ref class ResponseQueryResult; +} +#endif + +namespace ResponseRules +{ + using ::DataMapAccess; + //using ::DataMapInit; + class CResponseSystem; + +#pragma pack(push,1) + template + struct response_interval_t + { + T start; + T range; + + interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; } + void FromInterval( const interval_t &from ) { start = from.start; range = from.range; } + float Random() const { interval_t temp = { start, range }; return RandomInterval( temp ); } + }; + + typedef response_interval_t responseparams_interval_t; +#pragma pack(pop) + +#pragma pack(push,1) + struct AI_ResponseFollowup + { + + + // TODO: make less wasteful of memory, by using a symbol table. + const char *followup_concept; // 12 -- next response + const char *followup_contexts; // 16 + 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 + 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; } + + 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, + char *_followup_entityiotarget, char *_followup_entityioinput, float _followup_entityiodelay ) : + followup_concept(_followup_concept), followup_contexts(_followup_contexts), followup_delay(_followup_delay), followup_target(_followup_target), + followup_entityiotarget(_followup_entityiotarget), followup_entityioinput(_followup_entityioinput), followup_entityiodelay(_followup_entityiodelay), + bFired(false) + {}; + }; +#pragma pack(pop) + + + enum ResponseType_t + { + RESPONSE_NONE = 0, + RESPONSE_SPEAK, + RESPONSE_SENTENCE, + RESPONSE_SCENE, + RESPONSE_RESPONSE, // A reference to another response by name + RESPONSE_PRINT, + RESPONSE_ENTITYIO, // poke an input on an entity + + NUM_RESPONSES, + }; + + //MAPBASE: + // I wanted to add more options to apply contexts to, +// so I replaced the existing system with a flag-based integer instead of a bunch of booleans. +// +// New ones should be implemented in: +// CResponseSystem::ParseRule() - AI_ResponseSystem.cpp +// AI_Response::Describe() - AI_Criteria.cpp +// CAI_Expresser::SpeakDispatchResponse() - ai_speech.cpp + enum + { + APPLYCONTEXT_SELF = (1 << 0), // Included for contexts that apply to both self and something else + APPLYCONTEXT_WORLD = (1 << 1), // Apply to world + + APPLYCONTEXT_SQUAD = (1 << 2), // Apply to squad + APPLYCONTEXT_ENEMY = (1 << 3), // Apply to enemy + }; + +#pragma pack(push,1) + struct ResponseParams + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + enum + { + RG_DELAYAFTERSPEAK = (1<<0), + RG_SPEAKONCE = (1<<1), + RG_ODDS = (1<<2), + RG_RESPEAKDELAY = (1<<3), + RG_SOUNDLEVEL = (1<<4), + RG_DONT_USE_SCENE = (1<<5), + RG_STOP_ON_NONIDLE = (1<<6), + RG_WEAPONDELAY = (1<<7), + RG_DELAYBEFORESPEAK = (1<<8), + }; + + ResponseParams() + { + flags = 0; + odds = 100; + delay.start = 0; + delay.range = 0; + respeakdelay.start = 0; + respeakdelay.range = 0; + weapondelay.start = 0; + weapondelay.range = 0; + soundlevel = 0; + predelay.start = 0; + predelay.range = 0; + } + responseparams_interval_t delay; //4 + responseparams_interval_t respeakdelay; //8 + responseparams_interval_t weapondelay; //12 + + short odds; //14 + + short flags; //16 + byte soundlevel; //17 + + responseparams_interval_t predelay; //21 + + ALIGN32 AI_ResponseFollowup *m_pFollowup; + + }; +#pragma pack(pop) + + class CriteriaSet + { + public: + typedef CUtlSymbol CritSymbol_t; ///< just to make it clear that some symbols come out of our special static table + public: + CriteriaSet(); + CriteriaSet( const CriteriaSet& src ); + CriteriaSet( const char *criteria, const char *value ) ; // construct initialized with a key/value pair (convenience) + ~CriteriaSet(); + + static CritSymbol_t ComputeCriteriaSymbol( const char *criteria ); + void AppendCriteria( CritSymbol_t criteria, const char *value = "", float weight = 1.0f ); + void AppendCriteria( const char *criteria, const char *value = "", float weight = 1.0f ); + void AppendCriteria( const char *criteria, float value, float weight = 1.0f ); + void RemoveCriteria( const char *criteria ); + + void Describe() const; + + int GetCount() const; + int FindCriterionIndex( CritSymbol_t criteria ) const; + int FindCriterionIndex( const char *name ) const; + inline bool IsValidIndex( int index ) const; + + CritSymbol_t GetNameSymbol( int nIndex ) const; + inline static const char *SymbolToStr( const CritSymbol_t &symbol ); + const char *GetName( int index ) const; + const char *GetValue( int index ) const; + float GetWeight( int index ) const; + + /// Merge another CriteriaSet into this one. + void Merge( const CriteriaSet *otherCriteria ); + void Merge( const char *modifiers ); // add criteria parsed from a text string + + /// add all of the contexts herein onto an entity. all durations are infinite. + void WriteToEntity( CBaseEntity *pEntity ); + + // Accessors to things that need only be done under unusual circumstances. + inline void EnsureCapacity( int num ); + void Reset(); // clear out this criteria (should not be necessary) + + /// When this is true, calls to AppendCriteria on a criteria that already exists + /// will override the existing value. (This is the default behavior). Can be temporarily + /// set false to prevent such overrides. + inline void OverrideOnAppend( bool bOverride ) { m_bOverrideOnAppend = bOverride; } + + // For iteration from beginning to end (also should not be necessary except in + // save/load) + inline int Head() const; + inline int Next( int i ) const; // use with IsValidIndex above + + const static char kAPPLYTOWORLDPREFIX = '$'; + + /// A last minute l4d2 change: deferred contexts prefixed with a '$' + /// character are actually applied to the world. This matches the + /// related hack in CBaseEntity::AppplyContext. + /// This function works IN-PLACE on the "from" parameter. + /// any $-prefixed criteria in pFrom become prefixed by "world", + /// and are also written into pSetOnWorld. + /// *IF* a response matches using the modified criteria, then and only + /// then should you write back the criteria in pSetOnWorld to the world + /// 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 ); + + private: + 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 ); + } + + CritEntry_t& operator=( const CritEntry_t& src ) + { + if ( this == &src ) + return *this; + + criterianame = src.criterianame; + weight = src.weight; + SetValue( src.value ); + + return *this; + } + + static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs ) + { + return lhs.criterianame < rhs.criterianame; + } + + void SetValue( char const *str ) + { + if ( !str ) + { + value[ 0 ] = 0; + } + else + { + Q_strncpy( value, str, sizeof( value ) ); + } + } + + 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 + bool m_bOverrideOnAppend; + }; + + inline void CriteriaSet::EnsureCapacity( int num ) + { + m_Lookup.EnsureCapacity(num); + } + + //----------------------------------------------------------------------------- + // Purpose: Generic container for a response to a match to a criteria set + // This is what searching for a response returns + //----------------------------------------------------------------------------- + + class CRR_Response + { + public: + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + CRR_Response(); + CRR_Response( const CRR_Response &from ); + CRR_Response &operator=( const CRR_Response &from ); + ~CRR_Response(); + private: + void operator delete(void* p); // please do not new or delete CRR_Responses. + public: + + // void Release(); // we no longer encourage new and delete on these things + + void GetName( char *buf, size_t buflen ) const; + void GetResponse( char *buf, size_t buflen ) const; + const char* GetNamePtr() const; + const char* GetResponsePtr() const; + const ResponseParams *GetParams() const { return &m_Params; } + ResponseType_t GetType() const { return (ResponseType_t)m_Type; } + soundlevel_t GetSoundLevel() const; + float GetRespeakDelay() const; + float GetWeaponDelay() const; + bool GetSpeakOnce() const; + bool ShouldntUseScene( ) const; + bool ShouldBreakOnNonIdle( void ) const; + int GetOdds() const; + float GetDelay() const; + float GetPreDelay() const; + + inline bool IsEmpty() const; // true iff my response name is empty + void Invalidate() ; // wipe out my contents, mark me invalid + + // Get/set the contexts we apply to character and world after execution + void SetContext( const char *context ); + const char * GetContext( void ) const { return m_szContext; } + + // Get/set the score I matched with (under certain circumstances) + inline float GetMatchScore( void ) { return m_fMatchScore; } + inline void SetMatchScore( float f ) { m_fMatchScore = f; } + + int GetContextFlags() { return m_iContextFlags; } + bool IsApplyContextToWorld() const { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } + + void Describe( const CriteriaSet *pDebugCriteria = NULL ); + + void Init( ResponseType_t type, + const char *responseName, + const ResponseParams& responseparams, + const char *matchingRule, + const char *applyContext, + int iContextFlags ); + + static const char *DescribeResponse( ResponseType_t type ); + + enum + { + MAX_RESPONSE_NAME = 64, + MAX_RULE_NAME = 64 + }; + + + private: + byte m_Type; + char m_szResponseName[ MAX_RESPONSE_NAME ]; + char m_szMatchingRule[ MAX_RULE_NAME ]; + + ResponseParams m_Params; + float m_fMatchScore; // when instantiated dynamically in SpeakFindResponse, the score of the rule that matched it. + + char * m_szContext; // context data we apply to character after running + int m_iContextFlags; + +#ifdef _MANAGED + friend ref class ResponseRulesCLI::ResponseQueryResult; +#endif + }; + + + + abstract_class IResponseFilter + { + public: + virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ) = 0; + }; + + abstract_class IResponseSystem + { + public: + virtual ~IResponseSystem() {} + + virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL ) = 0; + virtual void GetAllResponses( CUtlVector *pResponses ) = 0; + virtual void PrecacheResponses( bool bEnable ) = 0; + }; + + + + // INLINE FUNCTIONS + + // Used as a failsafe in finding responses. + bool CRR_Response::IsEmpty() const + { + return m_szResponseName[0] == 0; + } + + inline bool CriteriaSet::IsValidIndex( int index ) const + { + 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); + } + +} + +#include "rr_speechconcept.h" +#include "response_host_interface.h" + +#endif diff --git a/src/public/responserules/rr_speechconcept.h b/src/public/responserules/rr_speechconcept.h new file mode 100644 index 000000000..65b1bb6e6 --- /dev/null +++ b/src/public/responserules/rr_speechconcept.h @@ -0,0 +1,57 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Class data for an AI Concept, an atom of response-driven dialog. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RR_SPEECHCONCEPT_H +#define RR_SPEECHCONCEPT_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "utlsymbol.h" + +#define RR_CONCEPTS_ARE_STRINGS 0 + + +typedef CUtlSymbolTable CRR_ConceptSymbolTable; + +namespace ResponseRules +{ +class CRR_Concept +{ +public: // local typedefs + typedef CUtlSymbol tGenericId; // an int-like type that can be used to refer to all concepts of this type + tGenericId m_iConcept; + +public: + CRR_Concept() {}; + // construct concept from a string. + CRR_Concept(const char *fromString); + + // Return as a string + const char *GetStringConcept() const; + static const char *GetStringForGenericId(tGenericId genericId); + + operator tGenericId() const { return m_iConcept; } + operator const char *() const { return GetStringConcept(); } + inline bool operator==(const CRR_Concept &other) // default is compare by concept ids + { + return m_iConcept == other.m_iConcept; + } + bool operator==(const char *pszConcept); + +protected: + +private: + // dupe a concept + // CRR_Concept& operator=(CRR_Concept &other); + CRR_Concept& operator=(const char *fromString); +}; +}; + + +#endif diff --git a/src/public/tier0/basetypes.h b/src/public/tier0/basetypes.h index d4208dbcd..7b9df1d4a 100644 --- a/src/public/tier0/basetypes.h +++ b/src/public/tier0/basetypes.h @@ -131,6 +131,70 @@ constexpr T Max( T const &val1, T const &val2 ) #define TRUE (!FALSE) #endif +//----------------------------------------------------------------------------- +// fsel +//----------------------------------------------------------------------------- +#ifndef _X360 + +#define fsel(c,x,y) ( (c) >= 0 ? (x) : (y) ) + +// integer conditional move +// if a >= 0, return x, else y +#define isel(a,x,y) ( ((a) >= 0) ? (x) : (y) ) + +// if x = y, return a, else b +#define ieqsel(x,y,a,b) (( (x) == (y) ) ? (a) : (b)) + +// if the nth bit of a is set (counting with 0 = LSB), +// return x, else y +// this is fast if nbit is a compile-time immediate +#define ibitsel(a, nbit, x, y) ( ( ((a) & (1 << (nbit))) != 0 ) ? (x) : (y) ) + +#else + +// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT +// this is much faster than if ( aFloat > 0 ) { x = .. } +// the XDK defines two intrinsics, one for floats and one for doubles -- it's the same +// opcode, but the __fself version tells the compiler not to do a wasteful unnecessary +// rounding op after each sel. +// #define fsel __fsel +FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) { return __fsel( fComparand, fValGE, fLT ); } +FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) { return __fself( fComparand, fValGE, fLT ); } + +// if a >= 0, return x, else y +FORCEINLINE int isel( int a, int x, int y ) +{ + int mask = a >> 31; // arithmetic shift right, splat out the sign bit + return x + ((y - x) & mask); +}; + +// if a >= 0, return x, else y +FORCEINLINE unsigned isel( int a, unsigned x, unsigned y ) +{ + int mask = a >> 31; // arithmetic shift right, splat out the sign bit + return x + ((y - x) & mask); +}; + +// ( x == y ) ? a : b +FORCEINLINE unsigned ieqsel( unsigned x, unsigned y, unsigned a, unsigned b ) +{ + unsigned mask = (x == y) ? 0 : -1; + return a + ((b - a) & mask); +}; + +// ( x == y ) ? a : b +FORCEINLINE int ieqsel( int x, int y, int a, int b ) +{ + int mask = (x == y) ? 0 : -1; + return a + ((b - a) & mask); +}; + +// if the nth bit of a is set (counting with 0 = LSB), +// return x, else y +// this is fast if nbit is a compile-time immediate +#define ibitsel(a, nbit, x, y) ( (x) + (((y) - (x)) & (((a) & (1 << (nbit))) ? 0 : -1)) ) + +#endif #ifndef DONT_DEFINE_BOOL // Needed for Cocoa stuff to compile. typedef int BOOL; diff --git a/src/public/tier0/platform.h b/src/public/tier0/platform.h index 500edcb62..5039653f4 100644 --- a/src/public/tier0/platform.h +++ b/src/public/tier0/platform.h @@ -800,29 +800,6 @@ typedef uint32 HMODULE; typedef void *HANDLE; #endif -//----------------------------------------------------------------------------- -// fsel -//----------------------------------------------------------------------------- -#ifndef _X360 - -static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} -static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) -{ - return fComparand >= 0 ? fValGE : fLT; -} - -#else - -// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT -// this is much faster than if ( aFloat > 0 ) { x = .. } -#define fsel __fsel - -#endif - - //----------------------------------------------------------------------------- // FP exception handling //----------------------------------------------------------------------------- diff --git a/src/public/tier1/generichash.h b/src/public/tier1/generichash.h index 7e7f002b3..6c79bb58d 100644 --- a/src/public/tier1/generichash.h +++ b/src/public/tier1/generichash.h @@ -41,6 +41,12 @@ inline uint32 HashStringCaseless( const char *pszKey, size_t len ) return MurmurHash3_32( pszKey, len, 1047 /*anything will do for a seed*/, true ); } +inline uint32 HashStringCaselessConventional(const char* pszKey) +{ + size_t len = strlen(pszKey); + HashStringCaseless(pszKey, len); +} + #if !defined(_MINIMUM_BUILD_) inline uint32 HashString( const char *pszKey ) { diff --git a/src/game/shared/interval.h b/src/public/tier1/interval.h similarity index 100% rename from src/game/shared/interval.h rename to src/public/tier1/interval.h diff --git a/src/responserules/runtime/criteriaset.cpp b/src/responserules/runtime/criteriaset.cpp new file mode 100644 index 000000000..3dc5cb200 --- /dev/null +++ b/src/responserules/runtime/criteriaset.cpp @@ -0,0 +1,477 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "rrbase.h" + +#include "utlmap.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include + +using namespace ResponseRules; + +//----------------------------------------------------------------------------- +// Case-insensitive criteria symbol table +//----------------------------------------------------------------------------- +CUtlSymbolTable CriteriaSet::sm_CriteriaSymbols( 1024, 1024, true ); + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *raw - +// *key - +// keylen - +// *value - +// valuelen - +// *duration - +// Output : static bool +//----------------------------------------------------------------------------- +const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration, const char *entireContext ) +{ + char *colon1 = Q_strstr( raw, ":" ); + if ( !colon1 ) + { + DevMsg( "SplitContext: warning, ignoring context '%s', missing colon separator!\n", raw ); + *key = *value = 0; + return NULL; + } + + int len = colon1 - raw; + Q_strncpy( key, raw, MIN( len + 1, keylen ) ); + key[ MIN( len, keylen - 1 ) ] = 0; + + bool last = false; + char *end = Q_strstr( colon1 + 1, "," ); + if ( !end ) + { + int remaining = Q_strlen( colon1 + 1 ); + end = colon1 + 1 + remaining; + last = true; + } + + char *colon2 = Q_strstr( colon1 + 1, ":" ); + if ( colon2 && ( colon2 < end ) ) + { + if ( duration ) + *duration = atof( colon2 + 1 ); + + char durationStartChar = *(colon2 + 1); + if ( durationStartChar < '0' || durationStartChar > '9' ) + { + DevMsg( "SplitContext: warning, ignoring context '%s', missing comma separator! Entire context was '%s'.\n", raw, entireContext ); + *key = *value = 0; + return NULL; + } + + len = MIN( colon2 - ( colon1 + 1 ), valuelen - 1 ); + Q_strncpy( value, colon1 + 1, len + 1 ); + value[ len ] = 0; + } + else + { + if ( duration ) + *duration = 0.0; + + len = MIN( end - ( colon1 + 1 ), valuelen - 1 ); + Q_strncpy( value, colon1 + 1, len + 1 ); + value[ len ] = 0; + } + + return last ? NULL : end + 1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true), + m_nNumPrefixedContexts(0) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::CriteriaSet( const CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_nNumPrefixedContexts(src.m_nNumPrefixedContexts) +{ + m_Lookup.EnsureCapacity( src.m_Lookup.Count() ); + for ( short i = src.m_Lookup.FirstInorder(); + i != src.m_Lookup.InvalidIndex(); + i = src.m_Lookup.NextInorder( i ) ) + { + m_Lookup.Insert( src.m_Lookup[ i ] ); + } +} + +CriteriaSet::CriteriaSet( const char *criteria, const char *value ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true) +{ + AppendCriteria(criteria,value); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CriteriaSet::~CriteriaSet() +{ +} + +//----------------------------------------------------------------------------- +// Computes a symbol for the criteria +//----------------------------------------------------------------------------- +CriteriaSet::CritSymbol_t CriteriaSet::ComputeCriteriaSymbol( const char *criteria ) +{ + return sm_CriteriaSymbols.AddString( criteria ); +} + + +//----------------------------------------------------------------------------- +// Computes a symbol for the criteria +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( CriteriaSet::CritSymbol_t criteria, const char *value, float weight ) +{ + int idx = FindCriterionIndex( criteria ); + if ( idx == -1 ) + { + CritEntry_t entry; + entry.criterianame = criteria; + MEM_ALLOC_CREDIT(); + idx = m_Lookup.Insert( entry ); + if ( sm_CriteriaSymbols.String(criteria)[0] == kAPPLYTOWORLDPREFIX ) + { + m_nNumPrefixedContexts += 1; + } + } + else // criteria already existed + { + // bail out if override existing criteria is not allowed + if ( !m_bOverrideOnAppend ) + return; + } + + CritEntry_t *entry = &m_Lookup[ idx ]; + entry->SetValue( value ); + entry->weight = weight; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criteria - +// "" - +// 1.0f - +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( const char *pCriteriaName, const char *value /*= ""*/, float weight /*= 1.0f*/ ) +{ + CUtlSymbol criteria = ComputeCriteriaSymbol( pCriteriaName ); + AppendCriteria( criteria, value, weight ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criteria - +// "" - +// 1.0f - +//----------------------------------------------------------------------------- +void CriteriaSet::AppendCriteria( const char *criteria, float value, float weight /*= 1.0f*/ ) +{ + char buf[32]; + V_snprintf( buf, 32, "%f", value ); + AppendCriteria( criteria, buf, weight ); +} + + +//----------------------------------------------------------------------------- +// Removes criteria in a set +//----------------------------------------------------------------------------- +void CriteriaSet::RemoveCriteria( const char *criteria ) +{ + const int idx = FindCriterionIndex( criteria ); + if ( idx == -1 ) + return; + + if ( criteria[0] == kAPPLYTOWORLDPREFIX ) + { + Assert( m_nNumPrefixedContexts > 0 ); + m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 ); + } + RemoveCriteria( idx, false ); +} + +// bTestForIndex tells us whether the calling function has already checked for a +// $ prefix and decremented m_nNumPrefixedContexts appropriately (false), +// or if this function should do that (true). +void CriteriaSet::RemoveCriteria( int idx, bool bTestForPrefix ) +{ + Assert( m_Lookup.IsValidIndex(idx) ); + if ( bTestForPrefix ) + { + if ( sm_CriteriaSymbols.String( m_Lookup[idx].criterianame )[0] == kAPPLYTOWORLDPREFIX ) + { + Assert( m_nNumPrefixedContexts > 0 ); + m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 ); + } + } + m_Lookup.RemoveAt( idx ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CriteriaSet::GetCount() const +{ + return m_Lookup.Count(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// Output : int +//----------------------------------------------------------------------------- +int CriteriaSet::FindCriterionIndex( CritSymbol_t criteria ) const +{ + CritEntry_t search; + search.criterianame = criteria; + int idx = m_Lookup.Find( search ); + return ( idx == m_Lookup.InvalidIndex() ) ? -1 : idx; +} + +int CriteriaSet::FindCriterionIndex( const char *name ) const +{ + CUtlSymbol criteria = ComputeCriteriaSymbol( name ); + return FindCriterionIndex( criteria ); +} + + +//----------------------------------------------------------------------------- +// Returns the name symbol +//----------------------------------------------------------------------------- +CriteriaSet::CritSymbol_t CriteriaSet::GetNameSymbol( int nIndex ) const +{ + if ( nIndex < 0 || nIndex >= (int)m_Lookup.Count() ) + return UTL_INVAL_SYMBOL; + + const CritEntry_t *entry = &m_Lookup[ nIndex ]; + return entry->criterianame; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : char const +//----------------------------------------------------------------------------- +const char *CriteriaSet::GetName( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return ""; + else + { + const char *pCriteriaName = sm_CriteriaSymbols.String( m_Lookup[ index ].criterianame ); + return pCriteriaName ? pCriteriaName : ""; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : char const +//----------------------------------------------------------------------------- +const char *CriteriaSet::GetValue( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return ""; + + const CritEntry_t *entry = &m_Lookup[ index ]; + return entry->value ? entry->value : ""; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : index - +// Output : float +//----------------------------------------------------------------------------- +float CriteriaSet::GetWeight( int index ) const +{ + if ( index < 0 || index >= (int)m_Lookup.Count() ) + return 1.0f; + + const CritEntry_t *entry = &m_Lookup[ index ]; + return entry->weight; +} + + +//----------------------------------------------------------------------------- +// Purpose: Merge another criteria set into this one. +//----------------------------------------------------------------------------- +void CriteriaSet::Merge( const CriteriaSet * RESTRICT otherCriteria ) +{ + Assert(otherCriteria); + if (!otherCriteria) + return; + + // for now, just duplicate everything. + int count = otherCriteria->GetCount(); + EnsureCapacity( count + GetCount() ); + for ( int i = 0 ; i < count ; ++i ) + { + AppendCriteria( otherCriteria->GetNameSymbol(i), otherCriteria->GetValue(i), otherCriteria->GetWeight(i) ); + } +} + +void CriteriaSet::Merge( const char *modifiers ) // add criteria parsed from a text string +{ + // Always include any optional modifiers + if ( modifiers == NULL ) + return; + + char copy_modifiers[ 255 ]; + const char *pCopy; + char key[ 128 ] = { 0 }; + char value[ 128 ] = { 0 }; + + Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) ); + pCopy = copy_modifiers; + + while( pCopy ) + { + pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers ); + + if( *key && *value ) + { + AppendCriteria( key, value, 1 ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CriteriaSet::Describe() const +{ + // build an alphabetized representation of the set for printing + typedef CUtlMap tMap; + tMap m_TempMap( 0, m_Lookup.Count(), CaselessStringLessThan ); + + for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) + { + const CritEntry_t *entry = &m_Lookup[ i ]; + + m_TempMap.Insert( sm_CriteriaSymbols.String( entry->criterianame ), entry ); + } + + for ( tMap::IndexType_t i = m_TempMap.FirstInorder(); i != m_TempMap.InvalidIndex(); i = m_TempMap.NextInorder( i ) ) + { + // const CritEntry_t *entry = &m_TempMap[ i ]; + // const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame ); + + const char *name = m_TempMap.Key( i ); + const CritEntry_t *entry = m_TempMap.Element( i ); + if ( entry->weight != 1.0f ) + { + DevMsg( " %20s = '%s' (weight %f)\n", name, entry->value ? entry->value : "", entry->weight ); + } + else + { + DevMsg( " %20s = '%s'\n", name, entry->value ? entry->value : "" ); + } + } + + /* + for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) ) + { + const CritEntry_t *entry = &m_Lookup[ i ]; + + const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame ); + if ( entry->weight != 1.0f ) + { + DevMsg( " %20s = '%s' (weight %f)\n", pCriteriaName, entry->value ? entry->value : "", entry->weight ); + } + else + { + DevMsg( " %20s = '%s'\n", pCriteriaName, entry->value ? entry->value : "" ); + } + } + */ +} + + +void CriteriaSet::Reset() +{ + m_Lookup.Purge(); +} + +void CriteriaSet::WriteToEntity( CBaseEntity *pEntity ) +{ +#if 0 + if ( GetCount() < 1 ) + return; + + for ( int i = Head() ; IsValidIndex(i); i = Next(i) ) + { + pEntity->AddContext( GetName(i), GetValue(i), 0 ); + } +#else + AssertMsg( false, "CriteriaSet::WriteToEntity has not been ported from l4d2.\n" ); +#endif +} + +int CriteriaSet::InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, CriteriaSet * RESTRICT pSetOnWorld ) +{ + // Assert( pFrom ); Assert( pTo ); Assert( pSetOnWorld ); + Assert( pSetOnWorld != pFrom ); + Assert( pSetOnWorld->GetCount() == 0 ); + + if ( pFrom->m_nNumPrefixedContexts == 0 ) + { + // nothing needs to be done to it. + return 0; + } + +#ifdef DEBUG + // save this off for later error checking. + const int nPrefixedContexts = pFrom->m_nNumPrefixedContexts; +#endif + + // make enough space for the expected output quantity. + pSetOnWorld->EnsureCapacity( pFrom->m_nNumPrefixedContexts ); + + // initialize a buffer with the "world" prefix (so we can use strncpy instead of snprintf and be much faster) + char buf[80] = { 'w', 'o', 'r', 'l', 'd', '\0' }; + const unsigned int PREFIXLEN = 5; // strlen("world") + + // create a second tree that has the appropriately renamed criteria, + // then swap it into pFrom + CriteriaSet rewrite; + rewrite.EnsureCapacity( pFrom->GetCount() + 1 ); + + for ( int i = pFrom->Head(); pFrom->IsValidIndex(i); i = pFrom->Next(i) ) + { + const char *pszName = pFrom->GetName( i ); + if ( pszName[0] == CriteriaSet::kAPPLYTOWORLDPREFIX ) + { // redirect to the world contexts + V_strncpy( buf+PREFIXLEN, pszName+1, sizeof(buf) - PREFIXLEN ); + rewrite.AppendCriteria( buf, pFrom->GetValue(i), pFrom->GetWeight(i) ); + pSetOnWorld->AppendCriteria( pszName+1, pFrom->GetValue(i), pFrom->GetWeight(i) ); + buf[PREFIXLEN] = 0; + } + else + { // does not need to be fiddled; do not write back to world + rewrite.AppendCriteria( pFrom->GetNameSymbol(i), pFrom->GetValue(i), pFrom->GetWeight(i) ); + } + } + AssertMsg2( pSetOnWorld->GetCount() == nPrefixedContexts, "Count of $ persistent RR contexts is inconsistent (%d vs %d)! Call Elan.", + pSetOnWorld->GetCount(), nPrefixedContexts ); + + pFrom->m_nNumPrefixedContexts = 0; + pFrom->m_Lookup.Swap(rewrite.m_Lookup); + return pSetOnWorld->GetCount(); +} diff --git a/src/responserules/runtime/response_rules.vpc b/src/responserules/runtime/response_rules.vpc new file mode 100644 index 000000000..164f48564 --- /dev/null +++ b/src/responserules/runtime/response_rules.vpc @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// response_rules.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$macro SRCDIR "..\.." +$include "$SRCDIR\vpc_scripts\source_lib_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;..\public\responserules" + $PreprocessorDefinitions "$BASE;RR_RUNTIME" + } +} + +$Project "responserules_runtime" +{ + $Folder "Source Files" + { + $File "criteriaset.cpp" + $File "response_system.cpp" + $File "response_system.h" + $File "response_types.cpp" + $File "response_types_internal.cpp" + $File "response_types_internal.h" + $File "rr_convars.cpp" + $File "rr_response.cpp" + $File "rr_speechconcept.cpp" + $File "rrrlib.cpp" + } + + $Folder "Public Header Files" + { + $File "$SRCDIR\public\responserules\response_host_interface.h" + $File "$SRCDIR\public\responserules\response_types.h" + $File "$SRCDIR\public\responserules\rr_speechconcept.h" + } +} \ No newline at end of file diff --git a/src/responserules/runtime/response_system.cpp b/src/responserules/runtime/response_system.cpp new file mode 100644 index 000000000..b98110dae --- /dev/null +++ b/src/responserules/runtime/response_system.cpp @@ -0,0 +1,2749 @@ +//========= Copyright © 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" +#include "vstdlib/random.h" +#include "utlbuffer.h" +#include "tier1/interval.h" +#include "convar.h" +#include "fmtstr.h" +#include "generichash.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// #pragma optimize( "", off ) + +using namespace ResponseRules; +static void CC_RR_Debug_ResponseConcept_Exclude( const CCommand &args ); +static ConCommand rr_debug_responseconcept_exclude( "rr_debugresponseconcept_exclude", CC_RR_Debug_ResponseConcept_Exclude, "Set a list of concepts to exclude from rr_debugresponseconcept. Separate multiple concepts with spaces. Call with no arguments to see current list. Call 'rr_debug_responseconcept_exclude !' to reset."); +static void CC_RR_DumpHashInfo( const CCommand &args ); + +namespace ResponseRules +{ + // ick + // Wrap string lookup with a hash on the string so that all of the repetitive playerxxx type strings get bucketed out better + #define STRING_BUCKETS_COUNT 64 // Must be power of two + #define STRING_BUCKETS_MASK ( STRING_BUCKETS_COUNT - 1 ) + + CUtlRBTree g_ResponseStrings[ STRING_BUCKETS_COUNT ]; + class CResponseStringBuckets + { + public: + CResponseStringBuckets() + { + for ( int i = 0; i < ARRAYSIZE( g_ResponseStrings ); ++i ) + { + g_ResponseStrings[ i ].SetLessFunc( &StringLessThan ); + } + } + } g_ReponseStringBucketInitializer; + + const char *ResponseCopyString( const char *in ) + { + if ( !in ) + return NULL; + if ( !*in ) + return ""; + + int bucket = ( RR_HASH( in ) & STRING_BUCKETS_MASK ); + + CUtlRBTree &list = g_ResponseStrings[ bucket ]; + + int i = list.Find( in ); + if ( i != list.InvalidIndex() ) +{ + return list[i]; + } + + int len = Q_strlen( in ); + char *out = new char[ len + 1 ]; + Q_memcpy( out, in, len ); + out[ len ] = 0; + list.Insert( out ); + return out; + } +} + +IEngineEmulator *IEngineEmulator::Get() +{ + AssertMsg( IEngineEmulator::s_pSingleton, "Response rules fail: no IEngineEmulator" ); + return IEngineEmulator::s_pSingleton; +} + + +//----------------------------------------------------------------------------- +// Convars +//----------------------------------------------------------------------------- + + +ConVar rr_debugresponses( "rr_debugresponses", "0", FCVAR_NONE, "Show verbose matching output (1 for simple, 2 for rule scoring, 3 for noisy). If set to 4, it will only show response success/failure for npc_selected NPCs." ); +ConVar rr_debugrule( "rr_debugrule", "", FCVAR_NONE, "If set to the name of the rule, that rule's score will be shown whenever a concept is passed into the response rules system."); +ConVar rr_dumpresponses( "rr_dumpresponses", "0", FCVAR_NONE, "Dump all response_rules.txt and rules (requires restart)" ); +ConVar rr_debugresponseconcept( "rr_debugresponseconcept", "", FCVAR_NONE, "If set, rr_debugresponses will print only responses testing for the specified concept" ); +#define RR_DEBUGRESPONSES_SPECIALCASE 4 + + + +//----------------------------------------------------------------------------- +// Copied from SoundParametersInternal.cpp +//----------------------------------------------------------------------------- + +#define SNDLVL_PREFIX "SNDLVL_" + +struct SoundLevelLookup +{ + soundlevel_t level; + char const *name; +}; + +// NOTE: Needs to reflect the soundlevel_t enum defined in soundflags.h +static SoundLevelLookup g_pSoundLevels[] = +{ + { SNDLVL_NONE, "SNDLVL_NONE" }, + { SNDLVL_20dB, "SNDLVL_20dB" }, + { SNDLVL_25dB, "SNDLVL_25dB" }, + { SNDLVL_30dB, "SNDLVL_30dB" }, + { SNDLVL_35dB, "SNDLVL_35dB" }, + { SNDLVL_40dB, "SNDLVL_40dB" }, + { SNDLVL_45dB, "SNDLVL_45dB" }, + { SNDLVL_50dB, "SNDLVL_50dB" }, + { SNDLVL_55dB, "SNDLVL_55dB" }, + { SNDLVL_IDLE, "SNDLVL_IDLE" }, + { SNDLVL_TALKING, "SNDLVL_TALKING" }, + { SNDLVL_60dB, "SNDLVL_60dB" }, + { SNDLVL_65dB, "SNDLVL_65dB" }, + { SNDLVL_STATIC, "SNDLVL_STATIC" }, + { SNDLVL_70dB, "SNDLVL_70dB" }, + { SNDLVL_NORM, "SNDLVL_NORM" }, + { SNDLVL_75dB, "SNDLVL_75dB" }, + { SNDLVL_80dB, "SNDLVL_80dB" }, + { SNDLVL_85dB, "SNDLVL_85dB" }, + { SNDLVL_90dB, "SNDLVL_90dB" }, + { SNDLVL_95dB, "SNDLVL_95dB" }, + { SNDLVL_100dB, "SNDLVL_100dB" }, + { SNDLVL_105dB, "SNDLVL_105dB" }, + { SNDLVL_110dB, "SNDLVL_110dB" }, + { SNDLVL_120dB, "SNDLVL_120dB" }, + { SNDLVL_130dB, "SNDLVL_130dB" }, + { SNDLVL_GUNFIRE, "SNDLVL_GUNFIRE" }, + { SNDLVL_140dB, "SNDLVL_140dB" }, + { SNDLVL_150dB, "SNDLVL_150dB" }, + { SNDLVL_180dB, "SNDLVL_180dB" }, +}; + +static soundlevel_t TextToSoundLevel( const char *key ) +{ + if ( !key ) + { + Assert( 0 ); + return SNDLVL_NORM; + } + + int c = ARRAYSIZE( g_pSoundLevels ); + + int i; + + for ( i = 0; i < c; i++ ) + { + SoundLevelLookup *entry = &g_pSoundLevels[ i ]; + if ( !Q_strcasecmp( key, entry->name ) ) + return entry->level; + } + + if ( !Q_strnicmp( key, SNDLVL_PREFIX, Q_strlen( SNDLVL_PREFIX ) ) ) + { + char const *val = key + Q_strlen( SNDLVL_PREFIX ); + int sndlvl = atoi( val ); + if ( sndlvl > 0 && sndlvl <= 180 ) + { + return ( soundlevel_t )sndlvl; + } + } + + DevMsg( "CSoundEmitterSystem: Unknown sound level %s\n", key ); + + return SNDLVL_NORM; +} + +CResponseSystem::ExcludeList_t CResponseSystem::m_DebugExcludeList( 4, 0 ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CResponseSystem::CResponseSystem() : + m_RootCommandHashes( 0, 0, DefLessFunc( unsigned int ) ), + m_FileDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_RuleDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_ResponseDispatch( 0, 0, DefLessFunc( unsigned int ) ), + m_ResponseGroupDispatch( 0, 0, DefLessFunc( unsigned int ) ) +{ + token[0] = 0; + m_bUnget = false; + m_bCustomManagable = false; + + BuildDispatchTables(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CResponseSystem::~CResponseSystem() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CResponseSystem::GetCurrentScript( char *buf, size_t buflen ) +{ + Assert( buf ); + buf[ 0 ] = 0; + if ( m_ScriptStack.Count() <= 0 ) + return; + + if ( IEngineEmulator::Get()->GetFilesystem()->String( m_ScriptStack[ 0 ].name, buf, buflen ) ) + { + return; + } + buf[ 0 ] = 0; +} + +void CResponseSystem::PushScript( const char *scriptfile, unsigned char *buffer ) +{ + ScriptEntry e; + e.name = IEngineEmulator::Get()->GetFilesystem()->FindOrAddFileName( scriptfile ); + e.buffer = buffer; + e.currenttoken = (char *)e.buffer; + e.tokencount = 0; + m_ScriptStack.AddToHead( e ); +} + +void CResponseSystem::PopScript(void) +{ + Assert( m_ScriptStack.Count() >= 1 ); + if ( m_ScriptStack.Count() <= 0 ) + return; + + m_ScriptStack.Remove( 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::Clear() +{ + m_Responses.RemoveAll(); + m_Criteria.RemoveAll(); + m_RulePartitions.RemoveAll(); + m_Enumerations.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// found - +// Output : float +//----------------------------------------------------------------------------- +float CResponseSystem::LookupEnumeration( const char *name, bool& found ) +{ + int idx = m_Enumerations.Find( name ); + if ( idx == m_Enumerations.InvalidIndex() ) + { + found = false; + return 0.0f; + } + + + found = true; + return m_Enumerations[ idx ].value; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : matcher - +//----------------------------------------------------------------------------- +void CResponseSystem::ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ) +{ + if ( rawtoken[0] != '[' ) + { + Q_strncpy( token, rawtoken, bufsize ); + return; + } + + // Now lookup enumeration + bool found = false; + float f = LookupEnumeration( rawtoken, found ); + if ( !found ) + { + Q_strncpy( token, rawtoken, bufsize ); + ResponseWarning( "No such enumeration '%s'\n", token ); + return; + } + + Q_snprintf( token, bufsize, "%f", f ); +} + + +static bool AppearsToBeANumber( char const *token ) +{ + if ( atof( token ) != 0.0f ) + return true; + + char const *p = token; + while ( *p ) + { + if ( *p != '0' ) + return false; + + p++; + } + + return true; +} + +void CResponseSystem::ComputeMatcher( Criteria *c, Matcher& matcher ) +{ + const char *s = c->value; + if ( !s ) + { + matcher.valid = false; + return; + } + + const char *in = s; + + char token[ 128 ]; + char rawtoken[ 128 ]; + + token[ 0 ] = 0; + rawtoken[ 0 ] = 0; + + int n = 0; + + bool gt = false; + bool lt = false; + bool eq = false; + bool nt = false; + bool bit = false; + + bool done = false; + while ( !done ) + { + switch( *in ) + { + case '>': + { + gt = true; + Assert( !lt ); // Can't be both + } + break; + case '<': + { + lt = true; + Assert( !gt ); // Can't be both + } + break; + case '=': + { + eq = true; + } + break; + case ',': + case '\0': + { + rawtoken[ n ] = 0; + n = 0; + + // Convert raw token to real token in case token is an enumerated type specifier + ResolveToken( matcher, token, sizeof( token ), rawtoken ); + + // Bits are an entirely different and independent story + if (bit) + { + matcher.isbit = true; + matcher.notequal = nt; + + matcher.isnumeric = true; + } + else + // Fill in first data set + if ( gt ) + { + matcher.usemin = true; + matcher.minequals = eq; + matcher.minval = (float)atof( token ); + + matcher.isnumeric = true; + } + else if ( lt ) + { + matcher.usemax = true; + matcher.maxequals = eq; + matcher.maxval = (float)atof( token ); + + matcher.isnumeric = true; + } + else + { + if ( *in == ',' ) + { + // If there's a comma, this better have been a less than or a gt key + Assert( 0 ); + } + + matcher.notequal = nt; + + matcher.isnumeric = AppearsToBeANumber( token ); + } + + gt = lt = eq = nt = false; + + if ( !(*in) ) + { + done = true; + } + } + break; + case '!': + nt = true; + break; + case '~': + nt = true; + case '&': + bit = true; + break; + default: + rawtoken[ n++ ] = *in; + break; + } + + in++; + } + + matcher.SetToken( token ); + matcher.SetRaw( rawtoken ); + matcher.valid = true; +} + +bool CResponseSystem::CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose /*=false*/ ) +{ + if ( !m.valid ) + return false; + + float v = (float)atof( setValue ); + if ( setValue[0] == '[' ) + { + bool found = false; + v = LookupEnumeration( setValue, found ); + } + + // Bits are always a different story + if (m.isbit) + { + int v1 = v; + int v2 = atoi(m.GetToken()); + if (m.notequal) + return (v1 & v2) == 0; + else + return (v1 & v2) != 0; + } + + int minmaxcount = 0; + + if ( m.usemin ) + { + if ( m.minequals ) + { + if ( v < m.minval ) + return false; + } + else + { + if ( v <= m.minval ) + return false; + } + + ++minmaxcount; + } + + if ( m.usemax ) + { + if ( m.maxequals ) + { + if ( v > m.maxval ) + return false; + } + else + { + if ( v >= m.maxval ) + return false; + } + + ++minmaxcount; + } + + // Had one or both criteria and met them + if ( minmaxcount >= 1 ) + { + return true; + } + + if ( m.notequal ) + { + if ( m.isnumeric ) + { + if ( v == (float)atof( m.GetToken() ) ) + return false; + } + else + { + if ( !Q_stricmp( setValue, m.GetToken() ) ) + return false; + } + + return true; + } + + if ( m.isnumeric ) + { + // If the setValue is "", the NPC doesn't have the key at all, + // in which case we shouldn't match "0". + if ( !setValue || !setValue[0] ) + return false; + + return v == (float)atof( m.GetToken() ); + } + + return !Q_stricmp( setValue, m.GetToken() ) ? true : false; +} + +bool CResponseSystem::Compare( const char *setValue, Criteria *c, bool verbose /*= false*/ ) +{ + Assert( c ); + Assert( setValue ); + + bool bret = CompareUsingMatcher( setValue, c->matcher, verbose ); + + if ( verbose ) + { + DevMsg( "'%20s' vs. '%20s' = ", setValue, c->value ); + + { + //DevMsg( "\n" ); + //m.Describe(); + } + } + return bret; +} + +float CResponseSystem::RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ) +{ + float score = 0.0f; + int subcount = parent->subcriteria.Count(); + for ( int i = 0; i < subcount; i++ ) + { + int icriterion = parent->subcriteria[ i ]; + + bool excludesubrule = false; + if (verbose) + { + DevMsg( "\n" ); + } + score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, excludesubrule, verbose ); + } + + exclude = ( parent->required && score == 0.0f ) ? true : false; + + return score * parent->weight.GetFloat(); +} + +float CResponseSystem::RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent ) +{ + float flScore = 0.0f; + int nSubCount = pParent->subcriteria.Count(); + for ( int iSub = 0; iSub < nSubCount; ++iSub ) + { + int iCriteria = pParent->subcriteria[iSub]; + flScore += LookForCriteria( criteriaSet, iCriteria ); + } + + return flScore; +} + +float CResponseSystem::LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria ) +{ + Criteria *pCriteria = &m_Criteria[iCriteria]; + if ( pCriteria->IsSubCriteriaType() ) + { + return RecursiveLookForCriteria( criteriaSet, pCriteria ); + } + + int iIndex = criteriaSet.FindCriterionIndex( pCriteria->nameSym ); + if ( iIndex == -1 ) + return 0.0f; + + Assert( criteriaSet.GetValue( iIndex ) ); + if ( Q_stricmp( criteriaSet.GetValue( iIndex ), pCriteria->value ) ) + return 0.0f; + + return 1.0f; +} + +float CResponseSystem::ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose /*=false*/ ) +{ + Criteria *c = &m_Criteria[ icriterion ]; + + if ( c->IsSubCriteriaType() ) + { + return RecursiveScoreSubcriteriaAgainstRule( set, c, exclude, verbose ); + } + + if ( verbose ) + { + DevMsg( " criterion '%25s':'%15s' ", m_Criteria.GetElementName( icriterion ), CriteriaSet::SymbolToStr(c->nameSym) ); + } + + exclude = false; + + float score = 0.0f; + + const char *actualValue = ""; + + /* + const char * RESTRICT critname = c->name; + CUtlSymbol sym(critname); + const char * nameDoubleCheck = sym.String(); + */ + int found = set.FindCriterionIndex( c->nameSym ); + if ( found != -1 ) + { + actualValue = set.GetValue( found ); + if ( !actualValue ) + { + Assert( 0 ); + return score; + } + } + + Assert( actualValue ); + + if ( Compare( actualValue, c, verbose ) ) + { + float w = set.GetWeight( found ); + score = w * c->weight.GetFloat(); + + if ( verbose ) + { + DevMsg( "matched, weight %4.2f (s %4.2f x c %4.2f)", + score, w, c->weight.GetFloat() ); + } + } + else + { + if ( c->required ) + { + exclude = true; + if ( verbose ) + { + DevMsg( "failed (+exclude rule)" ); + } + } + else + { + if ( verbose ) + { + DevMsg( "failed" ); + } + } + } + + return score; +} + +float CResponseSystem::ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose /*=false*/ ) +{ + Rule * RESTRICT rule = dict[ irule ]; + float score = 0.0f; + + bool bBeingWatched = false; + + // See if we're trying to debug this rule + const char *pszText = rr_debugrule.GetString(); + if ( pszText && pszText[0] && !Q_stricmp( pszText, dict.GetElementName( irule ) ) ) + { + bBeingWatched = true; + } + + if ( !rule->IsEnabled() ) + { + if ( bBeingWatched ) + { + DevMsg("Rule is disabled.\n" ); + } + return 0.0f; + } + + if ( bBeingWatched ) + { + verbose = true; + } + + if ( verbose ) + { + DevMsg( "Scoring rule '%s' (%i)\n{\n", dict.GetElementName( irule ), irule+1 ); + } + + // Iterate set criteria + int count = rule->m_Criteria.Count(); + int i; + for ( i = 0; i < count; i++ ) + { + int icriterion = rule->m_Criteria[ i ]; + + bool exclude = false; + score += ScoreCriteriaAgainstRuleCriteria( set, icriterion, exclude, verbose ); + + if ( verbose ) + { + DevMsg( ", score %4.2f\n", score ); + } + + if ( exclude ) + { + score = 0.0f; + break; + } + } + + if ( verbose ) + { + DevMsg( "}\n" ); + } + + if ( rule->m_nForceWeight > 0 ) + { // this means override the cumulative weight of criteria and just force the rule's total score, + // assuming it matched at all. + return fsel( score - FLT_MIN, rule->m_nForceWeight, 0 ); + } + else + { + return score; +} +} + +void CResponseSystem::DebugPrint( int depth, const char *fmt, ... ) +{ + int indentchars = 3 * depth; + char *indent = (char *) stackalloc( indentchars + 1); + indent[ indentchars ] = 0; + while ( --indentchars >= 0 ) + { + indent[ indentchars ] = ' '; + } + + // Dump text to debugging console. + va_list argptr; + char szText[1024]; + + va_start (argptr, fmt); + Q_vsnprintf (szText, sizeof( szText ), fmt, argptr); + va_end (argptr); + + DevMsg( "%s%s", indent, szText ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::ResetResponseGroups() +{ + int i; + int c = m_Responses.Count(); + for ( i = 0; i < c; i++ ) + { + m_Responses[ i ].Reset(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Make certain responses unavailable by marking them as depleted +//----------------------------------------------------------------------------- +void CResponseSystem::FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter ) +{ + m_FakedDepletes.RemoveAll(); + + // Fake depletion of unavailable choices + int c = g->group.Count(); + if ( pFilter && g->ShouldCheckRepeats() ) + { + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( r->depletioncount != g->GetDepletionCount() && !pFilter->IsValidResponse( r->GetType(), r->value ) ) + { + m_FakedDepletes.AddToTail( i ); + g->MarkResponseUsed( i ); + } + } + } + + // Fake depletion of choices that fail the odds check + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( RandomInt( 1, 100 ) > r->params.odds ) + { + m_FakedDepletes.AddToTail( i ); + g->MarkResponseUsed( i ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Restore responses that were faked as being depleted +//----------------------------------------------------------------------------- +void CResponseSystem::RevertFakedDepletes( ResponseGroup *g ) +{ + for ( int i = 0; i < m_FakedDepletes.Count(); i++ ) + { + g->group[ m_FakedDepletes[ i ] ].depletioncount = 0; + } + m_FakedDepletes.RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *g - +// Output : int +//----------------------------------------------------------------------------- +int CResponseSystem::SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ) +{ + int c = g->group.Count(); + if ( !c ) + { + Assert( !"Expecting response group with >= 1 elements" ); + return -1; + } + + FakeDepletes( g, pFilter ); + + if ( !g->HasUndepletedChoices() ) + { + g->ResetDepletionCount(); + + FakeDepletes( g, pFilter ); + + if ( !g->HasUndepletedChoices() ) + return -1; + + // Disable the group if we looped through all the way + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); + return -1; + } + } + + bool checkrepeats = g->ShouldCheckRepeats(); + int depletioncount = g->GetDepletionCount(); + + float totalweight = 0.0f; + int slot = -1; + + if ( checkrepeats ) + { + int check= -1; + // Snag the first slot right away + if ( g->HasUndepletedFirst( check ) && check != -1 ) + { + slot = check; + } + + if ( slot == -1 && g->HasUndepletedLast( check ) && check != -1 ) + { + // If this is the only undepleted one, use it now + int i; + for ( i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( checkrepeats && + ( r->depletioncount == depletioncount ) ) + { + continue; + } + + if ( r->last ) + { + Assert( i == check ); + continue; + } + + // There's still another undepleted entry + break; + } + + // No more undepleted so use the r->last slot + if ( i >= c ) + { + slot = check; + } + } + } + + if ( slot == -1 ) + { + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &g->group[ i ]; + if ( checkrepeats && + ( r->depletioncount == depletioncount ) ) + { + continue; + } + + // Always skip last entry here since we will deal with it above + if ( checkrepeats && r->last ) + continue; + + int prevSlot = slot; + + if ( !totalweight ) + { + slot = i; + } + + // Always assume very first slot will match + totalweight += r->weight.GetFloat(); + if ( !totalweight || IEngineEmulator::Get()->GetRandomStream()->RandomFloat(0,totalweight) < r->weight.GetFloat() ) + { + slot = i; + } + + if ( !checkrepeats && slot != prevSlot && pFilter && !pFilter->IsValidResponse( r->GetType(), r->value ) ) + { + slot = prevSlot; + totalweight -= r->weight.GetFloat(); + } + } + } + + if ( slot != -1 ) + g->MarkResponseUsed( slot ); + + // Revert fake depletion of unavailable choices + RevertFakedDepletes( g ); + + return slot; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : searchResult - +// depth - +// *name - +// verbose - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CResponseSystem::ResolveResponse( ResponseSearchResult& searchResult, int depth, const char *name, bool verbose /*= false*/, IResponseFilter *pFilter ) +{ + int responseIndex = m_Responses.Find( name ); + if ( responseIndex == m_Responses.InvalidIndex() ) + return false; + + ResponseGroup *g = &m_Responses[ responseIndex ]; + // Group has been disabled + if ( !g->IsEnabled() ) + return false; + + int c = g->group.Count(); + if ( !c ) + return false; + + int idx = 0; + + if ( g->IsSequential() ) + { + // See if next index is valid + int initialIndex = g->GetCurrentIndex(); + bool bFoundValid = false; + + do + { + idx = g->GetCurrentIndex(); + g->SetCurrentIndex( idx + 1 ); + if ( idx >= c ) + { + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); + return false; + } + idx = 0; + g->SetCurrentIndex( 0 ); + } + + if ( !pFilter || pFilter->IsValidResponse( g->group[idx].GetType(), g->group[idx].value ) ) + { + bFoundValid = true; + break; + } + + } while ( g->GetCurrentIndex() != initialIndex ); + + if ( !bFoundValid ) + return false; + } + else + { + idx = SelectWeightedResponseFromResponseGroup( g, pFilter ); + if ( idx < 0 ) + return false; + } + + if ( verbose ) + { + DebugPrint( depth, "%s\n", m_Responses.GetElementName( responseIndex ) ); + DebugPrint( depth, "{\n" ); + DescribeResponseGroup( g, idx, depth ); + } + + bool bret = true; + + ParserResponse *result = &g->group[ idx ]; + if ( result->type == RESPONSE_RESPONSE ) + { + // Recurse + bret = ResolveResponse( searchResult, depth + 1, result->value, verbose, pFilter ); + } + else + { + searchResult.action = result; + searchResult.group = g; + } + + if( verbose ) + { + DebugPrint( depth, "}\n" ); + } + + return bret; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *group - +// selected - +// depth - +//----------------------------------------------------------------------------- +void CResponseSystem::DescribeResponseGroup( ResponseGroup *group, int selected, int depth ) +{ + int c = group->group.Count(); + + for ( int i = 0; i < c ; i++ ) + { + ParserResponse *r = &group->group[ i ]; + DebugPrint( depth + 1, "%s%20s : %40s %5.3f\n", + i == selected ? "-> " : " ", + CRR_Response::DescribeResponse( r->GetType() ), + r->value, + r->weight.GetFloat() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *rule - +// Output : CResponseSystem::Response +//----------------------------------------------------------------------------- +bool CResponseSystem::GetBestResponse( ResponseSearchResult& searchResult, Rule *rule, bool verbose /*=false*/, IResponseFilter *pFilter ) +{ + int c = rule->m_Responses.Count(); + if ( !c ) + return false; + + int index = IEngineEmulator::Get()->GetRandomStream()->RandomInt( 0, c - 1 ); + int groupIndex = rule->m_Responses[ index ]; + + ResponseGroup *g = &m_Responses[ groupIndex ]; + + // Group has been disabled + if ( !g->IsEnabled() ) + return false; + + int count = g->group.Count(); + if ( !count ) + return false; + + int responseIndex = 0; + + if ( g->IsSequential() ) + { + // See if next index is valid + int initialIndex = g->GetCurrentIndex(); + bool bFoundValid = false; + + do + { + responseIndex = g->GetCurrentIndex(); + g->SetCurrentIndex( responseIndex + 1 ); + if ( responseIndex >= count ) + { + if ( g->IsNoRepeat() ) + { + g->SetEnabled( false ); + return false; + } + responseIndex = 0; + g->SetCurrentIndex( 0 ); + } + + if ( !pFilter || pFilter->IsValidResponse( g->group[responseIndex].GetType(), g->group[responseIndex].value ) ) + { + bFoundValid = true; + break; + } + + } while ( g->GetCurrentIndex() != initialIndex ); + + if ( !bFoundValid ) + return false; + } + else + { + responseIndex = SelectWeightedResponseFromResponseGroup( g, pFilter ); + if ( responseIndex < 0 ) + return false; + } + + + ParserResponse *r = &g->group[ responseIndex ]; + + int depth = 0; + + if ( verbose ) + { + DebugPrint( depth, "%s\n", m_Responses.GetElementName( groupIndex ) ); + DebugPrint( depth, "{\n" ); + + DescribeResponseGroup( g, responseIndex, depth ); + } + + bool bret = true; + + if ( r->type == RESPONSE_RESPONSE ) + { + bret = ResolveResponse( searchResult, depth + 1, r->value, verbose, pFilter ); + } + else + { + searchResult.action = r; + searchResult.group = g; + } + + if ( verbose ) + { + DebugPrint( depth, "}\n" ); + } + + return bret; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : set - +// verbose - +// Output : int +// Warning: If you change this, be sure to also change +// ResponseSystemImplementationCLI::FindAllRulesMatchingCriteria(). +//----------------------------------------------------------------------------- +ResponseRulePartition::tIndex CResponseSystem::FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule ) +{ + CUtlVector< ResponseRulePartition::tIndex > bestrules(16,4); + float bestscore = 0.001f; + scoreOfBestMatchingRule = 0; + + CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > buckets( 0, 2 ); + m_RulePartitions.GetDictsForCriteria( &buckets, set ); + for ( int b = 0 ; b < buckets.Count() ; ++b ) + { + ResponseRulePartition::tRuleDict *prules = buckets[b]; + int c = prules->Count(); + int i; + for ( i = 0; i < c; i++ ) + { + float score = ScoreCriteriaAgainstRule( set, *prules, i, verbose ); + // Check equals so that we keep track of all matching rules + if ( score >= bestscore ) + { + // Reset bucket + if( score != bestscore ) + { + bestscore = score; + bestrules.RemoveAll(); + } + + // Add to bucket + bestrules.AddToTail( m_RulePartitions.IndexFromDictElem( prules, i ) ); + } + } + } + + int bestCount = bestrules.Count(); + if ( bestCount <= 0 ) + return m_RulePartitions.InvalidIdx(); + + scoreOfBestMatchingRule = bestscore ; + if ( bestCount == 1 ) + { + return bestrules[ 0 ] ; + } + else + { + // Randomly pick one of the tied matching rules + int idx = IEngineEmulator::Get()->GetRandomStream()->RandomInt( 0, bestCount - 1 ); + if ( verbose ) + { + DevMsg( "Found %i matching rules, selecting slot %i\n", bestCount, idx ); + } + return bestrules[ idx ] ; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : set - +// Output : CRR_Response +//----------------------------------------------------------------------------- +bool CResponseSystem::FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter ) +{ + bool valid = false; + + int iDbgResponse = rr_debugresponses.GetInt(); + bool showRules = ( iDbgResponse >= 2 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ); + bool showResult = ( iDbgResponse >= 1 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ); + + // Look for match. verbose mode used to be at level 2, but disabled because the writers don't actually care for that info. + float scoreOfBestRule; + ResponseRulePartition::tIndex bestRule = FindBestMatchingRule( set, + ( iDbgResponse >= 3 && iDbgResponse < RR_DEBUGRESPONSES_SPECIALCASE ), + scoreOfBestRule ); + + ResponseType_t responseType = RESPONSE_NONE; + ResponseParams rp; + + char ruleName[ 128 ]; + char responseName[ 128 ]; + const char *context; + int iApplyContext; + ruleName[ 0 ] = 0; + responseName[ 0 ] = 0; + context = NULL; + iApplyContext = 0; + if ( m_RulePartitions.IsValid( bestRule ) ) + { + Rule * RESTRICT r = &m_RulePartitions[ bestRule ]; + + ResponseSearchResult result; + if ( GetBestResponse( result, r, showResult, pFilter ) ) + { + Q_strncpy( responseName, result.action->value, sizeof( responseName ) ); + responseType = result.action->GetType(); + rp = result.action->params; + rp.m_pFollowup = &result.action->m_followup; + } + + Q_strncpy( ruleName, m_RulePartitions.GetElementName( bestRule ), sizeof( ruleName ) ); + + // Disable the rule if it only allows for matching one time + if ( r->IsMatchOnce() ) + { + r->Disable(); + } + context = r->GetContext(); + iApplyContext = r->m_iContextFlags; + + response.SetMatchScore(scoreOfBestRule); + valid = true; + } + + response.Init( responseType, responseName, rp, ruleName, context, iApplyContext); + + if ( showResult ) + { + /* + // clipped -- chet doesn't really want this info + if ( valid ) + { + // Rescore the winner and dump to console + ScoreCriteriaAgainstRule( set, bestRule, true ); + } + */ + + + if ( valid || showRules ) + { + const char *pConceptFilter = rr_debugresponseconcept.GetString(); + // Describe the response, too + if ( V_strlen(pConceptFilter) > 0 && !rr_debugresponseconcept.GetBool() ) + { // filter for only one concept + if ( V_stricmp(pConceptFilter, set.GetValue(set.FindCriterionIndex("concept")) ) == 0 ) + { + response.Describe(&set); + } // else don't print + } + else + { + // maybe we need to filter *out* some concepts + if ( m_DebugExcludeList.IsValidIndex( m_DebugExcludeList.Head() ) ) + { + // we are excluding at least one concept + CRR_Concept test( set.GetValue(set.FindCriterionIndex("concept")) ); + if ( ! m_DebugExcludeList.IsValidIndex( m_DebugExcludeList.Find( test ) ) ) + { // if not found in exclude list, then print + response.Describe(&set); + } + } + else + { + // describe everything + response.Describe(&set); + } + } + } + } + + return valid; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::GetAllResponses( CUtlVector *pResponses ) +{ + for ( int i = 0; i < (int)m_Responses.Count(); i++ ) + { + ResponseGroup &group = m_Responses[i]; + + for ( int j = 0; j < group.group.Count(); j++) + { + ParserResponse &response = group.group[j]; + if ( response.type != RESPONSE_RESPONSE ) + { + /* + CRR_Response *pResponse = new CRR_Response; + pResponse->Init( response.GetType(), response.value, CriteriaSet(), response.params, NULL, NULL, false ); + pResponses->AddToTail(pResponse); + */ + pResponses->Element(pResponses->AddToTail()).Init( response.GetType(), response.value, response.params, NULL, NULL, false ); + } + } + } +} + +void CResponseSystem::ParseInclude() +{ + char includefile[ 256 ]; + ParseToken(); + Q_snprintf( includefile, sizeof( includefile ), "scripts/%s", token ); + + // check if the file is already included + if ( m_IncludedFiles.Find( includefile ) != NULL ) + { + return; + } + + MEM_ALLOC_CREDIT(); + + // Try and load it + CUtlBuffer buf; + if ( !IEngineEmulator::Get()->GetFilesystem()->ReadFile( includefile, "GAME", buf ) ) + { + DevMsg( "Unable to load #included script %s\n", includefile ); + return; + } + + LoadFromBuffer( includefile, (const char *)buf.PeekGet() ); +} + +void CResponseSystem::LoadFromBuffer( const char *scriptfile, const char *buffer ) +{ + COM_TimestampedLog( "CResponseSystem::LoadFromBuffer [%s] - Start", scriptfile ); + m_IncludedFiles.Allocate( scriptfile ); + PushScript( scriptfile, (unsigned char * )buffer ); + + if( rr_dumpresponses.GetBool() ) + { + DevMsg("Reading: %s\n", scriptfile ); + } + + while ( 1 ) + { + ParseToken(); + if ( !token[0] ) + { + break; + } + + unsigned int hash = RR_HASH( token ); + bool bSuccess = Dispatch( token, hash, m_FileDispatch ); + if ( !bSuccess ) + { + int byteoffset = m_ScriptStack[ 0 ].currenttoken - (const char *)m_ScriptStack[ 0 ].buffer; + + Error( "CResponseSystem::LoadFromBuffer: Unknown entry type '%s', expecting 'response', 'criterion', 'enumeration' or 'rules' in file %s(offset:%i)\n", + token, scriptfile, byteoffset ); + break; + } + } + + if ( m_ScriptStack.Count() == 1 ) + { + char cur[ 256 ]; + GetCurrentScript( cur, sizeof( cur ) ); + DevMsg( 1, "CResponseSystem: %s (%i rules, %i criteria, and %i responses)\n", + cur, m_RulePartitions.Count(), m_Criteria.Count(), m_Responses.Count() ); + + if( rr_dumpresponses.GetBool() ) + { + DumpRules(); + } + } + + PopScript(); + COM_TimestampedLog( "CResponseSystem::LoadFromBuffer [%s] - Finish", scriptfile ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::LoadRuleSet( const char *basescript ) +{ + float flStart = Plat_FloatTime(); + int length = 0; + unsigned char *buffer = (unsigned char *)IEngineEmulator::Get()->LoadFileForMe( basescript, &length ); + if ( length <= 0 || !buffer ) + { + DevMsg( 1, "CResponseSystem: failed to load %s\n", basescript ); + return; + } + + m_IncludedFiles.FreeAll(); + LoadFromBuffer( basescript, (const char *)buffer ); + + IEngineEmulator::Get()->FreeFile( buffer ); + + Assert( m_ScriptStack.Count() == 0 ); + float flEnd = Plat_FloatTime(); + COM_TimestampedLog( "CResponseSystem::LoadRuleSet took %f msec", 1000.0f * ( flEnd - flStart ) ); +} + +inline ResponseType_t ComputeResponseType( const char *s ) +{ + switch ( s[ 0 ] ) + { + default: + break; + case 's': + switch ( s[ 1 ] ) + { + default: + break; + case 'c': + return RESPONSE_SCENE; + case 'e': + return RESPONSE_SENTENCE; + case 'p': + return RESPONSE_SPEAK; + } + break; + case 'r': + return RESPONSE_RESPONSE; + case 'p': + return RESPONSE_PRINT; + case 'e': + return RESPONSE_ENTITYIO; + } + + return RESPONSE_NONE; +} + +void CResponseSystem::ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + newResponse.weight.SetFloat( (float)atof( token ) ); +} + +void CResponseSystem::ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; + rp->predelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.start = 0; + rp->delay.range = 0; +} + +void CResponseSystem::ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.start = AIS_DEF_MIN_DELAY; + rp->delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); +} + +void CResponseSystem::ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + rp->delay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_SPEAKONCE; +} + +void CResponseSystem::ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_DONT_USE_SCENE; +} + +void CResponseSystem::ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + rp->flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; +} + +void CResponseSystem::ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_ODDS; + rp->odds = clamp( atoi( token ), 0, 100 ); +} + +void CResponseSystem::ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_RESPEAKDELAY; + rp->respeakdelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_WEAPONDELAY; + rp->weapondelay.FromInterval( ReadInterval( token ) ); +} + +void CResponseSystem::ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + ParseToken(); + rp->flags |= AI_ResponseParams::RG_SOUNDLEVEL; + rp->soundlevel = (soundlevel_t)TextToSoundLevel( token ); +} + +void CResponseSystem::ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + newResponse.first = true; + group.m_bHasFirst = true; +} + +void CResponseSystem::ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + newResponse.last = true; + group.m_bHasLast= true; +} + +void CResponseSystem::ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + // get target name + bool bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityiotarget = ResponseCopyString(token); + + bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityioinput = ResponseCopyString(token); + + bSuc = ParseToken(); + if (!bSuc) + { + ResponseWarning( "FIRE token in response needs exactly three parameters." ); + return; + } + newResponse.m_followup.followup_entityiodelay = atof( token ); + /* + m_followup.followup_entityioinput = ResponseCopyString(src.m_followup.followup_entityioinput); + m_followup.followup_entityiotarget = ResponseCopyString(src.m_followup.followup_entityiotarget); + */ +} + +void CResponseSystem::ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + // eg, "subject TALK_ANSWER saidunplant:1 3" + bool bSuc = ParseToken(); + if (!bSuc) + { + AssertMsg(false, "THEN token in response lacked any further info.\n"); + ResponseWarning( "THEN token in response lacked any further info.\n" ); + return; + } + + newResponse.m_followup.followup_target = ResponseCopyString(token); + + bSuc = ParseToken(); // get another token + if (!bSuc) + { + AssertMsg1(false, "THEN token in response had a target '%s', but lacked any further info.\n", newResponse.m_followup.followup_target ); + ResponseWarning( "THEN token in response had a target '%s', but lacked any further info.\n", newResponse.m_followup.followup_target ); + return; + } + + newResponse.m_followup.followup_concept = ResponseCopyString( token ); + + + // Okay, this is totally asinine. + // Because the ParseToken() function will split foo:bar into three tokens + // (which is reasonable), but we have no safe way to parse the file otherwise + // because it's all behind an engine interface, it's necessary to parse all + // the tokens to the end of the line and catenate them, except for the last one + // which is the delay. That's crap. + bSuc = ParseToken(); + if (!bSuc) + { + AssertMsg(false, "THEN token in response lacked contexts.\n"); + ResponseWarning( "THEN token in response lacked contexts.\n" ); + return; + } + + // okay, as long as there is at least one more token, catenate the ones we + // see onto a temporary buffer. When we're down to the last token, that is + // the delay. + char buf[4096]; + buf[0] = '\0'; + while ( TokenWaiting() ) + { + Q_strncat( buf, token, 4096 ); + bSuc = ParseToken(); + AssertMsg(bSuc, "Token parsing mysteriously failed."); + } + + // down here, token is the last token, and buf is everything up to there. + newResponse.m_followup.followup_contexts = ResponseCopyString( buf ); + + newResponse.m_followup.followup_delay = atof( token ); +} + +void CResponseSystem::ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams ) +{ + ParserResponse &newResponse = group.group[ group.group.AddToTail() ]; + newResponse.weight.SetFloat( 1.0f ); + // inherit from group if appropriate + if (defaultParams) + { + newResponse.params = *defaultParams; + } + + ResponseParams *rp = &newResponse.params; + + newResponse.type = ComputeResponseType( token ); + if ( RESPONSE_NONE == newResponse.type ) +{ + ResponseWarning( "response entry '%s' with unknown response type '%s'\n", responseGroupName, token ); + return; +} + + ParseToken(); + newResponse.value = ResponseCopyString( token ); + + while ( TokenWaiting() ) + { + ParseToken(); + + unsigned int hash = RR_HASH( token ); + if ( DispatchParseResponse( token, hash, m_ResponseDispatch, newResponse, group, rp ) ) + { + continue; + } + + ResponseWarning( "response entry '%s' with unknown command '%s'\n", responseGroupName, token ); + } + +} + +void CResponseSystem::ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + if ( !Q_stricmp( token, "permitrepeats" ) ) + { + newGroup.m_bDepleteBeforeRepeat = false; + continue; + } + else if ( !Q_stricmp( token, "sequential" ) ) + { + newGroup.SetSequential( true ); + continue; + } + else if ( !Q_stricmp( token, "norepeat" ) ) + { + newGroup.SetNoRepeat( true ); + continue; + } + + ParseOneResponse( responseGroupName, newGroup ); + } + } + +void CResponseSystem::ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYBEFORESPEAK; + groupResponseParams.predelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.start = 0; + groupResponseParams.delay.range = 0; + } + +void CResponseSystem::ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.start = AIS_DEF_MIN_DELAY; + groupResponseParams.delay.range = ( AIS_DEF_MAX_DELAY - AIS_DEF_MIN_DELAY ); + } + +void CResponseSystem::ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_DELAYAFTERSPEAK; + groupResponseParams.delay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_SPEAKONCE; + } + +void CResponseSystem::ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_DONT_USE_SCENE; + } + +void CResponseSystem::ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + groupResponseParams.flags |= AI_ResponseParams::RG_STOP_ON_NONIDLE; + } + +void CResponseSystem::ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_ODDS; + groupResponseParams.odds = clamp( atoi( token ), 0, 100 ); + } + +void CResponseSystem::ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_RESPEAKDELAY; + groupResponseParams.respeakdelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_WEAPONDELAY; + groupResponseParams.weapondelay.FromInterval( ReadInterval( token ) ); + } + +void CResponseSystem::ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ) + { + ParseToken(); + groupResponseParams.flags |= AI_ResponseParams::RG_SOUNDLEVEL; + groupResponseParams.soundlevel = (soundlevel_t)TextToSoundLevel( token ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::ParseResponse( void ) +{ + AI_ResponseParams groupResponseParams; // default response parameters inherited from single line format for group + + // Should have groupname at start + ParseToken(); + char responseGroupName[ 128 ]; + Q_strncpy( responseGroupName, token, sizeof( responseGroupName ) ); + + int slot = m_Responses.Insert( responseGroupName ); + ResponseGroup &newGroup = m_Responses[ slot ]; + + while ( 1 ) + { + ParseToken(); + + unsigned int hash = RR_HASH( token ); + + // Oops, part of next definition + if( IsRootCommand( hash ) ) + { + Unget(); + break; + } + + if ( DispatchParseResponseGroup( token, hash, m_ResponseGroupDispatch, responseGroupName, newGroup, groupResponseParams ) ) + { + continue; + } + ParseOneResponse( responseGroupName, newGroup ); + } + } + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *criterion - +//----------------------------------------------------------------------------- +int CResponseSystem::ParseOneCriterion( const char *criterionName ) +{ + char key[ 128 ]; + char value[ 128 ]; + + Criteria *pNewCriterion = NULL; + + int idx; + if ( m_Criteria.Find( criterionName ) != m_Criteria.InvalidIndex() ) + { + static Criteria dummy; + pNewCriterion = &dummy; + + ResponseWarning( "Multiple definitions for criteria '%s' [%d]\n", criterionName, RR_HASH( criterionName ) ); + idx = m_Criteria.InvalidIndex(); + } + else + { + idx = m_Criteria.Insert( criterionName ); + pNewCriterion = &m_Criteria[ idx ]; + } + + bool gotbody = false; + + while ( TokenWaiting() || !gotbody ) + { + ParseToken(); + + // Oops, part of next definition + if( IsRootCommand() ) + { + Unget(); + break; + } + + if ( !Q_stricmp( token, "{" ) ) + { + gotbody = true; + + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + // Look up subcriteria index + int idx = m_Criteria.Find( token ); + if ( idx != m_Criteria.InvalidIndex() ) + { + pNewCriterion->subcriteria.AddToTail( idx ); + } + else + { + ResponseWarning( "Skipping unrecongized subcriterion '%s' in '%s'\n", token, criterionName ); + } + } + continue; + } + else if ( !Q_stricmp( token, "required" ) ) + { + pNewCriterion->required = true; + } + else if ( !Q_stricmp( token, "weight" ) ) + { + ParseToken(); + pNewCriterion->weight.SetFloat( (float)atof( token ) ); + } + else + { + Assert( pNewCriterion->subcriteria.Count() == 0 ); + + // Assume it's the math info for a non-subcriteria resposne + Q_strncpy( key, token, sizeof( key ) ); + ParseToken(); + Q_strncpy( value, token, sizeof( value ) ); + + V_strlower( key ); + pNewCriterion->nameSym = CriteriaSet::ComputeCriteriaSymbol( key ); + pNewCriterion->value = ResponseCopyString( value ); + + gotbody = true; + } + } + + if ( !pNewCriterion->IsSubCriteriaType() ) + { + ComputeMatcher( pNewCriterion, pNewCriterion->matcher ); + } + + return idx; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseCriterion( void ) +{ + // Should have groupname at start + char criterionName[ 128 ]; + ParseToken(); + Q_strncpy( criterionName, token, sizeof( criterionName ) ); + + ParseOneCriterion( criterionName ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseEnumeration( void ) +{ + char enumerationName[ 128 ]; + ParseToken(); + Q_strncpy( enumerationName, token, sizeof( enumerationName ) ); + + ParseToken(); + if ( Q_stricmp( token, "{" ) ) + { + ResponseWarning( "Expecting '{' in enumeration '%s', got '%s'\n", enumerationName, token ); + return; + } + + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + break; + + if ( Q_strlen( token ) <= 0 ) + { + ResponseWarning( "Expecting more tokens in enumeration '%s'\n", enumerationName ); + break; + } + + char key[ 128 ]; + + Q_strncpy( key, token, sizeof( key ) ); + ParseToken(); + float value = (float)atof( token ); + + char sz[ 128 ]; + Q_snprintf( sz, sizeof( sz ), "[%s::%s]", enumerationName, key ); + Q_strlower( sz ); + + Enumeration newEnum; + newEnum.value = value; + + if ( m_Enumerations.Find( sz ) == m_Enumerations.InvalidIndex() ) + { + m_Enumerations.Insert( sz, newEnum ); + } + /* + else + { + ResponseWarning( "Ignoring duplication enumeration '%s'\n", sz ); + } + */ + } +} + +void CResponseSystem::ParseRule_MatchOnce( Rule &newRule ) + { + newRule.m_bMatchOnce = true; + } + +void CResponseSystem::ParseRule_ApplyContextToWorld( Rule &newRule ) + { + newRule.m_iContextFlags |= APPLYCONTEXT_WORLD; + } + +void ResponseRules::CResponseSystem::ParseRule_ApplyContextToSelf(Rule& newRule) +{ + newRule.m_iContextFlags |= APPLYCONTEXT_SELF; +} + +void ResponseRules::CResponseSystem::ParseRule_ApplyContextToSquad(Rule& newRule) +{ + newRule.m_iContextFlags |= APPLYCONTEXT_SQUAD; +} + +void ResponseRules::CResponseSystem::ParseRule_ApplyContextToEnemy(Rule& newRule) +{ + newRule.m_iContextFlags |= APPLYCONTEXT_ENEMY; +} + +void CResponseSystem::ParseRule_ApplyContext( Rule &newRule ) + { + ParseToken(); + if ( newRule.GetContext() == NULL ) + { + newRule.SetContext( token ); + } + else + { + CFmtStrN<1024> newContext( "%s,%s", newRule.GetContext(), token ); + newRule.SetContext( newContext ); + } + } + +void CResponseSystem::ParseRule_Response( Rule &newRule ) + { + // Read them until we run out. + while ( TokenWaiting() ) + { + ParseToken(); + int idx = m_Responses.Find( token ); + if ( idx != m_Responses.InvalidIndex() ) + { + MEM_ALLOC_CREDIT(); + newRule.m_Responses.AddToTail( idx ); + } + else + { + m_bParseRuleValid = false; + ResponseWarning( "No such response '%s' for rule '%s'\n", token, m_pParseRuleName ); + } + } +} + +/* +void CResponseSystem::ParseRule_ForceWeight( Rule &newRule ) +{ + ParseToken(); + if ( token[0] == 0 ) + { + // no token followed forceweight? + ResponseWarning( "Forceweight token in rule '%s' did not specify a numerical weight! Ignoring.\n", m_pParseRuleName ); + } + else + { + newRule.m_nForceWeight = atoi(token); + if ( newRule.m_nForceWeight == 0 ) + { + ResponseWarning( "Rule '%s' had forceweight '%s', which doesn't work out to a nonzero number. Ignoring.\n", + m_pParseRuleName, token ); + } + } + } +*/ + +void CResponseSystem::ParseRule_Criteria( Rule &newRule ) + { + // Read them until we run out. + while ( TokenWaiting() ) + { + ParseToken(); + + int idx = m_Criteria.Find( token ); + if ( idx != m_Criteria.InvalidIndex() ) + { + MEM_ALLOC_CREDIT(); + newRule.m_Criteria.AddToTail( idx ); + } + else + { + m_bParseRuleValid = false; + ResponseWarning( "No such criterion '%s' for rule '%s'\n", token, m_pParseRuleName ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *kv - +//----------------------------------------------------------------------------- +void CResponseSystem::ParseRule( void ) +{ + static int instancedCriteria = 0; + + char ruleName[ 128 ]; + ParseToken(); + Q_strncpy( ruleName, token, sizeof( ruleName ) ); + + ParseToken(); + if ( Q_stricmp( token, "{" ) ) + { + ResponseWarning( "Expecting '{' in rule '%s', got '%s'\n", ruleName, token ); + return; + } + + // entries are "criteria", "response" or an in-line criteria to instance + Rule *newRule = new Rule; + + char sz[ 128 ]; + + m_bParseRuleValid = true; + m_pParseRuleName = ruleName; + while ( 1 ) + { + ParseToken(); + if ( !Q_stricmp( token, "}" ) ) + { + break; + } + + if ( Q_strlen( token ) <= 0 ) + { + ResponseWarning( "Expecting more tokens in rule '%s'\n", ruleName ); + break; + } + + unsigned int hash = RR_HASH( token ); + if ( DispatchParseRule( token, hash, m_RuleDispatch, *newRule ) ) + continue; + + // It's an inline criteria, generate a name and parse it in + Q_snprintf( sz, sizeof( sz ), "[%s%03i]", ruleName, ++instancedCriteria ); + Unget(); + int idx = ParseOneCriterion( sz ); + if ( idx != m_Criteria.InvalidIndex() ) + { + newRule->m_Criteria.AddToTail( idx ); + } + } + + if ( m_bParseRuleValid ) + { + m_RulePartitions.GetDictForRule( this, newRule ).Insert( ruleName, newRule ); + } + else + { + DevMsg( "Discarded rule %s\n", ruleName ); + delete newRule; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CResponseSystem::GetCurrentToken() const +{ + if ( m_ScriptStack.Count() <= 0 ) + return -1; + + return m_ScriptStack[ 0 ].tokencount; +} + + +void CResponseSystem::ResponseWarning( const char *fmt, ... ) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, fmt); + Q_vsnprintf(string, sizeof(string), fmt,argptr); + va_end (argptr); + + char cur[ 256 ]; + GetCurrentScript( cur, sizeof( cur ) ); + DevMsg( 1, "%s(token %i) : %s", cur, GetCurrentToken(), string ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) +{ + // Add criteria from this rule to global list in custom response system. + int nCriteriaCount = pSrcRule->m_Criteria.Count(); + for ( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) + { + int iSrcIndex = pSrcRule->m_Criteria[iCriteria]; + Criteria *pSrcCriteria = &m_Criteria[iSrcIndex]; + if ( pSrcCriteria ) + { + int iIndex = pCustomSystem->m_Criteria.Find( m_Criteria.GetElementName( iSrcIndex ) ); + if ( iIndex != pCustomSystem->m_Criteria.InvalidIndex() ) + { + pDstRule->m_Criteria.AddToTail( iIndex ); + continue; + } + + // Add the criteria. + Criteria dstCriteria; + + dstCriteria.nameSym = pSrcCriteria->nameSym ; + dstCriteria.value = ResponseCopyString( pSrcCriteria->value ); + dstCriteria.weight = pSrcCriteria->weight; + dstCriteria.required = pSrcCriteria->required; + dstCriteria.matcher = pSrcCriteria->matcher; + + int nSubCriteriaCount = pSrcCriteria->subcriteria.Count(); + for ( int iSubCriteria = 0; iSubCriteria < nSubCriteriaCount; ++iSubCriteria ) + { + int iSrcSubIndex = pSrcCriteria->subcriteria[iSubCriteria]; + Criteria *pSrcSubCriteria = &m_Criteria[iSrcSubIndex]; + if ( pSrcCriteria ) + { + int iSubIndex = pCustomSystem->m_Criteria.Find( pSrcSubCriteria->value ); + if ( iSubIndex != pCustomSystem->m_Criteria.InvalidIndex() ) + continue; + + // Add the criteria. + Criteria dstSubCriteria; + + dstSubCriteria.nameSym = pSrcSubCriteria->nameSym ; + dstSubCriteria.value = ResponseCopyString( pSrcSubCriteria->value ); + dstSubCriteria.weight = pSrcSubCriteria->weight; + dstSubCriteria.required = pSrcSubCriteria->required; + dstSubCriteria.matcher = pSrcSubCriteria->matcher; + + int iSubInsertIndex = pCustomSystem->m_Criteria.Insert( pSrcSubCriteria->value, dstSubCriteria ); + dstCriteria.subcriteria.AddToTail( iSubInsertIndex ); + } + } + + int iInsertIndex = pCustomSystem->m_Criteria.Insert( m_Criteria.GetElementName( iSrcIndex ), dstCriteria ); + pDstRule->m_Criteria.AddToTail( iInsertIndex ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ) +{ + // Add responses from this rule to global list in custom response system. + int nResponseGroupCount = pSrcRule->m_Responses.Count(); + for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) + { + int iSrcResponseGroup = pSrcRule->m_Responses[iResponseGroup]; + ResponseGroup *pSrcResponseGroup = &m_Responses[iSrcResponseGroup]; + if ( pSrcResponseGroup ) + { + // Add response group. + ResponseGroup dstResponseGroup; + + dstResponseGroup.m_bDepleteBeforeRepeat = pSrcResponseGroup->m_bDepleteBeforeRepeat; + dstResponseGroup.m_nDepletionCount = pSrcResponseGroup->m_nDepletionCount; + dstResponseGroup.m_bHasFirst = pSrcResponseGroup->m_bHasFirst; + dstResponseGroup.m_bHasLast = pSrcResponseGroup->m_bHasLast; + dstResponseGroup.m_bSequential = pSrcResponseGroup->m_bSequential; + dstResponseGroup.m_bNoRepeat = pSrcResponseGroup->m_bNoRepeat; + dstResponseGroup.m_bEnabled = pSrcResponseGroup->m_bEnabled; + dstResponseGroup.m_nCurrentIndex = pSrcResponseGroup->m_nCurrentIndex; + + int nSrcResponseCount = pSrcResponseGroup->group.Count(); + for ( int iResponse = 0; iResponse < nSrcResponseCount; ++iResponse ) + { + ParserResponse *pSrcResponse = &pSrcResponseGroup->group[iResponse]; + if ( pSrcResponse ) + { + // Add Response + ParserResponse dstResponse; + + dstResponse.weight = pSrcResponse->weight; + dstResponse.type = pSrcResponse->type; + dstResponse.value = ResponseCopyString( pSrcResponse->value ); + dstResponse.depletioncount = pSrcResponse->depletioncount; + dstResponse.first = pSrcResponse->first; + dstResponse.last = pSrcResponse->last; + + dstResponseGroup.group.AddToTail( dstResponse ); + } + } + + int iInsertIndex = pCustomSystem->m_Responses.Insert( m_Responses.GetElementName( iSrcResponseGroup ), dstResponseGroup ); + pDstRule->m_Responses.AddToTail( iInsertIndex ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyEnumerationsFrom( CResponseSystem *pCustomSystem ) +{ + int nEnumerationCount = m_Enumerations.Count(); + for ( int iEnumeration = 0; iEnumeration < nEnumerationCount; ++iEnumeration ) + { + Enumeration *pSrcEnumeration = &m_Enumerations[iEnumeration]; + if ( pSrcEnumeration ) + { + Enumeration dstEnumeration; + dstEnumeration.value = pSrcEnumeration->value; + pCustomSystem->m_Enumerations.Insert( m_Enumerations.GetElementName( iEnumeration ), dstEnumeration ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CResponseSystem::CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem ) +{ + // Verify data. + Assert( pSrcRule ); + Assert( pCustomSystem ); + if ( !pSrcRule || !pCustomSystem ) + return; + + // New rule + Rule *dstRule = new Rule; + + dstRule->SetContext( pSrcRule->GetContext() ); + dstRule->m_bMatchOnce = pSrcRule->m_bMatchOnce; + dstRule->m_bEnabled = pSrcRule->m_bEnabled; + dstRule->m_iContextFlags = pSrcRule->m_iContextFlags; + + // Copy off criteria. + CopyCriteriaFrom( pSrcRule, dstRule, pCustomSystem ); + + // Copy off responses. + CopyResponsesFrom( pSrcRule, dstRule, pCustomSystem ); + + // Copy off enumerations - Don't think we use these. + // CopyEnumerationsFrom( pCustomSystem ); + + // Add rule. + pCustomSystem->m_RulePartitions.GetDictForRule( this, dstRule ).Insert( m_RulePartitions.GetElementName( iRule ), dstRule ); +} + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::DumpRules() +{ + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + Msg("%s\n", m_RulePartitions.GetElementName( idx ) ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CResponseSystem::DumpDictionary( const char *pszName ) +{ + Msg( "\nDictionary: %s\n", pszName ); + + // int nRuleCount = m_Rules.Count(); + // for ( int iRule = 0; iRule < nRuleCount; ++iRule ) + for ( ResponseRulePartition::tIndex idx = m_RulePartitions.First() ; + m_RulePartitions.IsValid(idx) ; + idx = m_RulePartitions.Next(idx) ) + { + Msg(" Rule %d/%d: %s\n", m_RulePartitions.BucketFromIdx(idx), m_RulePartitions.PartFromIdx( idx ), m_RulePartitions.GetElementName( idx ) ); + + Rule *pRule = &m_RulePartitions[idx]; + + int nCriteriaCount = pRule->m_Criteria.Count(); + for( int iCriteria = 0; iCriteria < nCriteriaCount; ++iCriteria ) + { + int iRuleCriteria = pRule->m_Criteria[iCriteria]; + Criteria *pCriteria = &m_Criteria[iRuleCriteria]; + Msg( " Criteria %d: %s %s\n", iCriteria, CriteriaSet::SymbolToStr(pCriteria->nameSym), pCriteria->value ); + } + + int nResponseGroupCount = pRule->m_Responses.Count(); + for ( int iResponseGroup = 0; iResponseGroup < nResponseGroupCount; ++iResponseGroup ) + { + int iRuleResponse = pRule->m_Responses[iResponseGroup]; + ResponseGroup *pResponseGroup = &m_Responses[iRuleResponse]; + + Msg( " ResponseGroup %d: %s\n", iResponseGroup, m_Responses.GetElementName( iRuleResponse ) ); + + int nResponseCount = pResponseGroup->group.Count(); + for ( int iResponse = 0; iResponse < nResponseCount; ++iResponse ) + { + ParserResponse *pResponse = &pResponseGroup->group[iResponse]; + Msg( " Response %d: %s\n", iResponse, pResponse->value ); + } + } + } +} + +void CResponseSystem::BuildDispatchTables() +{ + m_RootCommandHashes.Insert( RR_HASH( "#include" ) ); + m_RootCommandHashes.Insert( RR_HASH( "response" ) ); + m_RootCommandHashes.Insert( RR_HASH( "enumeration" ) ); + m_RootCommandHashes.Insert( RR_HASH( "criterion" ) ); + m_RootCommandHashes.Insert( RR_HASH( "criteria" ) ); + m_RootCommandHashes.Insert( RR_HASH( "rule" ) ); + + m_FileDispatch.Insert( RR_HASH( "#include" ), &CResponseSystem::ParseInclude ); + m_FileDispatch.Insert( RR_HASH( "response" ), &CResponseSystem::ParseResponse ); + m_FileDispatch.Insert( RR_HASH( "criterion" ), &CResponseSystem::ParseCriterion ); + m_FileDispatch.Insert( RR_HASH( "criteria" ), &CResponseSystem::ParseCriterion ); + m_FileDispatch.Insert( RR_HASH( "rule" ), &CResponseSystem::ParseRule ); + m_FileDispatch.Insert( RR_HASH( "enumeration" ), &CResponseSystem::ParseEnumeration ); + + m_RuleDispatch.Insert( RR_HASH( "matchonce" ), &CResponseSystem::ParseRule_MatchOnce ); + m_RuleDispatch.Insert( RR_HASH( "applycontexttoworld" ), &CResponseSystem::ParseRule_ApplyContextToWorld ); + m_RuleDispatch.Insert(RR_HASH("applycontexttoself"), &CResponseSystem::ParseRule_ApplyContextToSelf); + m_RuleDispatch.Insert(RR_HASH("applycontexttosquad"), &CResponseSystem::ParseRule_ApplyContextToSquad); + m_RuleDispatch.Insert(RR_HASH("applycontexttoenemy"), &CResponseSystem::ParseRule_ApplyContextToEnemy); + m_RuleDispatch.Insert( RR_HASH( "applycontext" ), &CResponseSystem::ParseRule_ApplyContext ); + m_RuleDispatch.Insert( RR_HASH( "response" ), &CResponseSystem::ParseRule_Response ); +// m_RuleDispatch.Insert( RR_HASH( "forceweight" ), &CResponseSystem::ParseRule_ForceWeight ); + m_RuleDispatch.Insert( RR_HASH( "criteria" ), &CResponseSystem::ParseRule_Criteria ); + m_RuleDispatch.Insert( RR_HASH( "criterion" ), &CResponseSystem::ParseRule_Criteria ); + + + m_ResponseDispatch.Insert( RR_HASH( "weight" ), &CResponseSystem::ParseResponse_Weight ); + m_ResponseDispatch.Insert( RR_HASH( "predelay" ), &CResponseSystem::ParseResponse_PreDelay ); + m_ResponseDispatch.Insert( RR_HASH( "nodelay" ), &CResponseSystem::ParseResponse_NoDelay ); + m_ResponseDispatch.Insert( RR_HASH( "defaultdelay" ), &CResponseSystem::ParseResponse_DefaultDelay ); + m_ResponseDispatch.Insert( RR_HASH( "delay" ), &CResponseSystem::ParseResponse_Delay ); + m_ResponseDispatch.Insert( RR_HASH( "speakonce" ), &CResponseSystem::ParseResponse_SpeakOnce ); + m_ResponseDispatch.Insert( RR_HASH( "noscene" ), &CResponseSystem::ParseResponse_NoScene ); + m_ResponseDispatch.Insert( RR_HASH( "stop_on_nonidle" ), &CResponseSystem::ParseResponse_StopOnNonIdle ); + m_ResponseDispatch.Insert( RR_HASH( "odds" ), &CResponseSystem::ParseResponse_Odds ); + m_ResponseDispatch.Insert( RR_HASH( "respeakdelay" ), &CResponseSystem::ParseResponse_RespeakDelay ); + m_ResponseDispatch.Insert( RR_HASH( "weapondelay" ), &CResponseSystem::ParseResponse_WeaponDelay ); + m_ResponseDispatch.Insert( RR_HASH( "soundlevel" ), &CResponseSystem::ParseResponse_Soundlevel ); + m_ResponseDispatch.Insert( RR_HASH( "displayfirst" ), &CResponseSystem::ParseResponse_DisplayFirst ); + m_ResponseDispatch.Insert( RR_HASH( "displaylast" ), &CResponseSystem::ParseResponse_DisplayLast ); + m_ResponseDispatch.Insert( RR_HASH( "fire" ), &CResponseSystem::ParseResponse_Fire ); + m_ResponseDispatch.Insert( RR_HASH( "then" ), &CResponseSystem::ParseResponse_Then ); + + m_ResponseGroupDispatch.Insert( RR_HASH( "{" ), &CResponseSystem::ParseResponseGroup_Start ); + m_ResponseGroupDispatch.Insert( RR_HASH( "predelay" ), &CResponseSystem::ParseResponseGroup_PreDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "nodelay" ), &CResponseSystem::ParseResponseGroup_NoDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "defaultdelay" ), &CResponseSystem::ParseResponseGroup_DefaultDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "delay" ), &CResponseSystem::ParseResponseGroup_Delay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "speakonce" ), &CResponseSystem::ParseResponseGroup_SpeakOnce ); + m_ResponseGroupDispatch.Insert( RR_HASH( "noscene" ), &CResponseSystem::ParseResponseGroup_NoScene ); + m_ResponseGroupDispatch.Insert( RR_HASH( "stop_on_nonidle" ), &CResponseSystem::ParseResponseGroup_StopOnNonIdle ); + m_ResponseGroupDispatch.Insert( RR_HASH( "odds" ), &CResponseSystem::ParseResponseGroup_Odds ); + m_ResponseGroupDispatch.Insert( RR_HASH( "respeakdelay" ), &CResponseSystem::ParseResponseGroup_RespeakDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "weapondelay" ), &CResponseSystem::ParseResponseGroup_WeaponDelay ); + m_ResponseGroupDispatch.Insert( RR_HASH( "soundlevel" ), &CResponseSystem::ParseResponseGroup_Soundlevel ); +} + +bool CResponseSystem::Dispatch( char const *pToken, unsigned int uiHash, CResponseSystem::DispatchMap_t &rMap ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnResponseDispatch dispatch = rMap[ slot ]; + (this->*dispatch)(); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseRuleDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( newRule ); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseResponseDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( newResponse, group, rp ); + return true; + } + + return false; +} + +bool CResponseSystem::DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams ) +{ + int slot = rMap.Find( uiHash ); + if ( slot != rMap.InvalidIndex() ) + { + CResponseSystem::pfnParseResponseGroupDispatch dispatch = rMap[ slot ]; + (this->*dispatch)( responseGroupName, newGroup, groupResponseParams ); + return true; + } + + return false; +} + +unsigned int ResponseRulePartition::GetBucketForSpeakerAndConcept( const char *pszSpeaker, const char *pszConcept, const char *pszSubject ) +{ + // make sure is a power of two + COMPILE_TIME_ASSERT( ( N_RESPONSE_PARTITIONS & ( N_RESPONSE_PARTITIONS - 1 ) ) == 0 ); + + // hash together the speaker and concept strings, and mask off by the bucket mask + unsigned hashSpeaker = 0; // pszSpeaker ? HashStringCaseless( pszSpeaker ) : 0; + unsigned hashConcept = pszConcept ? HashStringCaseless( pszConcept ) : 0; + unsigned hashSubject = pszSubject ? HashStringCaseless( pszSubject ) : 0; + unsigned hashBrowns = ( ( hashSubject >> 3 ) ^ (hashSpeaker >> 1) ^ hashConcept ) & ( N_RESPONSE_PARTITIONS - 1 ); + return hashBrowns; +} + +const char *Rule::GetValueForRuleCriterionByName( CResponseSystem * RESTRICT pSystem, const CUtlSymbol &pCritNameSym ) +{ + const char * retval = NULL; + // for each rule criterion... + for ( int i = 0 ; i < m_Criteria.Count() ; ++i ) + { + retval = RecursiveGetValueForRuleCriterionByName( pSystem, &pSystem->m_Criteria[m_Criteria[i]], pCritNameSym ); + if ( retval != NULL ) + { + // we found a result, early out + break; + } + } + + return retval; +} + +const Criteria *Rule::GetPointerForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ) +{ + const Criteria * retval = NULL; + // for each rule criterion... + for ( int i = 0 ; i < m_Criteria.Count() ; ++i ) + { + retval = RecursiveGetPointerForRuleCriterionByName( pSystem, &pSystem->m_Criteria[m_Criteria[i]], pCritNameSym ); + if ( retval != NULL ) + { + // we found a result, early out + break; + } + } + + return retval; +} + +const char *Rule::RecursiveGetValueForRuleCriterionByName( CResponseSystem * RESTRICT pSystem, + const Criteria * RESTRICT pCrit, const CUtlSymbol &pCritNameSym ) +{ + Assert( pCrit ); + if ( !pCrit ) return NULL; + if ( pCrit->IsSubCriteriaType() ) + { + // test each of the children (depth first) + const char *pRet = NULL; + for ( int i = 0 ; i < pCrit->subcriteria.Count() ; ++i ) + { + pRet = RecursiveGetValueForRuleCriterionByName( pSystem, &pSystem->m_Criteria[pCrit->subcriteria[i]], pCritNameSym ); + if ( pRet ) // if found something, early out + return pRet; + } + } + else // leaf criterion + { + if ( pCrit->nameSym == pCritNameSym ) + { + return pCrit->value; + } + else + { + return NULL; + } + } + + return NULL; +} + + +const Criteria *Rule::RecursiveGetPointerForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ) +{ + Assert( pCrit ); + if ( !pCrit ) return NULL; + if ( pCrit->IsSubCriteriaType() ) + { + // test each of the children (depth first) + const Criteria *pRet = NULL; + for ( int i = 0 ; i < pCrit->subcriteria.Count() ; ++i ) + { + pRet = RecursiveGetPointerForRuleCriterionByName( pSystem, &pSystem->m_Criteria[pCrit->subcriteria[i]], pCritNameSym ); + if ( pRet ) // if found something, early out + return pRet; + } + } + else // leaf criterion + { + if ( pCrit->nameSym == pCritNameSym ) + { + return pCrit; + } + else + { + return NULL; + } + } + + return NULL; +} + + +static void CC_RR_Debug_ResponseConcept_Exclude( const CCommand &args ) +{ + // shouldn't use this extern elsewhere -- it's meant to be a hidden + // implementation detail + extern CRR_ConceptSymbolTable *g_pRRConceptTable; + Assert( g_pRRConceptTable ); + if ( !g_pRRConceptTable ) return; + + + // different things for different argument lengths + switch ( args.ArgC() ) + { + case 0: + { + AssertMsg( args.ArgC() > 0, "WTF error in ccommand parsing: zero arguments!\n" ); + return; + } + case 1: + { + // print usage info + Msg("Usage: rr_debugresponseconcept_exclude Concept1 Concept2 Concept3...\n"); + Msg("\tseparate multiple concepts with spaces.\n"); + Msg("\tcall with no arguments to see this message and a list of current excludes.\n"); + Msg("\tto reset the exclude list, type \"rr_debugresponseconcept_exclude !\"\n"); + + // print current excludes + Msg("\nCurrent exclude list:\n"); + if ( !CResponseSystem::m_DebugExcludeList.IsValidIndex( CResponseSystem::m_DebugExcludeList.Head() ) ) + { + Msg("\t\n"); + } + else + { + CResponseSystem::ExcludeList_t::IndexLocalType_t i; + for ( i = CResponseSystem::m_DebugExcludeList.Head() ; + CResponseSystem::m_DebugExcludeList.IsValidIndex(i) ; + i = CResponseSystem::m_DebugExcludeList.Next(i) ) + { + Msg( "\t%s\n", CResponseSystem::m_DebugExcludeList[i].GetStringConcept() ); + } + } + return; + } + case 2: + // deal with the erase operator + if ( args[1][0] == '!' ) + { + CResponseSystem::m_DebugExcludeList.Purge(); + Msg( "Exclude list emptied.\n" ); + return; + } + // else, FALL THROUGH: + default: + // add each arg to the exclude list + for ( int i = 1 ; i < args.ArgC() ; ++i ) + { + if ( !g_pRRConceptTable->Find(args[i]).IsValid() ) + { + Msg( "\t'%s' is not a known concept (adding it anyway)\n", args[i] ); + } + CRR_Concept concept( args[i] ); + CResponseSystem::m_DebugExcludeList.AddToTail( concept ); + } + } +} +#if RR_DUMPHASHINFO_ENABLED +static void CC_RR_DumpHashInfo( const CCommand &args ) +{ + defaultresponsesytem.m_InstancedSystems[0]->m_RulePartitions.PrintBucketInfo( defaultresponsesytem.m_InstancedSystems[0] ); +} +static ConCommand rr_dumphashinfo( "rr_dumphashinfo", CC_RR_DumpHashInfo, "Statistics on primary hash bucketing of response rule partitions"); + +void ResponseRulePartition::PrintBucketInfo( CResponseSystem *pSys ) +{ + struct bucktuple_t + { + int nBucket; + int nCount; + bucktuple_t() : nBucket(-1), nCount(-1) {}; + bucktuple_t( int bucket, int count ) : nBucket(bucket), nCount(count) {}; + + static int __cdecl SortCompare( const bucktuple_t * a, const bucktuple_t * b ) + { + return a->nCount - b->nCount; + } + }; + + CUtlVector infos( N_RESPONSE_PARTITIONS, N_RESPONSE_PARTITIONS ); + + float nAverage = 0; + for ( int i = 0 ; i < N_RESPONSE_PARTITIONS ; ++i ) + { + int count = m_RuleParts[i].Count(); + infos.AddToTail( bucktuple_t( i, count ) ); + nAverage += count; + } + nAverage /= N_RESPONSE_PARTITIONS; + infos.Sort( bucktuple_t::SortCompare ); + Msg( "%d buckets, %d total, %.2f average size\n", N_RESPONSE_PARTITIONS, Count(), nAverage ); + Msg( "8 shortest buckets:\n" ); + for ( int i = 0 ; i < 8 ; ++i ) + { + Msg("\t%d: %d\n", infos[i].nBucket, infos[i].nCount ); + } + Msg( "8 longest buckets:\n" ); + for ( int i = infos.Count() - 1 ; i >= infos.Count() - 9 ; --i ) + { + Msg("\t%d: %d\n", infos[i].nBucket, infos[i].nCount ); + } + int nempty = 0; + for ( nempty = 0 ; nempty < infos.Count() ; ++nempty ) + { + if ( infos[nempty].nCount != 0 ) + break; + } + Msg( "%d empty buckets\n", nempty ); + + /* + Msg( " Contents of longest bucket\nwho\tconcept\n" ); + tRuleDict &bucket = m_RuleParts[infos[infos.Count()-1].nBucket]; + for ( tRuleDict::IndexType_t i = bucket.FirstInorder(); bucket.IsValidIndex(i); i = bucket.NextInorder(i) ) + { + Rule &rule = bucket.Element(i) ; + Msg("%s\t%s\n", rule.GetValueForRuleCriterionByName( pSys, "who" ), rule.GetValueForRuleCriterionByName( pSys, CriteriaSet::ComputeCriteriaSymbol("concept") ) ); + } + */ +} +#endif \ No newline at end of file diff --git a/src/responserules/runtime/response_system.h b/src/responserules/runtime/response_system.h new file mode 100644 index 000000000..8f25a1b2a --- /dev/null +++ b/src/responserules/runtime/response_system.h @@ -0,0 +1,297 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: The CResponseSystem class. Don't include this header; include the response_types +// into which it is transcluded. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_SYSTEM_H +#define RESPONSE_SYSTEM_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utldict.h" +#include "utllinkedlist.h" +#include "stringpool.h" + +namespace ResponseRules +{ + typedef ResponseParams AI_ResponseParams ; + #define AI_CriteriaSet ResponseRules::CriteriaSet + + //----------------------------------------------------------------------------- + // Purpose: The database of all available responses. + // The Rules are partitioned based on a variety of factors (presently, + // speaker and concept) for faster lookup, basically a seperate-chained hash. + //----------------------------------------------------------------------------- + class CResponseSystem : public IResponseSystem + { + public: + CResponseSystem(); + ~CResponseSystem(); + + typedef void (CResponseSystem::*pfnResponseDispatch)( void ); + typedef void (CResponseSystem::*pfnParseRuleDispatch)( Rule & ); + typedef void (CResponseSystem::*pfnParseResponseDispatch)( ParserResponse &, ResponseGroup&, AI_ResponseParams * ); + typedef void (CResponseSystem::*pfnParseResponseGroupDispatch) ( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + + typedef CUtlMap< unsigned,pfnResponseDispatch > DispatchMap_t; + typedef CUtlMap< unsigned,pfnParseRuleDispatch > ParseRuleDispatchMap_t; + typedef CUtlMap< unsigned,pfnParseResponseDispatch > ParseResponseDispatchMap_t; + typedef CUtlMap< unsigned,pfnParseResponseGroupDispatch > ParseResponseGroupDispatchMap_t; + +#pragma region IResponseSystem + // IResponseSystem + virtual bool FindBestResponse( const CriteriaSet& set, CRR_Response& response, IResponseFilter *pFilter = NULL ); + virtual void GetAllResponses( CUtlVector *pResponses ); +#pragma endregion Implement interface from IResponseSystem + + virtual void Release() = 0; + + virtual void DumpRules(); + + bool IsCustomManagable() { return m_bCustomManagable; } + + void Clear(); + + void DumpDictionary( const char *pszName ); + + protected: + + void BuildDispatchTables(); + bool Dispatch( char const *pToken, unsigned int uiHash, DispatchMap_t &rMap ); + bool DispatchParseRule( char const *pToken, unsigned int uiHash, ParseRuleDispatchMap_t &rMap, Rule &newRule ); + bool DispatchParseResponse( char const *pToken, unsigned int uiHash, ParseResponseDispatchMap_t &rMap, ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + bool DispatchParseResponseGroup( char const *pToken, unsigned int uiHash, ParseResponseGroupDispatchMap_t &rMap, char const *responseGroupName, ResponseGroup& newGroup, AI_ResponseParams &groupResponseParams ); + + virtual const char *GetScriptFile( void ) = 0; + void LoadRuleSet( const char *setname ); + + void ResetResponseGroups(); + + float LookForCriteria( const CriteriaSet &criteriaSet, int iCriteria ); + float RecursiveLookForCriteria( const CriteriaSet &criteriaSet, Criteria *pParent ); + + public: + + void CopyRuleFrom( Rule *pSrcRule, ResponseRulePartition::tIndex iRule, CResponseSystem *pCustomSystem ); + void CopyCriteriaFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); + void CopyResponsesFrom( Rule *pSrcRule, Rule *pDstRule, CResponseSystem *pCustomSystem ); + void CopyEnumerationsFrom( CResponseSystem *pCustomSystem ); + + //private: + + struct Enumeration + { + float value; + }; + + struct ResponseSearchResult + { + ResponseSearchResult() + { + group = NULL; + action = NULL; + } + + ResponseGroup *group; + ParserResponse *action; + }; + + inline bool ParseToken( void ) + { + if ( m_bUnget ) + { + m_bUnget = false; + return true; + } + if ( m_ScriptStack.Count() <= 0 ) + { + Assert( 0 ); + return false; + } + + m_ScriptStack[ 0 ].currenttoken = IEngineEmulator::Get()->ParseFile( m_ScriptStack[ 0 ].currenttoken, token, sizeof( token ) ); + m_ScriptStack[ 0 ].tokencount++; + return m_ScriptStack[ 0 ].currenttoken != NULL ? true : false; + } + + inline void Unget() + { + m_bUnget = true; + } + + inline bool TokenWaiting( void ) + { + if ( m_ScriptStack.Count() <= 0 ) + { + Assert( 0 ); + return false; + } + + const char *p = m_ScriptStack[ 0 ].currenttoken; + + if ( !p ) + { + Error( "AI_ResponseSystem: Unxpected TokenWaiting() with NULL buffer in %s", (char * ) m_ScriptStack[ 0 ].name ); + return false; + } + + + while ( *p && *p!='\n') + { + // Special handler for // comment blocks + if ( *p == '/' && *(p+1) == '/' ) + return false; + + if ( !V_isspace( *p ) || isalnum( *p ) ) + return true; + + p++; + } + + return false; + } + + void ParseOneResponse( const char *responseGroupName, ResponseGroup& group, ResponseParams *defaultParams = NULL ); + + void ParseInclude( void ); + void ParseResponse( void ); + void ParseCriterion( void ); + void ParseRule( void ); + void ParseEnumeration( void ); + + private: + void ParseRule_MatchOnce( Rule &newRule ); + void ParseRule_ApplyContextToWorld( Rule &newRule ); + void ParseRule_ApplyContextToSelf(Rule& newRule); + void ParseRule_ApplyContextToSquad(Rule& newRule); + void ParseRule_ApplyContextToEnemy(Rule& newRule); + void ParseRule_ApplyContext( Rule &newRule ); + void ParseRule_Response( Rule &newRule ); + //void ParseRule_ForceWeight( Rule &newRule ); + void ParseRule_Criteria( Rule &newRule ); + char const *m_pParseRuleName; + bool m_bParseRuleValid; + + void ParseResponse_Weight( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_PreDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_NoDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DefaultDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Delay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_SpeakOnce( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_NoScene( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_StopOnNonIdle( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Odds( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_RespeakDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_WeaponDelay( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Soundlevel( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DisplayFirst( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_DisplayLast( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Fire( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + void ParseResponse_Then( ParserResponse &newResponse, ResponseGroup& group, AI_ResponseParams *rp ); + + void ParseResponseGroup_Start( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_PreDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_NoDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_DefaultDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Delay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_SpeakOnce( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_NoScene( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_StopOnNonIdle( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Odds( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_RespeakDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_WeaponDelay( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + void ParseResponseGroup_Soundlevel( char const *responseGroupName, ResponseGroup &newGroup, AI_ResponseParams &groupResponseParams ); + +public: + int ParseOneCriterion( const char *criterionName ); + + bool Compare( const char *setValue, Criteria *c, bool verbose = false ); + bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false ); + void ComputeMatcher( Criteria *c, Matcher& matcher ); + void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ); + float LookupEnumeration( const char *name, bool& found ); + + ResponseRulePartition::tIndex FindBestMatchingRule( const CriteriaSet& set, bool verbose, float &scoreOfBestMatchingRule ); + + float ScoreCriteriaAgainstRule( const CriteriaSet& set, ResponseRulePartition::tRuleDict &dict, int irule, bool verbose = false ); + float RecursiveScoreSubcriteriaAgainstRule( const CriteriaSet& set, Criteria *parent, bool& exclude, bool verbose /*=false*/ ); + float ScoreCriteriaAgainstRuleCriteria( const CriteriaSet& set, int icriterion, bool& exclude, bool verbose = false ); + void FakeDepletes( ResponseGroup *g, IResponseFilter *pFilter ); + void RevertFakedDepletes( ResponseGroup *g ); + bool GetBestResponse( ResponseSearchResult& result, Rule *rule, bool verbose = false, IResponseFilter *pFilter = NULL ); + bool ResolveResponse( ResponseSearchResult& result, int depth, const char *name, bool verbose = false, IResponseFilter *pFilter = NULL ); + int SelectWeightedResponseFromResponseGroup( ResponseGroup *g, IResponseFilter *pFilter ); + void DescribeResponseGroup( ResponseGroup *group, int selected, int depth ); + void DebugPrint( int depth, const char *fmt, ... ); + + void LoadFromBuffer( const char *scriptfile, const char *buffer ); + + void GetCurrentScript( char *buf, size_t buflen ); + int GetCurrentToken() const; + void SetCurrentScript( const char *script ); + + inline bool IsRootCommand( unsigned int hash ) const + { + int slot = m_RootCommandHashes.Find( hash ); + return slot != m_RootCommandHashes.InvalidIndex(); + } + + inline bool IsRootCommand() const + { + return IsRootCommand( RR_HASH( token ) ); + } + + void PushScript( const char *scriptfile, unsigned char *buffer ); + void PopScript(void); + + void ResponseWarning( const char *fmt, ... ); + + CUtlDict< ResponseGroup, short > m_Responses; + CUtlDict< Criteria, short > m_Criteria; + // CUtlDict< Rule, short > m_Rules; + ResponseRulePartition m_RulePartitions; + CUtlDict< Enumeration, short > m_Enumerations; + + CUtlVector m_FakedDepletes; + + char token[ 1204 ]; + + bool m_bUnget; + + bool m_bCustomManagable; + + struct ScriptEntry + { + unsigned char *buffer; + FileNameHandle_t name; + const char *currenttoken; + int tokencount; + }; + + CUtlVector< ScriptEntry > m_ScriptStack; + CStringPool m_IncludedFiles; + + DispatchMap_t m_FileDispatch; + ParseRuleDispatchMap_t m_RuleDispatch; + ParseResponseDispatchMap_t m_ResponseDispatch; + ParseResponseGroupDispatchMap_t m_ResponseGroupDispatch; + CUtlRBTree< unsigned int > m_RootCommandHashes; + + // for debugging purposes only: concepts to be emitted from rr_debugresponses 2 + typedef CUtlLinkedList< CRR_Concept, unsigned short, false, unsigned int > ExcludeList_t; + static ExcludeList_t m_DebugExcludeList; + + friend class CDefaultResponseSystemSaveRestoreBlockHandler; + friend class CResponseSystemSaveRestoreOps; + }; + + // Some globals inherited from AI_Speech.h: + const float AIS_DEF_MIN_DELAY = 2.8; // Minimum amount of time an NPCs will wait after someone has spoken before considering speaking again + const float AIS_DEF_MAX_DELAY = 3.2; // Maximum amount of time an NPCs will wait after someone has spoken before considering speaking again +} + +#endif // RESPONSE_SYSTEM_H \ No newline at end of file diff --git a/src/responserules/runtime/response_types.cpp b/src/responserules/runtime/response_types.cpp new file mode 100644 index 000000000..30502f118 --- /dev/null +++ b/src/responserules/runtime/response_types.cpp @@ -0,0 +1,267 @@ +//========= Copyright © 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace ResponseRules; + + +// bizarre function handed down from the misty days of yore +// and the original response system. a lot of stuff uses it +// and I can't be arsed to replace everything with the c stdlib +// stuff +namespace ResponseRules +{ + extern const char *ResponseCopyString( const char *in ); +}; + + +//-------------------- MATCHER ---------------------------------------------- + +Matcher::Matcher() +{ + valid = false; + isnumeric = false; + notequal = false; + usemin = false; + minequals = false; + usemax = false; + maxequals = false; + isbit = false; + maxval = 0.0f; + minval = 0.0f; + + token = UTL_INVAL_SYMBOL; + rawtoken = UTL_INVAL_SYMBOL; +} + +void Matcher::Describe( void ) +{ + if ( !valid ) + { + DevMsg( " invalid!\n" ); + return; + } + char sz[ 128 ]; + + sz[ 0] = 0; + int minmaxcount = 0; + if ( usemin ) + { + Q_snprintf( sz, sizeof( sz ), ">%s%.3f", minequals ? "=" : "", minval ); + minmaxcount++; + } + if ( usemax ) + { + char sz2[ 128 ]; + Q_snprintf( sz2, sizeof( sz2 ), "<%s%.3f", maxequals ? "=" : "", maxval ); + + if ( minmaxcount > 0 ) + { + Q_strncat( sz, " and ", sizeof( sz ), COPY_ALL_CHARACTERS ); + } + Q_strncat( sz, sz2, sizeof( sz ), COPY_ALL_CHARACTERS ); + minmaxcount++; + } + + if ( minmaxcount >= 1 ) + { + DevMsg( " matcher: %s\n", sz ); + return; + } + + if (isbit) + { + DevMsg(" matcher: &%s%s\n", notequal ? "~" : "", GetToken()); + return; + } + + if ( notequal ) + { + DevMsg( " matcher: !=%s\n", GetToken() ); + return; + } + + DevMsg( " matcher: ==%s\n", GetToken() ); +} + +void Matcher::SetToken( char const *s ) +{ + token = g_RS.AddString( s ); +} + +void Matcher::SetRaw( char const *raw ) +{ + rawtoken = g_RS.AddString( raw ); +} + +char const *Matcher::GetToken() +{ + if ( token.IsValid() ) + { + return g_RS.String( token ); + } + return ""; +} + +char const *Matcher::GetRaw() +{ + if ( rawtoken.IsValid() ) + { + return g_RS.String( rawtoken ); + } + return ""; +} + +//-------------------- CRITERIA ---------------------------------------------- + +Criteria::Criteria() +{ + value = NULL; + weight.SetFloat( 1.0f ); + required = false; +} +Criteria::Criteria(const Criteria& src ) +{ + operator=( src ); +} + +Criteria::~Criteria() +{ + // do nothing because we don't own name and value anymore +} + +Criteria& Criteria::operator =(const Criteria& src ) +{ + if ( this == &src ) + return *this; + + nameSym = src.nameSym; + value = ResponseCopyString( src.value ); + weight = src.weight; + required = src.required; + + matcher = src.matcher; + + int c = src.subcriteria.Count(); + subcriteria.EnsureCapacity( c ); + for ( int i = 0; i < c; i++ ) + { + subcriteria.AddToTail( src.subcriteria[ i ] ); + } + + return *this; +} + + +//-------------------- RESPONSE ---------------------------------------------- + + + +ParserResponse::ParserResponse() : m_followup() +{ + type = RESPONSE_NONE; + value = NULL; + weight.SetFloat( 1.0f ); + depletioncount = 0; + first = false; + last = false; +} + +ParserResponse& ParserResponse::operator =( const ParserResponse& src ) +{ + if ( this == &src ) + return *this; + weight = src.weight; + type = src.type; + value = ResponseCopyString( src.value ); + depletioncount = src.depletioncount; + first = src.first; + last = src.last; + params = src.params; + + m_followup.followup_concept = ResponseCopyString(src.m_followup.followup_concept); + m_followup.followup_contexts = ResponseCopyString(src.m_followup.followup_contexts); + m_followup.followup_target = ResponseCopyString(src.m_followup.followup_target); + m_followup.followup_entityioinput = ResponseCopyString(src.m_followup.followup_entityioinput); + m_followup.followup_entityiotarget = ResponseCopyString(src.m_followup.followup_entityiotarget); + m_followup.followup_delay = src.m_followup.followup_delay; + m_followup.followup_entityiodelay = src.m_followup.followup_entityiodelay; + + return *this; +} + +ParserResponse::ParserResponse( const ParserResponse& src ) +{ + operator=( src ); +} + +ParserResponse::~ParserResponse() +{ + // nothing to do, since we don't own + // the strings anymore +} + +// ------------ RULE --------------- + +Rule::Rule() : m_nForceWeight(0) +{ + m_bMatchOnce = false; + m_bEnabled = true; + m_szContext = NULL; + m_iContextFlags = 0; +} + +Rule& Rule::operator =( const Rule& src ) +{ + if ( this == &src ) + return *this; + + int i; + int c; + + c = src.m_Criteria.Count(); + m_Criteria.EnsureCapacity( c ); + for ( i = 0; i < c; i++ ) + { + m_Criteria.AddToTail( src.m_Criteria[ i ] ); + } + + c = src.m_Responses.Count(); + m_Responses.EnsureCapacity( c ); + for ( i = 0; i < c; i++ ) + { + m_Responses.AddToTail( src.m_Responses[ i ] ); + } + + SetContext( src.m_szContext ); + m_bMatchOnce = src.m_bMatchOnce; + m_bEnabled = src.m_bEnabled; + m_iContextFlags = src.m_iContextFlags; + m_nForceWeight = src.m_nForceWeight; + return *this; +} + +Rule::Rule( const Rule& src ) +{ + operator=(src); +} + +Rule::~Rule() +{ +} + +void Rule::SetContext( const char *context ) +{ + // we don't own the data we point to, so just update pointer + m_szContext = ResponseCopyString( context ); +} + + diff --git a/src/responserules/runtime/response_types_internal.cpp b/src/responserules/runtime/response_types_internal.cpp new file mode 100644 index 000000000..2d11bdd2c --- /dev/null +++ b/src/responserules/runtime/response_types_internal.cpp @@ -0,0 +1,120 @@ +//========= Copyright © 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace ResponseRules; + + + + +ResponseRulePartition::ResponseRulePartition() +{ + Assert(true); + COMPILE_TIME_ASSERT( kIDX_ELEM_MASK < (1 << 16) ); + COMPILE_TIME_ASSERT( (kIDX_ELEM_MASK & (kIDX_ELEM_MASK + 1)) == 0 ); /// assert is power of two minus one +} + +ResponseRulePartition::~ResponseRulePartition() +{ + RemoveAll(); +} + +ResponseRulePartition::tIndex ResponseRulePartition::IndexFromDictElem( tRuleDict* pDict, int elem ) +{ + Assert( pDict ); + // If this fails, you've tried to build an index for a rule that's not stored + // in this partition + Assert( pDict >= m_RuleParts && pDict < m_RuleParts + N_RESPONSE_PARTITIONS ); + AssertMsg1( elem <= kIDX_ELEM_MASK, "A rule dictionary has %d elements; this exceeds the 255 that can be packed into an index.\n", elem ); + + int bucket = pDict - m_RuleParts; + return ( bucket << 16 ) | ( elem & kIDX_ELEM_MASK ); // this is a native op on PPC +} + + +char const *ResponseRulePartition::GetElementName( const tIndex &i ) const +{ + Assert( IsValid(i) ); + return m_RuleParts[ BucketFromIdx(i) ].GetElementName( PartFromIdx(i) ); +} + + +int ResponseRulePartition::Count( void ) +{ + int count = 0 ; + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + count += m_RuleParts[bukkit].Count(); + } + + return count; +} + +void ResponseRulePartition::RemoveAll( void ) +{ + for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit ) + { + for ( int i = m_RuleParts[bukkit].FirstInorder(); i != m_RuleParts[bukkit].InvalidIndex(); i = m_RuleParts[bukkit].NextInorder( i ) ) + { + delete m_RuleParts[bukkit][ i ]; + } + m_RuleParts[bukkit].RemoveAll(); + } +} + +// don't bucket "subject" criteria that prefix with operators, since stripping all that out again would +// be a big pain, and the most important rules that need subjects are tlk_remarks anyway. +static inline bool CanBucketBySubject( const char * RESTRICT pszSubject ) +{ + return pszSubject && + ( ( pszSubject[0] >= 'A' && pszSubject[0] <= 'Z' ) || + ( pszSubject[0] >= 'a' && pszSubject[0] <= 'z' ) ); +} + +ResponseRulePartition::tRuleDict &ResponseRulePartition::GetDictForRule( CResponseSystem *pSystem, Rule *pRule ) +{ + const static CUtlSymbol kWHO = CriteriaSet::ComputeCriteriaSymbol("Who"); + const static CUtlSymbol kCONCEPT = CriteriaSet::ComputeCriteriaSymbol("Concept"); + const static CUtlSymbol kSUBJECT = CriteriaSet::ComputeCriteriaSymbol("Subject"); + + const char *pszSpeaker = pRule->GetValueForRuleCriterionByName( pSystem, kWHO ); + const char *pszConcept = pRule->GetValueForRuleCriterionByName( pSystem, kCONCEPT ); + const Criteria *pSubjCrit = pRule->GetPointerForRuleCriterionByName( pSystem, kSUBJECT ); + + return m_RuleParts[ + GetBucketForSpeakerAndConcept( pszSpeaker, pszConcept, + ( pSubjCrit && pSubjCrit->required && CanBucketBySubject(pSubjCrit->value) ) ? + pSubjCrit->value : + NULL ) + ]; +} + + +void ResponseRulePartition::GetDictsForCriteria( CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > *pResult, const CriteriaSet &criteria ) +{ + pResult->RemoveAll(); + pResult->EnsureCapacity( 2 ); + + // get the values for Who and Concept, which are what we bucket on + int speakerIdx = criteria.FindCriterionIndex( "Who" ); + const char *pszSpeaker = speakerIdx != -1 ? criteria.GetValue( speakerIdx ) : NULL ; + + int conceptIdx = criteria.FindCriterionIndex( "Concept" ); + const char *pszConcept = conceptIdx != -1 ? criteria.GetValue( conceptIdx ) : NULL ; + + int subjectIdx = criteria.FindCriterionIndex( "Subject" ); + const char *pszSubject = subjectIdx != -1 ? criteria.GetValue( subjectIdx ) : NULL ; + + pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, pszSubject) ] ); + // also try the rules not specifying subject + pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, NULL) ] ); + +} \ No newline at end of file diff --git a/src/responserules/runtime/response_types_internal.h b/src/responserules/runtime/response_types_internal.h new file mode 100644 index 000000000..1de53ff8b --- /dev/null +++ b/src/responserules/runtime/response_types_internal.h @@ -0,0 +1,542 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RESPONSE_TYPES_INTERNAL_H +#define RESPONSE_TYPES_INTERNAL_H +#ifdef _WIN32 +#pragma once +#endif + +#include "responserules/response_types.h" +#include "utldict.h" + + +namespace ResponseRules +{ + + inline unsigned FASTCALL HashStringConventional( const char *pszKey ) + { + unsigned hash = 0xAAAAAAAA; // Alternating 1's and 0's to maximize the effect of the later multiply and add + + for( ; *pszKey ; pszKey++ ) + { + hash = ( ( hash << 5 ) + hash ) + (uint8)(*pszKey); + } + + return hash; + } + + // Note: HashString causes collisions!!! +#define RR_HASH HashStringConventional + +#pragma pack(push,1) + + class Matcher + { + public: + Matcher(); + + void Describe( void ); + + float maxval; + float minval; + + bool valid : 1; //1 + bool isnumeric : 1; //2 + bool notequal : 1; //3 + bool usemin : 1; //4 + bool minequals : 1; //5 + bool usemax : 1; //6 + bool maxequals : 1; //7 + bool isbit : 1; //8 + + void SetToken( char const *s ); + + char const *GetToken(); + + void SetRaw( char const *raw ); + + char const *GetRaw(); + + private: + CUtlSymbol token; + CUtlSymbol rawtoken; + }; +#pragma pack(pop) + + struct Criteria + { + Criteria(); + Criteria& operator =(const Criteria& src ); + + Criteria(const Criteria& src ); + ~Criteria(); + + // Does this criterion recursively contain more criteria? + inline bool IsSubCriteriaType() const + { + return ( subcriteria.Count() > 0 ) ? true : false; + } + + // const char *name; + CUtlSymbol nameSym; + const char *value; + float16 weight; + bool required; + + Matcher matcher; + + // Indices into sub criteria + CUtlVectorConservative< unsigned short > subcriteria; + }; + +#pragma pack(push,1) + /// This is a response block as read from the file, + /// different from CRR_Response which is what is handed + /// back to queries. + struct ParserResponse + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + ParserResponse(); + ParserResponse( const ParserResponse& src ); + ParserResponse& operator =( const ParserResponse& src ); + ~ParserResponse(); + + ResponseType_t GetType() { return (ResponseType_t)type; } + + ResponseParams params; + + const char *value; // fixed up value spot // 4 + float16 weight; // 6 + + byte depletioncount; // 7 + byte type : 6; // 8 + byte first : 1; // + byte last : 1; // + + ALIGN32 AI_ResponseFollowup m_followup; // info on whether I should force the other guy to say something + }; +#pragma pack(pop) + +#pragma pack(push,1) + struct ResponseGroup + { + DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE(); + + ResponseGroup() + { + // By default visit all nodes before repeating + m_bSequential = false; + m_bNoRepeat = false; + m_bEnabled = true; + m_nCurrentIndex = 0; + m_bDepleteBeforeRepeat = true; + m_nDepletionCount = 1; + m_bHasFirst = false; + m_bHasLast = false; + } + + ResponseGroup( const ResponseGroup& src ) + { + int c = src.group.Count(); + for ( int i = 0; i < c; i++ ) + { + group.AddToTail( src.group[ i ] ); + } + + m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; + m_nDepletionCount = src.m_nDepletionCount; + m_bHasFirst = src.m_bHasFirst; + m_bHasLast = src.m_bHasLast; + m_bSequential = src.m_bSequential; + m_bNoRepeat = src.m_bNoRepeat; + m_bEnabled = src.m_bEnabled; + m_nCurrentIndex = src.m_nCurrentIndex; + } + + ResponseGroup& operator=( const ResponseGroup& src ) + { + if ( this == &src ) + return *this; + int c = src.group.Count(); + for ( int i = 0; i < c; i++ ) + { + group.AddToTail( src.group[ i ] ); + } + + m_bDepleteBeforeRepeat = src.m_bDepleteBeforeRepeat; + m_nDepletionCount = src.m_nDepletionCount; + m_bHasFirst = src.m_bHasFirst; + m_bHasLast = src.m_bHasLast; + m_bSequential = src.m_bSequential; + m_bNoRepeat = src.m_bNoRepeat; + m_bEnabled = src.m_bEnabled; + m_nCurrentIndex = src.m_nCurrentIndex; + return *this; + } + + bool HasUndepletedChoices() const + { + if ( !m_bDepleteBeforeRepeat ) + return true; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + if ( group[ i ].depletioncount != m_nDepletionCount ) + return true; + } + + return false; + } + + void MarkResponseUsed( int idx ) + { + if ( !m_bDepleteBeforeRepeat ) + return; + + if ( idx < 0 || idx >= group.Count() ) + { + Assert( 0 ); + return; + } + + group[ idx ].depletioncount = m_nDepletionCount; + } + + void ResetDepletionCount() + { + if ( !m_bDepleteBeforeRepeat ) + return; + ++m_nDepletionCount; + } + + void Reset() + { + ResetDepletionCount(); + SetEnabled( true ); + SetCurrentIndex( 0 ); + m_nDepletionCount = 1; + + for ( int i = 0; i < group.Count(); ++i ) + { + group[ i ].depletioncount = 0; + } + } + + bool HasUndepletedFirst( int& index ) + { + index = -1; + + if ( !m_bDepleteBeforeRepeat ) + return false; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &group[ i ]; + + if ( ( r->depletioncount != m_nDepletionCount ) && r->first ) + { + index = i; + return true; + } + } + + return false; + } + + bool HasUndepletedLast( int& index ) + { + index = -1; + + if ( !m_bDepleteBeforeRepeat ) + return false; + + int c = group.Count(); + for ( int i = 0; i < c; i++ ) + { + ParserResponse *r = &group[ i ]; + + if ( ( r->depletioncount != m_nDepletionCount ) && r->last ) + { + index = i; + return true; + } + } + + return false; + } + + bool ShouldCheckRepeats() const { return m_bDepleteBeforeRepeat; } + int GetDepletionCount() const { return m_nDepletionCount; } + + bool IsSequential() const { return m_bSequential; } + void SetSequential( bool seq ) { m_bSequential = seq; } + + bool IsNoRepeat() const { return m_bNoRepeat; } + void SetNoRepeat( bool norepeat ) { m_bNoRepeat = norepeat; } + + bool IsEnabled() const { return m_bEnabled; } + void SetEnabled( bool enabled ) { m_bEnabled = enabled; } + + int GetCurrentIndex() const { return m_nCurrentIndex; } + void SetCurrentIndex( byte idx ) { m_nCurrentIndex = idx; } + + CUtlVector< ParserResponse > group; + + bool m_bEnabled; + + byte m_nCurrentIndex; + // Invalidation counter + byte m_nDepletionCount; + + // Use all slots before repeating any + bool m_bDepleteBeforeRepeat : 1; + bool m_bHasFirst : 1; + bool m_bHasLast : 1; + bool m_bSequential : 1; + bool m_bNoRepeat : 1; + }; +#pragma pack(pop) + +#pragma pack(push,1) + struct Rule + { + Rule(); + Rule( const Rule& src ); + ~Rule(); + Rule& operator =( const Rule& src ); + + void SetContext( const char *context ); + + const char *GetContext( void ) const { return m_szContext; } + + inline bool IsEnabled() const { return m_bEnabled; } + inline void Disable() { m_bEnabled = false; } + inline bool IsMatchOnce() const { return m_bMatchOnce; } + inline bool IsApplyContextToWorld() const { return (m_iContextFlags & APPLYCONTEXT_WORLD) != 0; } + + const char *GetValueForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ); + const Criteria *GetPointerForRuleCriterionByName( CResponseSystem *pSystem, const CUtlSymbol &pCritNameSym ); + + // Indices into underlying criteria and response dictionaries + CUtlVectorConservative< unsigned short > m_Criteria; + CUtlVectorConservative< unsigned short> m_Responses; + + const char *m_szContext; + uint8 m_nForceWeight; + + int m_iContextFlags; + + bool m_bMatchOnce : 1; + bool m_bEnabled : 1; + + private: + // what is this, lisp? + const char *RecursiveGetValueForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ); + const Criteria *RecursiveGetPointerForRuleCriterionByName( CResponseSystem *pSystem, const Criteria *pCrit, const CUtlSymbol &pCritNameSym ); + }; +#pragma pack(pop) + + template + class CResponseDict : public CUtlMap + { + public: + CResponseDict() : CUtlMap( DefLessFunc( unsigned int ) ), m_ReverseMap( DefLessFunc( unsigned int ) ) + { + } + + I Insert( const char *pName, const T &element ) + { + char const *pString = ResponseCopyString( pName ); + unsigned int hash = RR_HASH( pString ); + m_ReverseMap.Insert( hash, pString ); + return CUtlMap::Insert( hash, element ); + } + + I Insert( const char *pName ) + { + char const *pString = ResponseCopyString( pName ); + unsigned int hash = RR_HASH( pString ); + m_ReverseMap.Insert( hash, pString ); + return CUtlMap::Insert( hash ); + } + + I Find( char const *pName ) const + { + unsigned int hash = RR_HASH( pName ); + return CUtlMap::Find( hash ); + } + + const char *GetElementName( I i ) + { + int k = Key( i ); + int slot = m_ReverseMap.Find( k ); + if ( slot == m_ReverseMap.InvalidIndex() ) + return ""; + return m_ReverseMap[ slot ]; + } + + const char *GetElementName( I i ) const + { + int k = Key( i ); + int slot = m_ReverseMap.Find( k ); + if ( slot == m_ReverseMap.InvalidIndex() ) + return ""; + return m_ReverseMap[ slot ]; + } + + private: + CUtlMap< unsigned int, const char * > m_ReverseMap; + + }; + + // define this to 1 to enable printing some occupancy + // information on the response system via concommmand + // rr_dumphashinfo + #define RR_DUMPHASHINFO_ENABLED 0 + // The Rules are partitioned based on a variety of factors (presently, + // speaker and concept) for faster lookup, basically a seperate-chained hash. + struct ResponseRulePartition + { + ResponseRulePartition( void ); + ~ResponseRulePartition(); + + typedef CResponseDict< Rule * > tRuleDict; + typedef uint32 tIndex; // an integer that can be used to find any rule in the dict + + /// get the appropriate m_rules dict for the provided rule + tRuleDict &GetDictForRule( CResponseSystem *pSystem, Rule *pRule ); + + /// get all bucket full of rules that might possibly match the given criteria. + /// (right now they are bucketed such that all rules that can possibly match a + /// criteria are in one of two dictionaries) + void GetDictsForCriteria( CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > *pResult, const CriteriaSet &criteria ); + + // dump everything. + void RemoveAll(); + + inline Rule &operator[]( tIndex idx ); + int Count( void ); // number of elements inside, but you can't iterate from 0 to this + char const *GetElementName( const tIndex &i ) const; + + /// given a dictionary and an element number inside that dict, + /// return a tIndex + tIndex IndexFromDictElem( tRuleDict* pDict, int elem ); + + // for iteration: + inline tIndex First( void ); + inline tIndex Next( const tIndex &idx ); + inline bool IsValid( const tIndex &idx ) const; + inline static tIndex InvalidIdx( void ) + { + return ((tIndex) -1); + } + + // used only for debug prints, do not rely on them otherwise + inline unsigned int BucketFromIdx( const tIndex &idx ) const ; + inline unsigned int PartFromIdx( const tIndex &idx ) const ; + + enum { + N_RESPONSE_PARTITIONS = 256, + kIDX_ELEM_MASK = 0xFFF, ///< this is used to mask the element number part of a ResponseRulePartition::tIndex + }; + +#if RR_DUMPHASHINFO_ENABLED + void PrintBucketInfo( CResponseSystem *pSys ); +#endif + + private: + tRuleDict m_RuleParts[N_RESPONSE_PARTITIONS]; + unsigned int GetBucketForSpeakerAndConcept( const char *pszSpeaker, const char *pszConcept, const char *pszSubject ); + }; + + // // // // // inline functions + + inline ResponseRulePartition::tIndex ResponseRulePartition::First( void ) + { + // find the first bucket that has anything + for ( int bucket = 0 ; bucket < N_RESPONSE_PARTITIONS; bucket++ ) + { + if ( m_RuleParts[bucket].Count() > 0 ) + return bucket << 16; + } + return InvalidIdx(); + } + + inline ResponseRulePartition::tIndex ResponseRulePartition::Next( const tIndex &idx ) + { + int bucket = BucketFromIdx( idx ); + unsigned int elem = PartFromIdx( idx ); + Assert( IsValid(idx) ); + AssertMsg( elem < kIDX_ELEM_MASK, "Too many response rules! Overflow! Doom!" ); + if ( elem + 1 < m_RuleParts[bucket].Count() ) + { + return idx+1; + } + else + { + // walk through the other buckets, skipping empty ones, until we find one with responses and give up. + while ( ++bucket < N_RESPONSE_PARTITIONS ) + { + if ( m_RuleParts[bucket].Count() > 0 ) + { + // 0th element in nth bucket + return bucket << 16; + } + } + + // out of buckets + return InvalidIdx(); + + } + } + + inline Rule &ResponseRulePartition::operator[]( tIndex idx ) + { + Assert( IsValid(idx) ); + return *m_RuleParts[ BucketFromIdx(idx) ][ PartFromIdx(idx) ] ; + } + + inline unsigned int ResponseRulePartition::BucketFromIdx( const tIndex &idx ) const + { + return idx >> 16; + } + + inline unsigned int ResponseRulePartition::PartFromIdx( const tIndex &idx ) const + { + return idx & kIDX_ELEM_MASK; + } + + inline bool ResponseRulePartition::IsValid( const tIndex & idx ) const + { + // make sure that the idx type for the dicts is still short + COMPILE_TIME_ASSERT( sizeof(m_RuleParts[0].FirstInorder()) == 2 ); + + if ( idx == -1 ) + return false; + + int bucket = idx >> 16; + unsigned int elem = idx & kIDX_ELEM_MASK; + + return ( bucket < N_RESPONSE_PARTITIONS && + elem < m_RuleParts[bucket].Count() ); + } + + //----------------------------------------------------------------------------- + // PARSER TYPES -- these are internal to the response system, and represent + // the objects as loaded from disk. + //----------------------------------------------------------------------------- + + +} + +#include "response_system.h" + +#endif \ No newline at end of file diff --git a/src/responserules/runtime/rr_convars.cpp b/src/responserules/runtime/rr_convars.cpp new file mode 100644 index 000000000..986ae0cd4 --- /dev/null +++ b/src/responserules/runtime/rr_convars.cpp @@ -0,0 +1,14 @@ +//========= Copyright © 1996-2010, Valve Corporation, All rights reserved. ============// +// +// Purpose: Convars used by the response rule system. +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" +#include + + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + diff --git a/src/responserules/runtime/rr_response.cpp b/src/responserules/runtime/rr_response.cpp new file mode 100644 index 000000000..6e9aae277 --- /dev/null +++ b/src/responserules/runtime/rr_response.cpp @@ -0,0 +1,330 @@ +#include "..\..\public\responserules\response_types.h" +#include "..\..\public\responserules\response_types.h" +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include "rrbase.h" + +#include + +/* +#include "AI_Criteria.h" +#include "ai_speech.h" +#include +#include "engine/IEngineSound.h" +*/ + +// memdbgon must be the last include file in a .cpp file!!! +#include + +using namespace ResponseRules; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRR_Response::CRR_Response() : m_fMatchScore(0) +{ + m_Type = ResponseRules::RESPONSE_NONE; + m_szResponseName[0] = 0; + m_szMatchingRule[0]=0; + m_szContext = NULL; + m_iContextFlags = 0; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CRR_Response::CRR_Response( const CRR_Response &from ) : m_fMatchScore(0) +{ + // Assert( (void*)(&m_Type) == (void*)this ); + Invalidate(); + memcpy( this, &from, sizeof(*this) ); + m_szContext = NULL; + SetContext( from.m_szContext ); + m_iContextFlags = from.m_iContextFlags; +} + + +//----------------------------------------------------------------------------- +CRR_Response &CRR_Response::operator=( const CRR_Response &from ) +{ + // Assert( (void*)(&m_Type) == (void*)this ); + Invalidate(); + memcpy( this, &from, sizeof(*this) ); + m_szContext = NULL; + SetContext( from.m_szContext ); + m_iContextFlags = from.m_iContextFlags; + return *this; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRR_Response::~CRR_Response() +{ + if (m_szContext) + delete[] m_szContext; +} + +void CRR_Response::Invalidate() +{ + if (m_szContext) + { + delete[] m_szContext; + m_szContext = NULL; + } + m_Type = ResponseRules::RESPONSE_NONE; + m_szResponseName[0] = 0; + // not really necessary: + /* + m_szMatchingRule[0]=0; + m_szContext = NULL; + m_bApplyContextToWorld = false; + */ +} + +// please do not new or delete CRR_Responses. +void CRR_Response::operator delete(void* p) +{ + AssertMsg(false, "DO NOT new or delete CRR_Response s."); + free(p); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *response - +// *criteria - +//----------------------------------------------------------------------------- +void CRR_Response::Init( ResponseType_t type, const char *responseName, const ResponseParams& responseparams, const char *ruleName, const char *applyContext, int iContextFlags) +{ + m_Type = type; + Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) ); + // Copy underlying criteria + Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) ); + m_Params = responseparams; + SetContext( applyContext ); + m_iContextFlags = iContextFlags; +} + +//----------------------------------------------------------------------------- +// Purpose: Debug-print the response. You can optionally pass in the criteria +// used to come up with this response (usually present in the calling function) +// if you want to print that as well. DO NOT store the entire criteria set in +// CRR_Response just to make this debug print cleaner. +//----------------------------------------------------------------------------- +void CRR_Response::Describe( const CriteriaSet *pDebugCriteria ) +{ + if ( pDebugCriteria ) + { + DevMsg( "Search criteria:\n" ); + pDebugCriteria->Describe(); + } + + if ( m_szMatchingRule[ 0 ] ) + { + DevMsg( "Matched rule '%s', ", m_szMatchingRule ); + } + if ( m_szContext ) + { + DevMsg("Contexts to set '%s' on ", m_szContext); + if (m_iContextFlags & APPLYCONTEXT_WORLD) + DevMsg("world, "); + else if (m_iContextFlags & APPLYCONTEXT_SQUAD) + DevMsg("squad, "); + else if (m_iContextFlags & APPLYCONTEXT_ENEMY) + DevMsg("enemy, "); + else + DevMsg("speaker, "); + } + + DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CRR_Response::GetName( char *buf, size_t buflen ) const +{ + Q_strncpy( buf, m_szResponseName, buflen ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : char const +//----------------------------------------------------------------------------- +void CRR_Response::GetResponse( char *buf, size_t buflen ) const +{ + GetName( buf, buflen ); +} + +const char* ResponseRules::CRR_Response::GetNamePtr() const +{ + return m_szResponseName; +} +const char* ResponseRules::CRR_Response::GetResponsePtr() const +{ + return m_szResponseName; +} +//----------------------------------------------------------------------------- +// Purpose: +// Input : type - +// Output : char const +//----------------------------------------------------------------------------- +const char *CRR_Response::DescribeResponse( ResponseType_t type ) +{ + if ( (int)type < 0 || (int)type >= ResponseRules::NUM_RESPONSES ) + { + Assert( 0 ); + return "???CRR_Response bogus index"; + } + + switch( type ) + { + default: + { + Assert( 0 ); + } + // Fall through + case ResponseRules::RESPONSE_NONE: + return "RESPONSE_NONE"; + case ResponseRules::RESPONSE_SPEAK: + return "RESPONSE_SPEAK"; + case ResponseRules::RESPONSE_SENTENCE: + return "RESPONSE_SENTENCE"; + case ResponseRules::RESPONSE_SCENE: + return "RESPONSE_SCENE"; + case ResponseRules::RESPONSE_RESPONSE: + return "RESPONSE_RESPONSE"; + case ResponseRules::RESPONSE_PRINT: + return "RESPONSE_PRINT"; + case ResponseRules::RESPONSE_ENTITYIO: + return "RESPONSE_ENTITYIO"; + } + + return "RESPONSE_NONE"; +} + +/* +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRR_Response::Release() +{ + delete this; +} +*/ + +//----------------------------------------------------------------------------- +// Purpose: +// Output : soundlevel_t +//----------------------------------------------------------------------------- +soundlevel_t CRR_Response::GetSoundLevel() const +{ + if ( m_Params.flags & ResponseParams::RG_SOUNDLEVEL ) + { + return (soundlevel_t)m_Params.soundlevel; + } + + return SNDLVL_TALKING; +} + +float CRR_Response::GetRespeakDelay( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_RESPEAKDELAY ) + { + interval_t temp; + m_Params.respeakdelay.ToInterval( temp ); + return RandomInterval( temp ); + } + + return 0.0f; +} + +float CRR_Response::GetWeaponDelay( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_WEAPONDELAY ) + { + interval_t temp; + m_Params.weapondelay.ToInterval( temp ); + return RandomInterval( temp ); + } + + return 0.0f; +} + +bool CRR_Response::GetSpeakOnce( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_SPEAKONCE ) + { + return true; + } + + return false; +} + +bool CRR_Response::ShouldntUseScene( void ) const +{ + return ( m_Params.flags & ResponseParams::RG_DONT_USE_SCENE ) != 0; +} + +bool CRR_Response::ShouldBreakOnNonIdle( void ) const +{ + return ( m_Params.flags & ResponseParams::RG_STOP_ON_NONIDLE ) != 0; +} + +int CRR_Response::GetOdds( void ) const +{ + if ( m_Params.flags & ResponseParams::RG_ODDS ) + { + return m_Params.odds; + } + return 100; +} + +float CRR_Response::GetDelay() const +{ + if ( m_Params.flags & ResponseParams::RG_DELAYAFTERSPEAK ) + { + interval_t temp; + m_Params.delay.ToInterval( temp ); + return RandomInterval( temp ); + } + return 0.0f; +} + +float CRR_Response::GetPreDelay() const +{ + if ( m_Params.flags & ResponseParams::RG_DELAYBEFORESPEAK ) + { + interval_t temp; + m_Params.predelay.ToInterval( temp ); + return RandomInterval( temp ); + } + return 0.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: Sets context string +// Output : void +//----------------------------------------------------------------------------- +void CRR_Response::SetContext( const char *context ) +{ + if (m_szContext) + { + delete[] m_szContext; + m_szContext = NULL; + } + + if ( context ) + { + int len = Q_strlen( context ); + m_szContext = new char[ len + 1 ]; + Q_memcpy( m_szContext, context, len ); + m_szContext[ len ] = 0; + } +} diff --git a/src/responserules/runtime/rr_speechconcept.cpp b/src/responserules/runtime/rr_speechconcept.cpp new file mode 100644 index 000000000..7e1e04abf --- /dev/null +++ b/src/responserules/runtime/rr_speechconcept.cpp @@ -0,0 +1,73 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "rrbase.h" + + +// memdbgon must be the last include file in a .cpp file!!! +#include + +#if RR_CONCEPTS_ARE_STRINGS +#pragma error("RR_CONCEPTS_ARE_STRINGS no longer supported") +#else + +using namespace ResponseRules; + +// Used to turn ad-hoc concept from strings into numbers. +CRR_ConceptSymbolTable *g_pRRConceptTable = NULL; + +// Q&D hack to defer initialization of concept table until I can figure out where it +// really needs to come from. +static void InitializeRRConceptTable() +{ + if (g_pRRConceptTable == NULL) + { + g_pRRConceptTable = new CRR_ConceptSymbolTable( 64, 64, true ); + } +} + +// construct from string +CRR_Concept::CRR_Concept(const char *fromString) +{ + InitializeRRConceptTable(); + m_iConcept = g_pRRConceptTable->AddString(fromString); +} + +CRR_Concept &CRR_Concept::operator=(const char *fromString) +{ + InitializeRRConceptTable(); + m_iConcept = g_pRRConceptTable->AddString(fromString); + return *this; +} + +bool CRR_Concept::operator==(const char *pszConcept) +{ + int otherConcept = g_pRRConceptTable->Find(pszConcept); + return ( otherConcept != UTL_INVAL_SYMBOL && otherConcept == m_iConcept ); +} + +const char *CRR_Concept::GetStringConcept() const +{ + InitializeRRConceptTable(); + AssertMsg( m_iConcept.IsValid(), "AI Concept has invalid string symbol.\n" ); + const char * retval = g_pRRConceptTable->String(m_iConcept); + AssertMsg( retval, "An RR_Concept couldn't find its string in the symbol table!\n" ); + if (retval == NULL) + { + Warning( "An RR_Concept couldn't find its string in the symbol table!\n" ); + retval = ""; + } + return retval; +} + +const char *CRR_Concept::GetStringForGenericId(tGenericId genericId) +{ + InitializeRRConceptTable(); + return g_pRRConceptTable->String(genericId); +} + +#endif diff --git a/src/responserules/runtime/rrbase.h b/src/responserules/runtime/rrbase.h new file mode 100644 index 000000000..e7af74dee --- /dev/null +++ b/src/responserules/runtime/rrbase.h @@ -0,0 +1,59 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef RRBASE_H +#define RRBASE_H +#ifdef _WIN32 +#pragma once +#endif + +#ifdef _WIN32 +// Silence certain warnings +// #pragma warning(disable : 4244) // int or float down-conversion +// #pragma warning(disable : 4305) // int or float data truncation +// #pragma warning(disable : 4201) // nameless struct/union +// #pragma warning(disable : 4511) // copy constructor could not be generated +// #pragma warning(disable : 4675) // resolved overload was found by argument dependent lookup +#endif + +#ifdef _DEBUG +#define DEBUG 1 +#endif + +// Misc C-runtime library headers +#include +#include +#include + +// tier 0 +#include "tier0/dbg.h" +#include "tier0/platform.h" +#include "basetypes.h" + +// tier 1 +#include "tier1/strtools.h" +#include "utlvector.h" +#include "utlsymbol.h" + +// tier 2 +#include "string_t.h" + +// Shared engine/DLL constants +#include "const.h" +#include "edict.h" + +// app +#if defined(_X360) +#define DISABLE_DEBUG_HISTORY 1 +#endif + +#include "responserules/response_types.h" +#include "response_types_internal.h" +#include "responserules/response_host_interface.h" + + +#endif // CBASE_H diff --git a/src/responserules/runtime/rrrlib.cpp b/src/responserules/runtime/rrrlib.cpp new file mode 100644 index 000000000..0d2c49fd7 --- /dev/null +++ b/src/responserules/runtime/rrrlib.cpp @@ -0,0 +1,13 @@ +/// PLACEHOLDER FILE FOR RESPONSE RULES RUNTIME LIBRARY + +#include "rrbase.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +namespace ResponseRules +{ + /// Custom symbol table for the response rules. + CUtlSymbolTable g_RS; +}; \ No newline at end of file diff --git a/src/responserules/runtime/stdafx.cpp b/src/responserules/runtime/stdafx.cpp new file mode 100644 index 000000000..4199359f2 --- /dev/null +++ b/src/responserules/runtime/stdafx.cpp @@ -0,0 +1,11 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: Builds the precompiled header for the game DLL +// +// $NoKeywords: $ +//=============================================================================// + + +#include "rrbase.h" + +// NOTE: DO NOT ADD ANY CODE OR HEADERS TO THIS FILE!!! diff --git a/src/game/shared/interval.cpp b/src/tier1/interval.cpp similarity index 100% rename from src/game/shared/interval.cpp rename to src/tier1/interval.cpp diff --git a/src/tier1/tier1.vpc b/src/tier1/tier1.vpc index 6f163a8be..bb11105f4 100644 --- a/src/tier1/tier1.vpc +++ b/src/tier1/tier1.vpc @@ -39,6 +39,7 @@ $Project "tier1" $File "generichash.cpp" $File "ilocalize.cpp" $File "interface.cpp" + $File "interval.cpp" $File "KeyValues.cpp" $File "kvpacker.cpp" $File "lzmaDecoder.cpp" diff --git a/src/vpc_scripts/groups.vgc b/src/vpc_scripts/groups.vgc index 07be80d15..64b16a15f 100644 --- a/src/vpc_scripts/groups.vgc +++ b/src/vpc_scripts/groups.vgc @@ -23,6 +23,7 @@ $Group "game" "tier1" "vgui_controls" "fgdlib" + "responserules" } $Group "shaders" @@ -42,6 +43,7 @@ $Group "everything" "motionmapper" "phonemeextractor" "raytrace" + "responserules" "qc_eyes" "server" "serverplugin_empty" @@ -65,5 +67,7 @@ $Group "dedicated" "mathlib" "server" "tier1" + "fgdlib" + "responserules" } diff --git a/src/vpc_scripts/projects.vgc b/src/vpc_scripts/projects.vgc index 0d4da2ee5..d2b92d283 100644 --- a/src/vpc_scripts/projects.vgc +++ b/src/vpc_scripts/projects.vgc @@ -80,6 +80,11 @@ $Project "server" "game\server\server_lazuul.vpc" [($WIN32||$POSIX) && $LAZUUL] } +$Project "responserules" +{ + "responserules\runtime\response_rules.vpc" [$WINDOWS||$X360||$POSIX] +} + $Project "mathlib" { "mathlib\mathlib.vpc" [$WINDOWS||$X360||$POSIX]